Exemple #1
0
        private void HandleErrorHttpRespone(PeerBase peer, byte operationCode, HttpRequestQueueResultCode result, AsyncHttpRequest request, string requestUri)
        {
            string msg;

            if (request != null)
            {
                msg = string.Format(
                    "webRpc request to address '{0}' failed. HttpQueueResult:{3}, WebStatus:{1}, Exception :{2}",
                    requestUri,
                    request.WebStatus,
                    request.Exception == null ? "(null)" : request.Exception.ToString(), result);
            }
            else
            {
                msg = string.Format("webRpc request to address '{0}' failed. HttpQueueResult:{1}", requestUri, result);
            }

            this.SendErrorResponse(peer, operationCode, new SendParameters(), msg: msg);

            if (result == HttpRequestQueueResultCode.QueueFull)
            {
                Log.Debug(msg);
            }
            else
            {
                Log.Error(msg);
            }
        }
Exemple #2
0
        public bool HandleCall(PeerBase peer, string userId, OperationRequest request, object authResultsSecure, SendParameters sp)
        {
            var rpcRequest = new WebRpcRequest(peer.Protocol, request);

            if (!rpcRequest.IsValid)
            {
                var msg = string.Format("Invalid RPC request format: {0}", rpcRequest.GetErrorMessage());
                Log.Error(msg);
                this.SendErrorResponse(peer, request.OperationCode, sp, (short)ErrorCode.OperationInvalid, msg);
                return(false);
            }

            try
            {
                var data = this.SerializeRequest(rpcRequest, userId, authResultsSecure);

                var uri = this.MakeRequestUri(rpcRequest);

                return(this.SendHttpRequest(peer, uri, data, rpcRequest));
            }
            catch (Exception e)
            {
                var msg = string.Format("Exception during RPC request handling {0}", e);
                Log.Error(msg);
                this.SendErrorResponse(peer, request.OperationCode, sp, msg: msg);
            }

            return(true);
        }
Exemple #3
0
        private bool SendHttpRequest(PeerBase peer, string uri, string data, WebRpcRequest rpcRequest)
        {
            var binData = Encoding.UTF8.GetBytes(data);

            HttpRequestQueueCallback callback =
                (result, request, state) => this.HandleHttpResponse(peer, rpcRequest.OperationRequest.OperationCode, result, rpcRequest, request, uri);


            var webRequest = (HttpWebRequest)WebRequest.Create(uri);

            webRequest.Proxy       = null;
            webRequest.Method      = "POST";
            webRequest.ContentType = "application/json";
            webRequest.Accept      = "application/json";
            webRequest.Timeout     = this.httpRequestTimeout;

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("WebRpc request {0}:{1}", uri, data);
            }

            this.httpRequestQueue.Enqueue(webRequest, binData, callback, null);

            return(true);
        }
Exemple #4
0
        public void OnDisconnectByOtherPeer(PeerBase peer)
        {
            this.ExitWorld();

            peer.RequestFiber.Enqueue(() => peer.RequestFiber.Enqueue(peer.Disconnect));
            CL.Out(LogFilter.PLAYER, "Player {0} disconnected by other peer".f(name));
        }
 /// <summary>
 ///   Initializes a new instance of the <see cref = "ClientInterestArea" /> class.
 /// </summary>
 /// <param name = "peer">
 ///   The peer.
 /// </param>
 /// <param name = "id">
 ///   The id for this interest area.
 ///   Unique per <see cref = "Actor" />.
 /// </param>
 /// <param name = "world">
 ///   The <see cref = "IWorld" /> this interest area is watching.
 /// </param>
 /// <param name = "fiber">
 ///   The fiber this intereast receives events on.
 /// </param>
 public ClientInterestArea(PeerBase peer, byte id, IWorld world, IFiber fiber)
     : base(id, world)
 {
     this.peer = peer;
     this.eventChannelSubscriptions = new Dictionary <Item, IDisposable>();
     this.fiber = fiber;
 }
