private Task onGetListGames(RequestContext<IScenePeerClient> ctx)
 {
     m_log.Debug("Lobby", "Client (id : " + ctx.RemotePeer.Id + ") with player name : \"" + m_players[ctx.RemotePeer].Name + "\" fetch games infos");
     try
     {
         ctx.SendValue(m_games);
     }
     catch (Exception)
     {
         ctx.SendValue(null);
     }
     return Task.FromResult(true);
 }
Example #2
0
        public async Task GetP2PData(RequestContext <IScenePeerClient> ctx)
        {
            var provider = ctx.ReadObject <string>();

            switch (provider)
            {
            case "userId":
            {
                var userId = ctx.ReadObject <string>();
                var peer   = await _userSessions.GetPeer(userId);

                if (peer == null)
                {
                    throw new ClientException($"The user '{userId}' is not connected.");
                }

                var r = await _natIndex.TryGet(peer.Id.ToString());

                if (!r.Success)
                {
                    throw new ClientException($"The user '{userId}' (peer : '{peer.Id}') is not available for p2p (no p2p data set).");
                }
                else
                {
                    ctx.SendValue(r.Value.P2PTransports);
                }
                break;
            }

            case "peerId":
            {
                var peerId = ctx.ReadObject <long>();
                var r      = await _natIndex.TryGet(peerId.ToString());

                if (!r.Success)
                {
                    ctx.SendValue(new Dictionary <string, string>());
                }
                else
                {
                    ctx.SendValue(r.Value.P2PTransports);
                }
                break;
            }

            default:
                throw new ClientException($"Unknown provider '{provider}'.");
            }
        }
Example #3
0
        public async Task Report(RequestContext <IScenePeerClient> ctx)
        {
            try
            {
                var user = await _userSessions.GetUser(ctx.RemotePeer);

                var reportDto = ctx.ReadObject <ReportDto>();
                var report    = new Report
                {
                    ReportUserId   = user.Id,
                    ReportedUserId = reportDto.ReportedUserId,
                    ReportDate     = DateTimeOffset.FromUnixTimeSeconds(reportDto.Timestamp).DateTime,
                    Message        = reportDto.Message,
                    Category       = reportDto.Category,
                    CustomData     = reportDto.CustomData,
                };
                await _reportPlayers.ReportPlayer(report);
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, _logCategory, "Server error, report doesn't save", ex.Message);
                throw new ClientException("Server error, report doesn't save");
            }

            ctx.SendValue <string>("Report saved");
        }
Example #4
0
        public async Task GetShard(RequestContext <IScenePeerClient> ctx)
        {
            var client = await _management.GetApplicationClient();

            // Get data send by client
            var mapId   = ctx.ReadObject <string>();
            var shardId = StringToHex(mapId);
            var shard   = await client.GetScene(shardId);

            if (shard == null)
            {
                var metadata = Newtonsoft.Json.Linq.JObject.FromObject(new { gameSession = new Server.Plugins.GameSession.GameSessionConfiguration {
                                                                                 Public = true, canRestart = true, UserData = mapId
                                                                             } });

                var template = global::Server.App.GAMESESSION_TEMPLATE;

                _logger.Log(LogLevel.Trace, "LocatorController", $"Creating scene {shardId} for map {mapId}", new { mapId, shardId });

                await client.CreateScene(
                    shardId,
                    template,
                    false,
                    metadata,
                    false);
            }
            var token = await client.CreateConnectionToken(shardId, "");

            ctx.SendValue(token);
        }
