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); }
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}'."); } }
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"); }
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); }
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); } }
public async Task Cursor(RequestContext <IScenePeerClient> ctx) { var cursor = ctx.ReadObject <string>(); var result = await _leaderboard.QueryCursor(cursor); ctx.SendValue(result); }
/// <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); }
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)); }
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)); }
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); }
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)); }
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)); }
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)); }
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()); }); }
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); }
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 }); }); }
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); }
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); }
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); }
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)); }
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); }
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); } }); } }
// 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); }
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"); } } }
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)); }
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); }
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); }
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); }
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); }
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); }