Exemple #6
0
 protected MmoActor(PeerBase peer, World world)
 {
     this.peer          = peer;
     this.world         = world;
     this.interestAreas = new Dictionary <byte, InterestArea>();
     this.interestItems = new InterestItems(peer);
 }
 /// <summary>
 ///   Initializes a new instance of the <see cref = "ClientInterestArea" /> class.
 /// </summary>
 /// <param name = "peer">
 ///   The peer.
 /// </param>
 /// <param name = "id">
 ///   The id for this interest area. 
 ///   Unique per <see cref = "Actor" />.
 /// </param>
 /// <param name = "world">
 ///   The <see cref = "IWorld" /> this interest area is watching.
 /// </param>
 /// <param name = "fiber">
 ///   The fiber this intereast receives events on.
 /// </param>
 public ClientInterestArea(PeerBase peer, byte id, IWorld world, IFiber fiber)
     : base(id, world)
 {
     this.peer = peer;
     this.eventChannelSubscriptions = new Dictionary<Item, IDisposable>();
     this.fiber = fiber;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="RoomReference"/> class.
 /// </summary>
 /// <param name="roomCache">
 /// The room cache.
 /// </param>
 /// <param name="room">
 /// The room.
 /// </param>
 public RoomReference(RoomCacheBase roomCache, Room room, PeerBase ownerPeer)
 {
     this.roomCache = roomCache;
     this.id = Guid.NewGuid();
     this.Room = room;
     this.ownerPeer = ownerPeer;
 }
Exemple #9
0
 /// <summary>
 ///   Initializes a new instance of the <see cref = "Actor" /> class.
 /// </summary>
 /// <param name = "peer">
 ///   The owner peer.
 /// </param>
 /// <param name = "world">
 ///   The world.
 /// </param>
 protected Actor(PeerBase peer, IWorld world)
 {
     this.peer = peer;
     this.world = world;
     this.ownedItems = new Dictionary<byte, Dictionary<string, Item>>();
     this.interestAreas = new Dictionary<byte, InterestArea>();
 }
        /// <summary>
        /// Handles operation SetViewDistance: Changes the subscribe and unsubscribe radius for an InterestArea.
        /// </summary>
        public OperationResponse OperationSetViewDistance(PeerBase peer, OperationRequest request)
        {
            var operation = new SetViewDistance(peer.Protocol, request);

            if (!operation.IsValid)
            {
                return(new OperationResponse(request.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                });
            }

            operation.OnStart();
            InterestArea interestArea;

            if (this.TryGetInterestArea(operation.InterestAreaId, out interestArea) == false)
            {
                return(operation.GetOperationResponse((int)ReturnCode.InterestAreaNotFound, "InterestAreaNotFound"));
            }

            lock (interestArea.SyncRoot)
            {
                interestArea.ViewDistanceEnter = operation.ViewDistanceEnter;
                interestArea.ViewDistanceExit  = operation.ViewDistanceExit;
                interestArea.UpdateInterestManagement();
            }

            // don't send response
            return(null);
        }
        /// <summary>
        /// Handles operation SetProperties: Sets the Item.Properties of an Item and ultimately sends event ItemPropertiesSet to other clients.
        /// </summary>
        public OperationResponse OperationSetProperties(PeerBase peer, OperationRequest request, SendParameters sendParameters)
        {
            var operation = new SetProperties(peer.Protocol, request);

            if (!operation.IsValid)
            {
                return(new OperationResponse(request.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                });
            }

            operation.OnStart();
            Item item;

            if (string.IsNullOrEmpty(operation.ItemId))
            {
                item = this.Avatar;

                // set return values
                operation.ItemId = item.Id;
            }
            else if (this.TryGetItem(operation.ItemId, out item) == false)
            {
                return(operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound"));
            }

            return(this.ItemOperationSetProperties(item, operation, sendParameters));
        }
        protected override OperationResponse OnOperationRequest(PeerBase peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            Dictionary <byte, object> dict = operationRequest.Parameters;

            foreach (object value in dict.Values)
            {
                MasterApplication.log.Info("============OperationHandlerInitial==========:" + value.ToString());
            }

            switch (operationRequest.OperationCode)
            {
            default:
                return(HandleUnknownOperationCode(operationRequest, log));

            case (byte)OperationCode.Authenticate:
                return(((MasterClientPeer)peer).HandleAuthenticate(operationRequest, sendParameters));

            case (byte)OperationCode.CreateGame:
            case (byte)OperationCode.JoinGame:
            case (byte)OperationCode.JoinLobby:
            case (byte)OperationCode.JoinRandomGame:
            case (byte)OperationCode.FindFriends:
            case (byte)OperationCode.LobbyStats:
            case (byte)OperationCode.LeaveLobby:
            case (byte)OperationCode.DebugGame:
            case (byte)OperationCode.Rpc:
            case (byte)OperationCode.Settings:
            case (byte)OperationCode.GetGameList:
                return(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (int)Photon.Common.ErrorCode.OperationDenied,
                    DebugMessage = LBErrorMessages.NotAuthorized
                });
            }
        }
 public void Dispose()
 {
     CloseConnection();
     Peer            = null;
     ServerTransport = null;
     ConnectionId    = "";
 }
        public Subscription AddSubscription(PeerBase peer, int gameCount)
        {
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("New Subscription: pid={0}, gc={1}, props={2}", peer.ConnectionId, gameCount, this.propertyString);
            }

            if (gameCount < 0)
            {
                gameCount = 0;
            }

            var subscription = new Subscription(this, peer, gameCount);
            HashSet<PeerBase> hashSet;
            if (this.subscriptions.TryGetValue(gameCount, out hashSet) == false)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Creating new hashset for game count = {0}", gameCount);
                }

                hashSet = new HashSet<PeerBase>();
                this.subscriptions.Add(gameCount, hashSet);
            }

            hashSet.Add(peer);
            return subscription;
        }
Exemple #15
0
 protected MmoActor(PeerBase peer, World world)
 {
     this.peer = peer;
     this.world = world;
     this.interestAreas = new Dictionary<byte, InterestArea>();
     this.interestItems = new InterestItems(peer);
 }
 public void PeerDisconnected(PeerBase peer)
 {
     lock (Connections)
     {
         Connections.Remove(peer);
     }
 }
 public void PeerConnected(PeerBase peer)
 {
     lock(Connections)
     {
         Connections.Add(peer);
     }
 }
        /// <summary>
        /// Handles operation SpawnItem: Creates a new Item and optionally subscribes an InterestArea to it.
        /// </summary>
        public OperationResponse OperationSpawnItem(PeerBase peer, OperationRequest request)
        {
            log.InfoFormat("Spawn item operation started for peer: {0}", this.Peer.ToString());
            var operation = new SpawnItem(peer.Protocol, request);

            if (!operation.IsValid)
            {
                log.InfoFormat("Spawn item operation invalid");
                return(new OperationResponse(request.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                });
            }

            operation.OnStart();
            var item = new Item(operation.Position, operation.Rotation, operation.Properties, this, operation.ItemId, operation.ItemType, this.World);

            if (this.World.ItemCache.AddItem(item))
            {
                log.InfoFormat("adding item");
                this.AddItem(item);
                return(this.ItemOperationSpawn(item, operation));
            }
            log.InfoFormat("Spawn item operation for peer: {0}", this.Peer.ToString());
            item.Dispose();
            return(operation.GetOperationResponse((int)ReturnCode.ItemAlreadyExists, "ItemAlreadyExists"));
        }