Example #5
0
        public async Task Message(RequestContext <IScenePeerClient> ctx)
        {
            try
            {
                await _chat.OnMessageReceived(ctx.RemotePeer, ctx.ReadObject <string>(), (messageDto, destination) =>
                {
                    if (messageDto == null)
                    {
                        throw new InvalidOperationException("Message recieved internal error");
                    }

                    if (destination.HasFlag(DestinationType.Others))
                    {
                        _scene.Broadcast("receivemessage", messageDto);
                    }

                    if (destination.HasFlag(DestinationType.Self))
                    {
                        ctx.SendValue(messageDto);
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, _logCategory, "Error occured when server received message", ex);
                throw new ClientException(ex.Message);
            }
        }
Example #6
0
        public async Task Cursor(RequestContext <IScenePeerClient> ctx)
        {
            var cursor = ctx.ReadObject <string>();
            var result = await _leaderboard.QueryCursor(cursor);

            ctx.SendValue(result);
        }
Example #7
0
 /// <summary>
 /// Sends an object as a response to a request.
 /// </summary>
 /// <typeparam name="TData">The type of object to send as a response.</typeparam>
 /// <param name="context">The request context to respond to.</param>
 /// <param name="data">The data to send as a response.</param>
 /// <param name="priority">The priority of the response.</param>
 public static void SendValue <TData>(this RequestContext <IScenePeerClient> context, TData data, PacketPriority priority = PacketPriority.MEDIUM_PRIORITY)
 {
     context.SendValue(s =>
     {
         context.RemotePeer.Serializer().Serialize(data, s);
     }, priority);
 }
Example #8
0
        public async Task GetPeer(RequestContext <IScenePeer> rq)
        {
            var userId = _serializer.Deserialize <string>(rq.InputStream);
            var result = await _sessions.GetPeer(userId);

            await rq.SendValue(s => _serializer.Serialize(result?.SessionId, s));
        }
Example #9
0
        public async Task GetSessionByPlatformId(RequestContext <IScenePeer> rq)
        {
            var platformId = _serializer.Deserialize <PlatformId>(rq.InputStream);
            var session    = await _sessions.GetSession(platformId);

            await rq.SendValue(s => _serializer.Serialize(session, s));
        }
Example #10
0
        public async Task GetSessionByUserId(RequestContext <IScenePeer> rq)
        {
            var userId  = _serializer.Deserialize <string>(rq.InputStream);
            var session = await _sessions.GetSessionByUserId(userId);

            await rq.SendValue(s => _serializer.Serialize(session, s));
        }
        public Task GetPlayerData(RequestContext <IScenePeerClient> ctx)
        {
            var playerId = ctx.ReadObject <string>();

            ctx.SendValue(_service.GetPlayerData(playerId));
            return(Task.CompletedTask);
        }
Example #12
0
        public async Task DecodeBearerToken(RequestContext <IScenePeer> rq)
        {
            var token = _serializer.Deserialize <string>(rq.InputStream);
            var app   = await _environment.GetApplicationInfos();

            var data = TokenGenerator.DecodeToken <BearerTokenData>(token, app.PrimaryKey);
            await rq.SendValue(s => _serializer.Serialize(data, s));
        }
Example #13
0
        public async Task IsAuthenticated(RequestContext <IScenePeer> rq)
        {
            var sessionId       = _serializer.Deserialize <string>(rq.InputStream);
            var peer            = _scene.RemotePeers.FirstOrDefault(p => p.SessionId == sessionId);
            var isAuthenticated = await _sessions.IsAuthenticated(peer);

            await rq.SendValue(s => _serializer.Serialize(isAuthenticated, s));
        }
Example #14
0
        public async Task GetBearerToken(RequestContext <IScenePeerClient> ctx)
        {
            var app = await _environment.GetApplicationInfos();

            var session = await _sessions.GetSession(ctx.RemotePeer);

            ctx.SendValue(TokenGenerator.CreateToken(new BearerTokenData {
                UserId = session.User.Id
            }, app.PrimaryKey));
        }
Example #15
0
        public async Task PostResults(RequestContext <IScenePeerClient> ctx)
        {
            var writer = await _service.PostResults(ctx.InputStream, ctx.RemotePeer);

            await ctx.SendValue(s =>
            {
                var oldPosition = s.Position;
                writer(s, ctx.RemotePeer.Serializer());
            });
        }
Example #16
0
        private Task OnGetShipKillCount(RequestContext<IScenePeerClient> request)
        {
            request.SendValue(s =>
            {
                s.Write(BitConverter.GetBytes(this._deathCount), 0, 8);
                s.Write(BitConverter.GetBytes(this._scene.GetComponent<IEnvironment>().Clock), 0, 8);
            });

            return Task.FromResult(true);
        }
Example #17
0
        public async Task PostResults(RequestContext <IScenePeerClient> ctx)
        {
            var writer = await _service.PostResults(ctx.InputStream, ctx.RemotePeer);

            ctx.SendValue(s =>
            {
                var oldPosition = s.Position;
                writer(s, ctx.RemotePeer.Serializer());
                //_logger.Log(LogLevel.Trace, "gamesession.postresult", "sending response to postresponse message.", new { Length = s.Position - oldPosition });
            });
        }
Example #18
0
        public async Task GetUserFromBearerToken(RequestContext <IScenePeerClient> ctx)
        {
            var app = await _environment.GetApplicationInfos();

            var data = TokenGenerator.DecodeToken <BearerTokenData>(ctx.ReadObject <string>(), app.PrimaryKey);

            if (data == null)
            {
                throw new ClientException("Invalid Token");
            }
            ctx.SendValue(data.UserId);
        }
Example #19
0
        public async Task Query(RequestContext <IScenePeerClient> ctx)
        {
            var rq = ctx.ReadObject <LeaderboardQuery>();

            if (rq.Count <= 0)
            {
                rq.Count = 10;
            }
            var r = await _leaderboard.Query(rq);

            ctx.SendValue(r);
        }
Example #20
0
        public async Task GetSessionData(RequestContext <IScenePeer> rq)
        {
            var sessionId = _serializer.Deserialize <string>(rq.InputStream);
            var key       = _serializer.Deserialize <string>(rq.InputStream);

            var value = await _sessions.GetSessionData(sessionId, key);

            if (value != null)
            {
                await rq.SendValue(s => s.Write(value, 0, value.Length));
            }
        }
        public async Task GetBearerToken(RequestContext <IScenePeerClient> ctx)
        {
            var sessionId = ctx.RemotePeer.SessionId;
            var app       = await _environment.GetApplicationInfos();

            var session = await _sessions.GetSessionById(sessionId);

            var token = TokenGenerator.CreateToken(new BearerTokenData {
                SessionId = sessionId, pid = session.platformId, userId = session.User.Id, IssuedOn = DateTime.UtcNow, ValidUntil = DateTime.UtcNow + TimeSpan.FromHours(1)
            }, app.PrimaryKey);
            await ctx.SendValue(token);
        }
Example #22
0
    Task OnGetUsersInfos(RequestContext <IScenePeerClient> ctx)
    {
        var users = new List <ChatUserInfo>();

        foreach (ChatUserInfo user in _UsersInfos.Values)
        {
            users.Add(user);
        }

        ctx.SendValue <List <ChatUserInfo> >(users);

        return(Task.FromResult(true));
    }
Example #23
0
        public async Task GetToken(RequestContext <IScenePeerClient> ctx)
        {
            var client = await _accessor.GetApplicationClient();

            var user = await _sessions.GetUser(ctx.RemotePeer);

            var sceneId = ctx.ReadObject <string>();

            _logger.Log(LogLevel.Debug, "authorization", $"Authorizing access to scene '{sceneId}'", new { sceneId, user.Id });
            var token = await client.CreateConnectionToken(sceneId, new byte[0], "application/octet-stream");

            ctx.SendValue(token);
        }
Example #24
0
        public async Task GetSingle(RequestContext <IScenePeerClient> ctx)
        {
            var userId    = ctx.RemotePeer.GetUserData <string>();
            var profileId = ctx.ReadObject <string>();

            if (string.IsNullOrEmpty(profileId))
            {
                throw new ArgumentNullException($"profileId is null. userId={userId}");
            }
            var profile = await this._profileService.GetProfile(profileId);

            if (profile == null)
            {
                profile = await CreatePlayerProfile(ctx.RemotePeer);
            }

            if (profile != null)
            {
                EnsureUserOwnsProfile(userId, profile, "User {0} cannot retrieve a profile owned by user {1}.");
            }
            //_logger.Log(LogLevel.Debug, "profiles", "Get single ", new { metadata = ctx.RemotePeer.Metadata });
            if (!ctx.RemotePeer.Metadata.ContainsKey("bfg.profiles.compression"))
            {
                ctx.SendValue(profile);
            }
            else
            {
                ctx.SendValue(s =>
                {
                    using (var lzStream = new LZ4.LZ4Stream(s, LZ4.LZ4StreamMode.Compress, LZ4.LZ4StreamFlags.HighCompression))
                    {
                        ctx.RemotePeer.Serializer().Serialize(profile, lzStream);
                    }
                });
            }
        }
Example #25
0
        // process the RPC server, send back the data, and start a RPC client
        private async Task OnRpc(RequestContext <IScenePeerClient> reqCtx)
        {
            _scene.GetComponent <ILogger>().Info("rpc", "RPC request received");

            // copy the RPC data
            var copyStream = new MemoryStream();

            reqCtx.InputStream.CopyTo(copyStream);

            // cancellation
            reqCtx.CancellationToken.Register(() =>
            {
                _scene.GetComponent <ILogger>().Info("rpcservercancelled", "RPC on server request cancelled");
                reqCtx.RemotePeer.Send("rpcservercancelled", s =>
                {
                    copyStream.Seek(0, SeekOrigin.Begin);
                    copyStream.CopyTo(s);
                }, PacketPriority.MEDIUM_PRIORITY, PacketReliability.RELIABLE_ORDERED);
            });

            await Task.Delay(1000);

            // if not cancelled, send back the data
            reqCtx.SendValue(s =>
            {
                copyStream.Seek(0, SeekOrigin.Begin);
                copyStream.CopyTo(s);
            });

            // create an async task for the RPC client
            _queue.Enqueue(Task.Run(async() =>
            {
                await Task.Delay(1000);
                var observable = reqCtx.RemotePeer.Rpc("rpc", s =>
                {
                    copyStream.Seek(0, SeekOrigin.Begin);
                    copyStream.CopyTo(s);
                }).Subscribe((p) =>
                {
                    _scene.GetComponent <ILogger>().Warn("rpc", "RPC on client should be cancelled, but a response has been received");
                });

                if (reqCtx.CancellationToken.IsCancellationRequested)
                {
                    observable.Dispose();
                }
            }));
        }
        public async Task GetToken(RequestContext <IScenePeerClient> ctx)
        {
            var client = await _accessor.GetApplicationClient();

            var user = await _sessions.GetUser(ctx.RemotePeer);

            if (user == null)
            {
                throw new ClientException("userDisconnected");
            }
            var sceneId = ctx.ReadObject <string>();

            var token = await client.CreateConnectionToken(sceneId, new byte[0], "application/octet-stream");

            await ctx.SendValue(token);
        }
Example #27
0
        public async Task SendRequest(string userId, RequestContext <IScenePeerClient> ctx)
        {
            var peer = await sessions.GetPeer(userId);

            var sender = await sessions.GetUser(ctx.RemotePeer);

            if (peer == null)
            {
                throw new ClientException($"userDisconnected?id={userId}");
            }
            var tcs = new TaskCompletionSource <bool>();


            var disposable = rpc.Rpc("sendRequest", peer, s =>
            {
                peer.Serializer().Serialize(sender.Id, s);
                ctx.InputStream.CopyTo(s);
            }, PacketPriority.MEDIUM_PRIORITY)
                             .Select(packet => Observable.FromAsync(async() => await ctx.SendValue(s => packet.Stream.CopyTo(s))))
                             .Concat()
                             .Subscribe(
                _ => { },
                (error) => tcs.SetException(error),
                () => tcs.SetResult(true)
                );

            ctx.CancellationToken.Register(() =>
            {
                disposable.Dispose();
            });
            try
            {
                await tcs.Task;
            }
            catch (TaskCanceledException ex)
            {
                if (ex.Message == "Peer disconnected")
                {
                    throw new ClientException($"userDisconnected?id={userId}");
                }
                else
                {
                    throw new ClientException("requestCanceled");
                }
            }
        }
Example #28
0
        public async Task GetToken(RequestContext <IScenePeerClient> ctx)
        {
            _logger.Log(LogLevel.Trace, "authorization", "Receiving a token request to access a scene", new { });

            var client = await _accessor.GetApplicationClient();

            var user = await _sessions.GetUser(ctx.RemotePeer);

            if (user == null)
            {
                throw new ClientException("Client is not logged in.");
            }
            var sceneId = ctx.ReadObject <string>();

            _logger.Log(LogLevel.Debug, "authorization", $"Authorizing access to scene '{sceneId}'", new { sceneId, user.Id });
            var token = await client.CreateConnectionToken(sceneId, new byte[0], "application/octet-stream");

            ctx.SendValue(token);
        }
        Task joinGameProcedure(RequestContext <IScenePeerClient> ctx)
        {
            // Make sure the client sends a unique name
            string name = ctx.ReadObject <string>();

            foreach (KeyValuePair <long, Player> player in mPlayers)
            {
                if (player.Value.name == name)
                {
                    throw new ClientException("The username you chose (\"" + name + "\") is already in use.");
                }
            }

            if (!mPlayers.TryAdd(ctx.RemotePeer.Id, new Player(name)))
            {
                throw new ClientException("The joinGame procedure must be called only once by clients.");
            }

            ctx.SendValue(mMapFilename);
            return(Task.FromResult(true));
        }
Example #30
0
        public async Task GetFile(RequestContext <IScenePeerClient> ctx)
        {
            var         branchName  = ctx.ReadObject <string>();
            var         path        = ctx.ReadObject <string>();
            MetafileDto metafileDto = null;

            try
            {
                metafileDto = await _assetsStorage.GetFile(branchName, path);
            }
            catch (BranchException ex)
            {
                _logger.Log(LogLevel.Warn, "AssetsStorageController", $"Branch not found: { branchName } ", ex.Message);
                throw new ClientException($"Branch Not Found:{ branchName }");
            }
            catch (FileException ex)
            {
                _logger.Log(LogLevel.Warn, "AssetsStorageController", $"File not found:  { path } ", ex.Message);
                throw new ClientException($"File not found :{ path }");
            }

            ctx.SendValue(metafileDto);
        }
        public async Task GetUserFromBearerToken(RequestContext <IScenePeerClient> ctx)
        {
            var app = await _environment.GetApplicationInfos();

            var bearerToken = ctx.ReadObject <string>();

            if (string.IsNullOrEmpty(bearerToken))
            {
                _logger.Log(LogLevel.Error, "authorization", $"Missing bearer token when calling GetUserFromBearerToken()", new { });
            }
            var data = TokenGenerator.DecodeToken <BearerTokenData>(bearerToken, app.PrimaryKey);

            if (data == null)
            {
                throw new ClientException("Invalid Token");
            }

            if (string.IsNullOrEmpty(data?.userId))
            {
                _logger.Log(LogLevel.Error, "authorization", $"Failed to retrieve userId from bearer token data", new { data });
            }
            await ctx.SendValue(data?.userId);
        }
Example #32
0
        public async Task LoadHistory(RequestContext <IScenePeerClient> ctx)
        {
            List <ChatMessageDto> result = new List <ChatMessageDto>();

            try
            {
                long startTimestamp = ctx.ReadObject <long>();
                long endTimestamp   = ctx.ReadObject <long>();

                DateTime start = TimestampHelper.UnixTimeStampSecondToDateTime(startTimestamp);
                DateTime end   = TimestampHelper.UnixTimeStampSecondToDateTime(endTimestamp);

                string channelName  = ctx.RemotePeer.SceneId;
                var    messagesData = await _chat.LoadHistory(channelName, start, end);

                foreach (ChatMessage msg in messagesData)
                {
                    var message = new ChatMessageDto {
                        Message   = msg.Message,
                        TimeStamp = TimestampHelper.DateTimeToUnixTimeStamp(msg.Date),
                        UserInfo  = new ChatUserInfoDto
                        {
                            UserId = msg.UserInfo.UserId,
                            Data   = msg.UserInfo.Data.ToString(),
                        }
                    };
                    result.Add(message);
                }
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, _logCategory, "Error occured when server try to load history", ex);
                throw new ClientException(ex.Message);
            }

            ctx.SendValue(result);
        }
        private Task onJoinGame(RequestContext<IScenePeerClient> packet)
        {
            GameInfos game = packet.ReadObject<GameInfos>();

            game = m_games.Find(npc => { return (npc.IDOwner == game.IDOwner); });
            if (game.Playing || game.IDPlayers.Count == game.MaxPlayer)
            {
                packet.SendValue(null);
                return Task.FromResult(true);
            }
            game.IDPlayers[packet.RemotePeer.Id] = m_players[packet.RemotePeer];
            foreach (IScenePeerClient client in m_scene.RemotePeers)
                foreach (long key in game.IDPlayers.Keys)
                    if (client.Id == key && key != packet.RemotePeer.Id)
                        client.Send("UpdateGame", game);
            packet.SendValue(game);
            return Task.FromResult(true);
        }
Example #34
0
 private async Task UseSkill(RequestContext<IScenePeerClient> args)
 {
     string errorMsg = null;
     if (!await UseSkillImpl(args))
     {
         args.SendValue(new UseSkillResponse { error = true, errorMsg = errorMsg });
     }
 }
        public Task OnRequestObjects(RequestContext<IScenePeer> ctx)
        {
           List<ReplicatorDTO> dtos = new List<ReplicatorDTO>();

            foreach(StormancerNetworkIdentity ni in LocalObjectToSync)
            {
                ReplicatorDTO dto = new ReplicatorDTO();

                dto.Id = ni.Id;
                dto.PrefabId = ni.PrefabId;
                dto.ClientId = ClientProvider.GetClientId(); ;

                dtos.Add(dto);
            }
            ctx.SendValue<List<ReplicatorDTO>>(dtos);
            Debug.Log("receiving objects for new player. Sent " + dtos.Count + " objects.");
            return TaskHelper.FromResult(true);
        }
 private Task onTest(RequestContext<IScenePeerClient> ctx)
 {
     ctx.SendValue("");
     return Task.FromResult(true);
 }
Example #37
0
        private Task OnGetShipInfos(RequestContext<IScenePeerClient> arg)
        {

            var shipIds = arg.ReadObject<ushort[]>();

            var ships = new List<ShipCreatedDto>(shipIds.Length);
            foreach (var id in shipIds)
            {
                Ship ship;
                if (_ships.TryGetValue(id, out ship))
                {
                    ships.Add(new ShipCreatedDto { timestamp = _scene.GetComponent<IEnvironment>().Clock, id = ship.id, team = ship.team, x = ship.x, y = ship.y, rot = ship.rot, weapons = ship.weapons, status = ship.Status });
                }
            }

            arg.SendValue(ships);
            return Task.FromResult(true);

        }
    Task OnGetUsersInfos(RequestContext<IScenePeerClient> ctx)
    {
        var users = new List<ChatUserInfo>();

        foreach(ChatUserInfo user in _UsersInfos.Values)
        {
            users.Add(user);
        }

        ctx.SendValue<List<ChatUserInfo>>(users);

        return Task.FromResult(true);
    }
        // OnClick is a reponse procedure handling the "click" rpc request sent by a client
        // We receive a Stream containing click information sent by a client and send back a stream telling the player whether he touched a ball or not and his life.
        // If a ball have been hit, the server telle very client to destory it.
        //
        private Task OnClick(RequestContext<IScenePeerClient> ctx)
        {
            Player player;
            if (_players.TryGetValue(ctx.RemotePeer.Id, out player))
            {
                //bool hitGoodBall = false;
               // bool touched = false;
                var reader = new BinaryReader(ctx.InputStream);
                float x = reader.ReadSingle();
                float y = reader.ReadSingle();
                long timestamp = reader.ReadInt32();

                Ball temp;
                Ball hitBall = null;

                bool hitGoodBall = TryFindHitBall(x,y,timestamp, out hitBall);
                
                if (hitBall != null)
                {
                    if (hitGoodBall)
                    {
                        player.score++;
                        player.streak++;
                        if (player.score > player.record)
                            player.record = player.score;
                        if (player.streak >= 5)
                        {
                            player.streak = 0;
                            player.Life++;
                            if (player.Life > 3)
                                player.Life = 3;
                            ctx.SendValue(s => 
                            {
                                var writer = new BinaryWriter(s, Encoding.UTF8, false);
                                writer.Write(3);
                                writer.Write(player.Life);
                            });
                        }
                        else
                            ctx.SendValue(s => { var writer = new BinaryWriter(s, Encoding.UTF8, false); writer.Write(1); });
                        _scene.Broadcast("destroy_ball", s =>
                        {
                            var writer = new BinaryWriter(s, Encoding.UTF8, false);
                            writer.Write(hitBall.id);
                        }, PacketPriority.MEDIUM_PRIORITY, PacketReliability.RELIABLE_SEQUENCED);
                        _balls.TryRemove(hitBall.id, out temp);
                    }
                    else
                    {
                        player.streak = 0;
                        player.Life--;
                        ctx.SendValue(s => 
                        {
                            var writer = new BinaryWriter(s, Encoding.UTF8, false);
                            writer.Write(2);
                            writer.Write(_players[ctx.RemotePeer.Id].Life);
                        });
                        _scene.Broadcast("destroy_ball", s =>
                        {
                            var writer = new BinaryWriter(s, Encoding.UTF8, false);
                            writer.Write(hitBall.id);
                        }, PacketPriority.MEDIUM_PRIORITY, PacketReliability.RELIABLE_SEQUENCED);
                        _balls.TryRemove(hitBall.id, out temp);
                        if (_players[ctx.RemotePeer.Id].Life <= 0)
                        {
                            _players[ctx.RemotePeer.Id].Life = 3;
                            _players[ctx.RemotePeer.Id].score = 0;
                        }
                    }
                }
                if (hitBall == null)
                    ctx.SendValue(s => { var writer = new BinaryWriter(s, Encoding.UTF8, false); writer.Write(0); });
            }
            return Task.FromResult(true);
        }
        // onUpdateLeaderBoard is a rpc resqponse procedure handling the "update_leaderboard" rpc request sent by a client
        // We receive nothing (null) and send a leaderboard data transfert object containing the leaderboard informations to be displayed by the client.
        //
        private Task OnUpdateLeaderBoard(RequestContext<IScenePeerClient> ctx)
        {
            List<Player> playerList = _players.Values.ToList();
            LeaderBoardDtO board = new LeaderBoardDtO();

            playerList.OrderByDescending(x => x.record);

            int i = 0;
            while (i < playerList.Count && i < 5)
            {
                board.names[i] = playerList[i].name;
                board.scores[i] = playerList[i].record.ToString();
                i++;
            }
            while (i < 5)
            {
                board.names[i] = "";
                board.scores[i] = "";
                i++;
            }
            if (_players.ContainsKey(ctx.RemotePeer.Id))
            {
                board.localNbr = _players[ctx.RemotePeer.Id].score.ToString();
            }
            ctx.SendValue(board);
            return Task.FromResult(true);
        }
        private async Task CreateAccount(RequestContext<IScenePeerClient> p, ISceneHost scene)
        {
            try
            {
                var userService = scene.GetComponent<IUserService>();
                var rq = p.ReadObject<CreateAccountRequest>();

                scene.GetComponent<ILogger>().Log(LogLevel.Trace, "user.provider.loginpassword", "Creating user " + rq.Login + ".", rq.Login);
                ValidateLoginPassword(rq.Login, rq.Password);

                var user = await userService.GetUserByClaim(PROVIDER_NAME, "login", rq.Login);

                if (user != null)
                {
                    scene.GetComponent<ILogger>().Log(LogLevel.Trace, "user.provider.loginpassword", "User with login " + rq.Login + " already exists.", rq.Login);

                    throw new ClientException("An user with this login already exist.");
                }

                user = await userService.GetUser(p.RemotePeer);
                if (user == null)
                {
                    try
                    {
                        var uid = PROVIDER_NAME + "-" + rq.Login;
                        user = await userService.CreateUser(uid, JObject.Parse(rq.UserData));
                    }
                    catch (Exception ex)
                    {
                        scene.GetComponent<ILogger>().Log(LogLevel.Trace, "user.provider.loginpassword", "Couldn't create user " + rq.Login + ".", ex);

                        throw new ClientException("Couldn't create account : " + ex.Message);
                    }
                }

                var salt = GenerateSaltValue();

                try
                {
                    await userService.AddAuthentication(user, PROVIDER_NAME, JObject.FromObject(new
                    {
                        login = rq.Login,
                        email = rq.Email,
                        salt = salt,
                        password = HashPassword(rq.Password, salt),
                        validated = false,
                    }));
                }
                catch (Exception ex)
                {
                    scene.GetComponent<ILogger>().Log(LogLevel.Trace, "user.provider.loginpassword", "Couldn't link account " + rq.Login + ".", ex);

                    throw new ClientException("Couldn't link account : " + ex.Message);
                }

                scene.GetComponent<ILogger>().Log(LogLevel.Trace, "user.provider.loginpassword", "Creating user " + rq.Login + ".", rq.Login);
                p.SendValue(new LoginResult
                {
                    Success = true
                });


            }
            catch (Exception ex)
            {
                p.SendValue(new LoginResult { ErrorMsg = ex.Message, Success = false });
            }
        }
        // process the RPC server, send back the data, and start a RPC client
        private async Task OnRpc(RequestContext<IScenePeerClient> reqCtx)
        {
            _scene.GetComponent<ILogger>().Info("rpc", "RPC request received");

            // copy the RPC data
            var copyStream = new MemoryStream();
            reqCtx.InputStream.CopyTo(copyStream);
            
            // cancellation
            reqCtx.CancellationToken.Register(() =>
            {
                _scene.GetComponent<ILogger>().Info("rpcservercancelled", "RPC on server request cancelled");
                reqCtx.RemotePeer.Send("rpcservercancelled", s =>
                {
                    copyStream.Seek(0, SeekOrigin.Begin);
                    copyStream.CopyTo(s);
                }, PacketPriority.MEDIUM_PRIORITY, PacketReliability.RELIABLE_ORDERED);
            });

            await Task.Delay(1000);

            // if not cancelled, send back the data
            reqCtx.SendValue(s =>
            {
                copyStream.Seek(0, SeekOrigin.Begin);
                copyStream.CopyTo(s);
            });

            // create an async task for the RPC client
            _queue.Enqueue(Task.Run(async () =>
            {
                await Task.Delay(1000);
                var observable = reqCtx.RemotePeer.Rpc("rpc", s =>
                {
                    copyStream.Seek(0, SeekOrigin.Begin);
                    copyStream.CopyTo(s);
                }).Subscribe((p) =>
                {
                    _scene.GetComponent<ILogger>().Warn("rpc", "RPC on client should be cancelled, but a response has been received");
                });

                if (reqCtx.CancellationToken.IsCancellationRequested)
                {
                    observable.Dispose();
                }
            }));
        }
 private Task OnRpcPing(RequestContext<IScenePeerClient> reqCtx)
 {
     reqCtx.SendValue((ulong)_scene.GetComponent<IEnvironment>().Clock);
     return Task.FromResult(true);
 }
Example #44
0
        private async Task<bool> UseSkillImpl(RequestContext<IScenePeerClient> arg)
        {

            var env = _scene.GetComponent<IEnvironment>();
            var p = arg.ReadObject<UserSkillRequest>();
            var ship = _ships[_players[arg.RemotePeer.Id].ShipId];

            if (ship.Status != ShipStatus.InGame || ship.currentPv <= 0)
            {
                return false;
                //throw new ClientException("You can only use skills during games.");
            }

            var timestamp = _scene.GetComponent<IEnvironment>().Clock;
            var weapon = ship.weapons.FirstOrDefault(w => w.id == p.skillId);
            if (weapon == null)
            {
                return false;
                //throw new ClientException(string.Format("Skill '{0}' not available.", p.skillId));
            }

            if (weapon.fireTimestamp + weapon.coolDown > timestamp)
            {
                return false;
                //throw new ClientException("Skill in cooldown.");
            }
            if (!_ships.ContainsKey(p.target))
            {
                return false;
            }

            var target = _ships[p.target];
            if (target.Status != ShipStatus.InGame)
            {
                return false;
                //throw new ClientException("Can only use skills on ships that are in game.");
            }
            var dx = ship.x - target.x;
            var dy = ship.y - target.y;
            if (weapon.range * weapon.range < dx * dx + dy * dy)
            {
                return false;
                //throw new ClientException("Target out of range.");
            }

            weapon.fireTimestamp = timestamp;
            var success = _rand.Next(100) < weapon.precision * 100;
            if (success)
            {
                if (target.currentPv > 0)
                {
                    target.ChangePv(-weapon.damage);
                }
            }

            this.RegisterSkill(ship.id, target.id, success, weapon.id, timestamp);

            arg.SendValue(new UseSkillResponse { error = false, errorMsg = null, skillUpTimestamp = weapon.fireTimestamp + weapon.coolDown, success = success });
            return true;
        }
        // OnPlay is a response procedure handling the "play" rpc request sent by a client
        // An Rpc response procedure is created by server when an rpc request is received. These are totaly asynchronous so it can handle multiple rpc at the same time.
        // Here, we receive a Connection Data Transfert Object and send back an int to tell the client whether he can play or not.
        //
        private Task OnPlay(RequestContext<IScenePeerClient> ctx)
        {
            // we use RequestContext.ReadObject<Type>() to deserialize to data received from the Client.
            string name = ctx.ReadObject<ConnectionDtO>().name.ToLower();
            bool nameAlreadyTaken = false;

            foreach (var p in _players.Values)
            {
                string temp = p.name.ToLower();
                if (temp == name)
                {
                    nameAlreadyTaken = true;
                    break;
                }
            }
            if (nameAlreadyTaken == false)
            {
                var player = new Player(name);
                _log.Debug("main", "client joined with name : " + player.name);
                _players.TryAdd(ctx.RemotePeer.Id, player);
                ctx.SendValue(0);
            }
            else
            {
                ctx.SendValue(1);
            }
            return Task.FromResult(true);
        }
        public Task OnRegisterObject(RequestContext<IScenePeerClient> ctx)
        {
            _log.Debug("replicator", "registering object");
            var dto = ctx.ReadObject<ReplicatorDTO>();
            var obj = new ReplicatorObject();

            obj.Client = ctx.RemotePeer;
            obj.PrefabId = dto.PrefabId;
            obj.Id = Ids++;

            dto.Id = obj.Id;

            ctx.SendValue<ReplicatorDTO>(dto);

            foreach(IScenePeerClient client in _scene.RemotePeers)
            {
                if (client.Id != ctx.RemotePeer.Id)
                {
                    client.Send<ReplicatorDTO>("CreateObject", dto);
                }
            }
            return Task.FromResult(true);
        }