Exemple #19
0
        public void removeClientPeer(PeerBase peer)
        {
            aclient_peer.Remove(peer);

            // remove from game's player list?
            agame_scene[cur_game].removeClient((STServerPeer)peer);
        }
Exemple #20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RoomReference"/> class.
 /// </summary>
 /// <param name="roomCache">
 /// The room cache.
 /// </param>
 /// <param name="room">
 /// The room.
 /// </param>
 /// <param name="ownerPeer">
 /// An <see cref="PeerBase"/> instance which obtained the room reference.
 /// </param>
 public RoomReference(RoomCacheBase roomCache, Room room, PeerBase ownerPeer)
 {
     this.roomCache = roomCache;
     this.id        = Guid.NewGuid();
     this.Room      = room;
     this.ownerPeer = ownerPeer;
 }
Exemple #21
0
 public RoomReference(RoomCacheBase roomCache, Room room, PeerBase ownerPeer)
 {
     _roomCache = roomCache;
     Id         = Guid.NewGuid();
     Room       = room;
     OwnerPeer  = ownerPeer;
 }
Exemple #22
0
 public void PeerConnected(PeerBase peer)
 {
     lock ( Connections )
     {
         Connections.Add(peer);
     }
 }
Exemple #23
0
 /// <summary>
 ///   Initializes a new instance of the <see cref = "Actor" /> class.
 /// </summary>
 /// <param name = "peer">
 ///   The owner peer.
 /// </param>
 /// <param name = "world">
 ///   The world.
 /// </param>
 protected Actor(PeerBase peer, IWorld world)
 {
     this.peer          = peer;
     this.world         = world;
     this.ownedItems    = new Dictionary <byte, Dictionary <string, Item> >();
     this.interestAreas = new Dictionary <byte, InterestArea>();
 }
Exemple #24
0
        public OperationResponse OnOperationRequest(PeerBase peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch ((OperationCode)operationRequest.OperationCode)
            {
            case OperationCode.EnterWorld:
                return(DefaultResponses.CreateNegativeResponse(operationRequest, ReturnCode.OperationNotAllowed));

            case OperationCode.Move:
                return(OperationMove(peer, operationRequest));

            case OperationCode.CharacterAction:
                return(OperationCharacterAction(peer, operationRequest));

            case OperationCode.StartAiLoop:
                AILooper.Instance.Start();
                return(null);

            case OperationCode.ToggleAiLoop:
                AILooper.Instance.ToggleLoop();
                return(null);

            default:
                return(DefaultResponses.CreateNegativeResponse(operationRequest, ReturnCode.OperationNotSupported));
            }
        }
Exemple #25
0
 public void RemoveSubscriber(PeerBase subscriber)
 {
     using (Lock.TryEnter(this.Subscribers, 10000))
     {
         this.Subscribers.Remove(subscriber);
     }
 }
        public override OperationResponse OnOperationRequest(PeerBase peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch (operationRequest.OperationCode)
            {
            default:
                return(HandleUnknownOperationCode(operationRequest, log));

            case (byte)OperationCode.Authenticate:
                return(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (short)ErrorCode.OperationDenied,
                    DebugMessage = LBErrorMessages.Authenticating
                });

            case (byte)OperationCode.CreateGame:
            case (byte)OperationCode.JoinGame:
            case (byte)OperationCode.JoinLobby:
            case (byte)OperationCode.JoinRandomGame:
            case (byte)OperationCode.LeaveLobby:
            case (byte)OperationCode.DebugGame:
            case (byte)OperationCode.FindFriends:
            case (byte)OperationCode.LobbyStats:
                return(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (short)ErrorCode.OperationDenied,
                    DebugMessage = LBErrorMessages.NotAuthorized,
                });
            }
        }
Exemple #27
0
 public void AddSubscriber(PeerBase subscriber)
 {
     using (Lock.TryEnter(this.Subscribers, 10000))
     {
         this.Subscribers.Add(subscriber);
     }
 }
Exemple #28
0
        public virtual IGameListSubscription AddSubscription(PeerBase peer, Hashtable gamePropertyFilter, int maxGameCount)
        {
            var subscribtion = new Subscribtion(this, maxGameCount);

            this.peers.Add(peer);
            return(subscribtion);
        }
Exemple #29
0
 public void PeerDisconnected(PeerBase peer)
 {
     lock ( Connections )
     {
         Connections.Remove(peer);
     }
 }
Exemple #30
0
            /// <summary>
            /// Adds a reference to the room instance.
            /// </summary>
            /// <param name="ownerPeer">
            /// The peer that holds this reference.
            /// </param>
            /// <returns>
            /// a new <see cref="RoomReference"/>
            /// </returns>
            public RoomReference AddReference(PeerBase ownerPeer)
            {
                var reference = new RoomReference(this.roomFactory, this.Room, ownerPeer);

                this.references.Add(reference.Id, reference);

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "Created room instance reference: roomName={0}, referenceCount={1}",
                        this.Room.Name,
                        this.ReferenceCount);
                }

                if (this.logQueue.Log.IsDebugEnabled)
                {
                    this.logQueue.Add(
                        new LogEntry(
                            "AddReference",
                            string.Format(
                                "RoomName={0}, ReferenceCount={1}, OwnerPeer={2}",
                                this.Room.Name,
                                this.ReferenceCount,
                                ownerPeer)));
                }

                return(reference);
            }
        /// <summary>
        /// Handles operation RemoveInterestArea: Removes one of the actor's InterestAreas.
        /// </summary>
        public OperationResponse OperationRemoveInterestArea(PeerBase peer, OperationRequest request)
        {
            var operation = new RemoveInterestArea(peer.Protocol, request);

            if (!operation.IsValid)
            {
                return(new OperationResponse(request.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                });
            }

            operation.OnStart();
            InterestArea interestArea;

            if (this.TryGetInterestArea(operation.InterestAreaId, out interestArea))
            {
                lock (interestArea.SyncRoot)
                {
                    interestArea.Detach();
                    interestArea.Dispose();
                }

                this.RemoveInterestArea(operation.InterestAreaId);
                return(operation.GetOperationResponse(MethodReturnValue.Ok));
            }

            return(operation.GetOperationResponse((int)ReturnCode.InterestAreaNotFound, "InterestAreaNotFound"));
        }
Exemple #32
0
        public Subscription AddSubscription(PeerBase peer, int gameCount)
        {
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("New Subscription: pid={0}, gc={1}, props={2}", peer.ConnectionId, gameCount, this.propertyString);
            }

            if (gameCount < 0)
            {
                gameCount = 0;
            }

            var subscription = new Subscription(this, peer, gameCount);
            HashSet <PeerBase> hashSet;

            if (this.subscriptions.TryGetValue(gameCount, out hashSet) == false)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Creating new hashset for game count = {0}", gameCount);
                }

                hashSet = new HashSet <PeerBase>();
                this.subscriptions.Add(gameCount, hashSet);
            }

            hashSet.Add(peer);
            return(subscription);
        }
Exemple #33
0
        public OperationResponse OnOperationRequest(PeerBase peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch ((OperationCode)operationRequest.OperationCode)
            {
            case OperationCode.CreateWorld:
            {
                return(this.OperationCreateWorld(peer, operationRequest));
            }

            case OperationCode.EnterWorld:
            {
                return(this.OperationEnterWorld(peer, operationRequest, sendParameters));
            }

            case OperationCode.SubscribeCounter:
            {
                return(CounterOperations.SubscribeCounter(peer, operationRequest));
            }

            case OperationCode.UnsubscribeCounter:
            {
                return(CounterOperations.UnsubscribeCounter(peer, operationRequest));
            }

            case OperationCode.ExecAction:
            {
                return(this.ExecAction(peer, operationRequest, sendParameters));
            }

            default:
            {
                return(InvalidOperation(operationRequest));
            }
            }
        }
 public void OnDisconnect(PeerBase peer)
 {
     if (m_Peer.Name != null)
     {
         World.Instance.RemoveEntity(m_Peer.Name);
     }
     peer.Dispose();
 }
Exemple #35
0
        private void PublishStatisticEvent(PeerBase peer)
        {
            var lobbyList  = this.lobbyFactory.GetLobbies(this.maxLobbyStatsCount);
            var lobbyStats = LobbyListToLobbyStatsData(lobbyList);
            var eventData  = new EventData((byte)EventCode.LobbyStats, lobbyStats);

            peer.SendEvent(eventData, new SendParameters());
        }
Exemple #36
0
 public bool TransitDisposeConnected(PeerBase peer)
 {
     if (peer.TransitConnectionState(DisposeDisconnecting.Instance, this))
     {
         return(false);
     }
     return(peer.ConnectionStateImpl.TransitDisposeConnected(peer));
 }
        /// <summary>
        /// Handles operation AttachInterestArea: Attaches an existing InterestArea to an existing Item.
        /// </summary>
        public OperationResponse OperationAttachInterestArea(PeerBase peer, OperationRequest request, SendParameters sendParameters)
        {
            var operation = new AttachInterestArea(peer.Protocol, request);

            if (!operation.IsValid)
            {
                return(new OperationResponse(request.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage()
                });
            }

            operation.OnStart();
            InterestArea interestArea;

            if (this.TryGetInterestArea(operation.InterestAreaId, out interestArea) == false)
            {
                return(operation.GetOperationResponse((int)ReturnCode.InterestAreaNotFound, "InterestAreaNotFound"));
            }

            Item item;
            bool actorItem;

            if (string.IsNullOrEmpty(operation.ItemId))
            {
                item      = this.Avatar;
                actorItem = true;

                // set return vaues
                operation.ItemId = item.Id;
            }
            else
            {
                actorItem = this.TryGetItem(operation.ItemId, out item);
            }

            if (actorItem)
            {
                // we are already in the item thread, invoke directly
                return(this.ItemOperationAttachInterestArea(item, operation, interestArea, sendParameters));
            }
            else
            {
                // search world cache just to see if item exists at all
                if (this.World.ItemCache.TryGetItem(operation.ItemId, out item) == false)
                {
                    return(operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound"));
                }
                else
                {
                    // second parameter (peer) allows us to send an error event to the client (in case of an error)
                    item.Fiber.Enqueue(() => this.ExecItemOperation(() => this.ItemOperationAttachInterestArea(item, operation, interestArea, sendParameters), sendParameters));

                    // response is sent later
                    return(null);
                }
            }
        }
        /// <summary>
        /// Kicks the actor from the world (event WorldExited is sent to the client) and then disconnects the client.
        /// </summary>
        /// <remarks>
        /// Called by DisconnectByOtherPeer after being enqueued to the PeerBase.RequestFiber.
        /// It kicks the actor from the world (event WorldExited) and then continues the original request by calling the original peer's OnOperationRequest method.        
        /// </remarks>
        public void OnDisconnectByOtherPeer(PeerBase otherPeer, OperationRequest otherRequest, SendParameters sendParameters)
        {
            this.ExitWorld();

            // disconnect peer after the exit world event is sent
            this.Peer.RequestFiber.Enqueue(() => this.Peer.RequestFiber.Enqueue(this.Peer.Disconnect));

            // continue execution of other request
            PeerHelper.InvokeOnOperationRequest(otherPeer, otherRequest, sendParameters);
        }
        public SocketUdpNativeDllImport(PeerBase npeer) : base(npeer)
        {
            if (this.ReportDebugOfLevel(DebugLevel.ALL))
            {
                this.Listener.DebugReturn(DebugLevel.ALL, "SocketWrapper: UDP, Unity Android Native.");
            }

            this.Protocol = ConnectionProtocol.Udp;
            this.PollReceive = false;
        }
        public SocketUdp(PeerBase npeer) : base(npeer)
        {
            if (this.ReportDebugOfLevel(DebugLevel.ALL))
            {
                this.Listener.DebugReturn(DebugLevel.ALL, "CSharpSocket: UDP, Unity3d.");
            }

            this.Protocol = ConnectionProtocol.Udp;
            this.PollReceive = false;
        }
        public SocketWebTcp(PeerBase npeer) : base(npeer)
        {
            ServerAddress = npeer.ServerAddress;
            if (this.ReportDebugOfLevel(DebugLevel.INFO))
            {
                Listener.DebugReturn(DebugLevel.INFO, "new SocketWebTcp() " + ServerAddress);
            }

            Protocol = ConnectionProtocol.Tcp;
            PollReceive = false;
        }
        /// <summary>
        /// The client stops receiving counter updates from the PhotonApplication.CounterPublisher.
        /// </summary>
        public static OperationResponse UnsubscribeCounter(PeerBase peer, OperationRequest request)
        {
            var mmoPeer = (MmoPeer)peer;
            if (mmoPeer.CounterSubscription == null)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperation, DebugMessage = "not subscribed" };
            }

            mmoPeer.CounterSubscription.Dispose();
            mmoPeer.CounterSubscription = null;
            return new OperationResponse(request.OperationCode);
        }
Exemple #43
0
        public OperationResponse OperationEnterWorld(PeerBase peer, OperationRequest request, SendParameters sendParameters)
        {
            var operation = new EnterWorld(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ErrorCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            MmoWorld world = MmoWorld.Instance;

            var actor = new MmoActor(peer, world, interestArea);
            var avatar = new MmoItem(world, operation.Position, operation.Rotation, operation.Properties, actor, operation.Username, (byte)ItemType.Avatar);

            while (world.ItemCache.AddItem(avatar) == false)
            {
                Item otherAvatarItem;
                if (world.ItemCache.TryGetItem(avatar.Type, avatar.Id, out otherAvatarItem))
                {
                    avatar.Dispose();
                    actor.Dispose();
                    interestArea.Dispose();

                    ((Peer)((MmoItem)otherAvatarItem).Owner.Peer).DisconnectByOtherPeer(this, request, sendParameters);

                    // request continued later, no response here
                    return null;
                }
            }

            // init avatar
            actor.AddItem(avatar);
            actor.Avatar = avatar;

            ((Peer)peer).SetCurrentOperationHandler(actor);

            // set return values
            var responseObject = new EnterWorldResponse
            {
            };

            // send response; use item channel to ensure that this event arrives before any move or subscribe events
            var response = new OperationResponse(request.OperationCode, responseObject);
            sendParameters.ChannelId = Settings.ItemEventChannel;
            peer.SendOperationResponse(response, sendParameters);

            avatar.Spawn(operation.Position);

            // response already sent
            return null;
        }
        public override IGameListSubscription AddSubscription(PeerBase peer, Hashtable gamePropertyFilter, int maxGameCount)
        {
            if (gamePropertyFilter == null)
            {
                gamePropertyFilter = new Hashtable(0);
            }

            GameChannel gameChannel;
            var key = new GameChannelKey(gamePropertyFilter);

            if (!this.GameChannels.TryGetValue(key, out gameChannel))
            {
                gameChannel = new GameChannel(this, key);
                this.GameChannels.Add(key, gameChannel);
            }

            return gameChannel.AddSubscription(peer, maxGameCount);
        }
Exemple #45
0
        public OperationResponse OnOperationRequest(PeerBase peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch ((OperationCode)operationRequest.OperationCode)
            {
                case OperationCode.EnterWorld:
                    return this.OperationEnterWorld(peer, operationRequest, sendParameters);

                case OperationCode.ExitWorld:
                case OperationCode.Move:
                    return InvalidOperation(operationRequest);
            }

            return new OperationResponse(operationRequest.OperationCode)
            {
                ReturnCode = (int)ErrorCode.OperationNotSupported,
                DebugMessage = "OperationNotSupported: " + operationRequest.OperationCode
            };
        }
        private static void PublishCounterData(PeerBase peer, ICollection<CounterSampleMessage> counterSamples)
        {
            IEnumerable<CounterAggregation> aggregations = CounterAggregation.Create(counterSamples);
            foreach (CounterAggregation aggregation in aggregations)
            {
                var @event = new CounterDataEvent
                    {
                        Name = aggregation.CounterName,
                        TimeStamps = aggregation.Timestamps.ToArray(),
                        Values = aggregation.Values.ToArray()
                    };

                var eventData = new EventData((byte)EventCode.CounterData, @event);

                // already in right fiber, we would use peer.SendEvent otherwise
                peer.SendEvent(eventData, new SendParameters { ChannelId = Settings.DiagnosticsEventChannel });
            }
        }
        // The client receives counter updates from the PhotonApplication.CounterPublisher.
        public static OperationResponse SubscribeCounter(PeerBase peer, OperationRequest request)
        {
            var operation = new SubscribeCounter(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            var mmoPeer = (MmoPeer)peer;
            if (mmoPeer.CounterSubscription == null)
            {
                mmoPeer.CounterSubscription = PhotonApplication.CounterPublisher.Channel.SubscribeToBatch(
                    peer.RequestFiber, m => PublishCounterData(peer, m), operation.ReceiveInterval);

                return operation.GetOperationResponse(MethodReturnValue.Ok);
            }

            return operation.GetOperationResponse((int)ReturnCode.InvalidOperation, "already subscribed");
        }
        /// <summary>
        /// Gets a room reference for a room with a specified id.
        /// If the room with the specified id does not exists, a new room will be created.
        /// </summary>
        /// <param name="roomName">
        /// The room id.
        /// </param>
        /// <param name="ownerPeer">
        /// The peer that holds this reference.
        /// </param>
        /// <param name="args">
        /// Optionally arguments used for room creation.
        /// </param>
        /// <returns>
        /// a <see cref="RoomReference"/>
        /// </returns>
        public RoomReference GetRoomReference(string roomName, PeerBase ownerPeer, params object[] args)
        {
            lock (this.SyncRoot)
            {
                RoomInstance roomInstance;
                if (!this.RoomInstances.TryGetValue(roomName, out roomInstance))
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Creating room instance: roomName={0}", roomName);
                    }

                    Room room = this.CreateRoom(roomName, args);
                    roomInstance = new RoomInstance(this, room);
                    this.RoomInstances.Add(roomName, roomInstance);
                }

                return roomInstance.AddReference(ownerPeer);
            }
        }
        /// <summary>
        /// Expects operation RadarSubscribe and subscribes the peer to the Radar.
        /// Publishes an OperationResponse with error code ReturnCode.Ok if successful.
        /// </summary>
        public static OperationResponse OperationRadarSubscribe(PeerBase peer, OperationRequest request, SendParameters sendParameters)
        {
            var mmoPeer = (MmoPeer)peer;
            var operation = new RadarSubscribe(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            if (mmoPeer.RadarSubscription != null)
            {
                mmoPeer.RadarSubscription.Dispose();
                mmoPeer.RadarSubscription = null;
            }

            World world;
            if (WorldCache.Instance.TryGet(operation.WorldName, out world) == false)
            {
                return operation.GetOperationResponse((int)ReturnCode.WorldNotFound, "WorldNotFound");
            }

            mmoPeer.RadarSubscription = world.Radar.Channel.Subscribe(mmoPeer.RequestFiber, m => RadarChannel_OnItemEventMessage(peer, m));

            // set return values
            var responseObject = new RadarSubscribeResponse
                {
                    BoundingBox = world.Area,
                    TileDimensions = world.TileDimensions,
                    WorldName = world.Name
                };

            // send response before sending radar content
            var response = new OperationResponse(request.OperationCode, responseObject);
            peer.SendOperationResponse(response, sendParameters);

            // send complete radar content to client
            world.Radar.SendContentToPeer(mmoPeer);

            // response already sent
            return null;
        }
Exemple #50
0
        private void HandleFiendFriends(PeerBase peer, FindFriendsRequest request, SendParameters sendParameters)
        {
            try
            {
                var onlineList = new bool[request.UserList.Length];
                var gameIds = new string[request.UserList.Length];

                for (int i = 0; i < request.UserList.Length; i++)
                {
                    PlayerState playerState;
                    if (this.playerDict.TryGetValue(request.UserList[i], out playerState))
                    {
                        onlineList[i] = true;
                        if (playerState.ActiveGame != null)
                        {
                            gameIds[i] = playerState.ActiveGame.Id;
                        }
                        else
                        {
                            gameIds[i] = string.Empty;
                        }
                    }
                    else
                    {
                        gameIds[i] = string.Empty;
                    }
                }

                var response = new FindFriendsResponse { IsOnline = onlineList, UserStates = gameIds };
                var opResponse = new OperationResponse((byte)OperationCode.FindFriends, response);
                peer.SendOperationResponse(opResponse, sendParameters);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MmoClientInterestArea"/> class. 
 /// </summary>
 /// <param name="peer">
 /// The peer state.
 /// </param>
 /// <param name="id">
 /// The interesta area id.
 /// </param>
 /// <param name="world">
 /// The world.
 /// </param>
 public MmoClientInterestArea(PeerBase peer, byte id, IWorld world)
     : base(peer, id, world, peer.RequestFiber)
 {
 }
        /// <summary>
        /// Expects operation EnterWorld and creates a new MmoActor with a new Item as avatar and a new MmoClientInterestArea. 
        /// </summary>
        /// <remarks>
        /// The MmoActor becomes the new Peer.CurrentOperationHandler.
        /// If another MmoActor with the same name exists he is disconnected.
        /// An OperationResponse with error code ReturnCode.Ok is published on success.
        /// </remarks>
        public OperationResponse OperationEnterWorld(PeerBase peer, OperationRequest request, SendParameters sendParameters)
        {
            var operation = new EnterWorld(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            World world;
            if (WorldCache.Instance.TryGet(operation.WorldName, out world) == false)
            {
                return operation.GetOperationResponse((int)ReturnCode.WorldNotFound, "WorldNotFound");
            }

            var interestArea = new ClientInterestArea(peer, operation.InterestAreaId, world)
                {
                    ViewDistanceEnter = operation.ViewDistanceEnter,
                    ViewDistanceExit = operation.ViewDistanceExit
                };

            var actor = new MmoActorOperationHandler(peer, world, interestArea);
            var avatar = new Item(operation.Position, operation.Rotation, operation.Properties, actor, operation.Username, (byte)ItemType.Avatar, world);

            while (world.ItemCache.AddItem(avatar) == false)
            {
                Item otherAvatarItem;
                if (world.ItemCache.TryGetItem(avatar.Id, out otherAvatarItem))
                {
                    avatar.Dispose();
                    actor.Dispose();
                    interestArea.Dispose();

                    (((Item)otherAvatarItem).Owner).DisconnectByOtherPeer(this.peer, request, sendParameters);

                    // request continued later, no response here
                    return null;
                }
            }

            // init avatar
            actor.AddItem(avatar);
            actor.Avatar = avatar;

            ((Peer)peer).SetCurrentOperationHandler(actor);

            // set return values
            var responseObject = new EnterWorldResponse
                {
                    BoundingBox = world.Area,
                    TileDimensions = world.TileDimensions,
                    WorldName = world.Name
                };

            // send response; use item channel to ensure that this event arrives before any move or subscribe events
            var response = new OperationResponse(request.OperationCode, responseObject);
            sendParameters.ChannelId = Settings.ItemEventChannel;
            peer.SendOperationResponse(response, sendParameters);

            lock (interestArea.SyncRoot)
            {
                interestArea.AttachToItem(avatar);
                interestArea.UpdateInterestManagement();
            }

            avatar.Spawn(operation.Position);
            world.Radar.AddItem(avatar, operation.Position);

            // response already sent
            return null;
        }
 private static void RadarChannel_OnItemEventMessage(PeerBase peer, ItemEventMessage message)
 {
     // already in right fiber, we would use peer.SendEvent otherwise
     peer.SendEvent(message.EventData, message.SendParameters);
 }
        /// <summary>
        /// IOperationHandler implementation.
        /// </summary>
        public OperationResponse OnOperationRequest(PeerBase peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch ((OperationCode)operationRequest.OperationCode)
            {
                case OperationCode.CreateWorld:
                    {
                        return this.OperationCreateWorld(peer, operationRequest);
                    }

                case OperationCode.EnterWorld:
                    {
                        return this.OperationEnterWorld(peer, operationRequest, sendParameters);
                    }

                case OperationCode.RadarSubscribe:
                    {
                        return OperationRadarSubscribe(peer, operationRequest, sendParameters);
                    }

                case OperationCode.SubscribeCounter:
                    {
                        return CounterOperations.SubscribeCounter(peer, operationRequest);
                    }

                case OperationCode.UnsubscribeCounter:
                    {
                        return CounterOperations.UnsubscribeCounter(peer, operationRequest);
                    }

                case OperationCode.AddInterestArea:
                case OperationCode.AttachInterestArea:
                case OperationCode.DestroyItem:
                case OperationCode.DetachInterestArea:
                case OperationCode.ExitWorld:
                case OperationCode.GetProperties:
                case OperationCode.Move:
                case OperationCode.MoveInterestArea:
                case OperationCode.RemoveInterestArea:
                case OperationCode.SetProperties:
                case OperationCode.SetViewDistance:
                case OperationCode.SpawnItem:
                case OperationCode.SubscribeItem:
                case OperationCode.UnsubscribeItem:
                    {
                        return InvalidOperation(operationRequest);
                    }
            }

            return new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.OperationNotSupported,
                    DebugMessage = "OperationNotSupported: " + operationRequest.OperationCode
                };
        }
        /// <summary>
        /// Expects operation CreateWorld and adds a new World to the WorldCache.
        /// </summary>
        public OperationResponse OperationCreateWorld(PeerBase peer, OperationRequest request)
        {
            var operation = new CreateWorld(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            World world;
            MethodReturnValue result = WorldCache.Instance.TryCreate(
                operation.WorldName, operation.BoundingBox, operation.TileDimensions, out world)
                                           ? MethodReturnValue.Ok
                                           : MethodReturnValue.New((int)ReturnCode.WorldAlreadyExists, "WorldAlreadyExists");

            return operation.GetOperationResponse(result);
        }
 /// <summary>
 /// IOperationHandler implementation.
 /// Disconnects the peer.
 /// </summary>
 public void OnDisconnectByOtherPeer(PeerBase peer)
 {
     // disconnect after any queued events are sent
     peer.RequestFiber.Enqueue(() => peer.RequestFiber.Enqueue(peer.Disconnect));
 }
 /// <summary>
 /// IOperationHandler implementation.
 /// Stops any further operation handling and disposes the peer's resources.
 /// </summary>
 public void OnDisconnect(PeerBase peer)
 {
     this.peer.SetCurrentOperationHandler(null);
     this.peer.Dispose();
 }
        /// <summary>
        /// Handles operation SpawnItem: Creates a new Item and optionally subscribes an InterestArea to it.
        /// </summary>
        public OperationResponse OperationSpawnItem(PeerBase peer, OperationRequest request)
        {
            var operation = new SpawnItem(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            operation.OnStart();
            var item = new Item(operation.Position, operation.Rotation, operation.Properties, this, operation.ItemId, operation.ItemType, this.World);
            if (this.World.ItemCache.AddItem(item))
            {
                this.AddItem(item);
                return this.ItemOperationSpawn(item, operation);
            }

            item.Dispose();
            return operation.GetOperationResponse((int)ReturnCode.ItemAlreadyExists, "ItemAlreadyExists");
        }
        /// <summary>
        /// Handles operation UnsubscribeItem: manually unsubscribes an existing InterestArea from an existing Item.
        /// The client receives event ItemUnsubscribed on success.
        /// </summary>
        public OperationResponse OperationUnsubscribeItem(PeerBase peer, OperationRequest request, SendParameters sendParameters)
        {
            var operation = new UnsubscribeItem(peer.Protocol, request);
            if (!operation.IsValid)
            {
                return new OperationResponse(request.OperationCode) { ReturnCode = (int)ReturnCode.InvalidOperationParameter, DebugMessage = operation.GetErrorMessage() };
            }

            operation.OnStart();

            Item item;
            bool actorItem = this.TryGetItem(operation.ItemId, out item);
            if (actorItem == false)
            {
                if (this.World.ItemCache.TryGetItem(operation.ItemId, out item) == false)
                {
                    return operation.GetOperationResponse((int)ReturnCode.ItemNotFound, "ItemNotFound");
                }
            }

            this.interestItems.UnsubscribeItem(item);

            if (actorItem)
            {
                // we are already in the item thread, invoke directly
                return this.ItemOperationUnsubscribeItem(item, operation);
            }
            else
            {
                // second parameter (peer) allows us to send an error event to the client (in case of an error)
                item.Fiber.Enqueue(() => this.ExecItemOperation(() => this.ItemOperationUnsubscribeItem(item, operation), sendParameters));

                // operation continues later
                return null;
            }
        }
        public OperationResponse OnOperationRequest(PeerBase peer, OperationRequest operationRequest, SendParameters sendParameters)
        {
            switch ((OperationCode)operationRequest.OperationCode)
            {
                case OperationCode.AddInterestArea:
                    return this.OperationAddInterestArea(peer, operationRequest, sendParameters);

                case OperationCode.AttachInterestArea:
                    return this.OperationAttachInterestArea(peer, operationRequest, sendParameters);

                case OperationCode.DestroyItem:
                    return this.OperationDestroyItem(peer, operationRequest, sendParameters);

                case OperationCode.DetachInterestArea:
                    return this.OperationDetachInterestArea(peer, operationRequest);

                case OperationCode.ExitWorld:
                    return this.OperationExitWorld(peer, operationRequest);

                case OperationCode.GetProperties:
                    return this.OperationGetProperties(peer, operationRequest, sendParameters);

                case OperationCode.Move:
                    return this.OperationMove(peer, operationRequest, sendParameters);

                case OperationCode.MoveInterestArea:
                    return this.OperationMoveInterestArea(peer, operationRequest);

                case OperationCode.RemoveInterestArea:
                    return this.OperationRemoveInterestArea(peer, operationRequest);

                case OperationCode.SetProperties:
                    return this.OperationSetProperties(peer, operationRequest, sendParameters);

                case OperationCode.SetViewDistance:
                    return this.OperationSetViewDistance(peer, operationRequest);

                case OperationCode.SpawnItem:
                    return this.OperationSpawnItem(peer, operationRequest);

                case OperationCode.SubscribeItem:
                    return this.OperationSubscribeItem(peer, operationRequest, sendParameters);

                case OperationCode.UnsubscribeItem:
                    return this.OperationUnsubscribeItem(peer, operationRequest, sendParameters);

                case OperationCode.RadarSubscribe:
                    return MmoInitialOperationHandler.OperationRadarSubscribe(peer, operationRequest, sendParameters);

                case OperationCode.SubscribeCounter:
                    return CounterOperations.SubscribeCounter(peer, operationRequest);

                case OperationCode.UnsubscribeCounter:
                    return CounterOperations.SubscribeCounter(peer, operationRequest);

                case OperationCode.RaiseGenericEvent:
                    return this.OperationRaiseGenericEvent(peer, operationRequest, sendParameters);

                case OperationCode.CreateWorld:
                case OperationCode.EnterWorld:
                    return InvalidOperation(operationRequest);
            }

            return new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (int)ReturnCode.OperationNotSupported,
                    DebugMessage = "OperationNotSupported: " + operationRequest.OperationCode
                };
        }