/// <inheritdoc /> public override async Task HandleMessage(IPeerSessionMessageContext <GameServerPacketPayload> context, ClientSessionClaimRequestPayload payload) { //TODO: We need better validation/authorization for clients trying to claim a session. Right now it's open to malicious attack ZoneServerTryClaimSessionResponse zoneServerTryClaimSessionResponse = null; try { ProjectVersionStage.AssertAlpha(); zoneServerTryClaimSessionResponse = await GameServerClient.TryClaimSession(new ZoneServerTryClaimSessionRequest(await GameServerClient.GetAccountIdFromToken(payload.JWT), payload.CharacterId)) .ConfigureAwaitFalse(); } catch (Exception e) //we could get an unauthorized response { Logger.Error($"Failed to Query for AccountId: {e.Message}. AuthToken provided was: {payload.JWT}"); throw; } if (!zoneServerTryClaimSessionResponse.isSuccessful) { if (Logger.IsWarnEnabled) { Logger.Warn($"Client attempted to claim session for Character: {payload.CharacterId} but was denied."); } //TODO: Better error code await context.PayloadSendService.SendMessage(new ClientSessionClaimResponsePayload(ClientSessionClaimResponseCode.SessionUnavailable)) .ConfigureAwaitFalse(); return; } NetworkEntityGuid entityGuid = new NetworkEntityGuidBuilder() .WithId(payload.CharacterId) .WithType(EntityType.Player) .Build(); //TODO: We assume they are authenticated, we don't check at the moment but we WILL and SHOULD. Just load their location. ZoneServerCharacterLocationResponse locationResponse = await GameServerClient.GetCharacterLocation(payload.CharacterId) .ConfigureAwaitFalse(); Vector3 position = locationResponse.isSuccessful ? locationResponse.Position : SpawnPointProvider.GetSpawnPoint().WorldPosition; SpawnPointData pointData = new SpawnPointData(position, Quaternion.identity); if (Logger.IsDebugEnabled) { Logger.Debug($"Recieved player location: {pointData.WorldPosition} from {(locationResponse.isSuccessful ? "Database" : "Spawnpoint")}"); } //TODO: We need a cleaner/better way to load initial player data. ResponseModel <CharacterDataInstance, CharacterDataQueryReponseCode> characterData = await CharacterService.GetCharacterData(payload.CharacterId); //TODO: Check success. InitialCharacterDataMappable.AddObject(entityGuid, characterData.Result); //Just broadcast successful claim, let listeners figure out what to do with this information. OnSuccessfulSessionClaimed?.Invoke(this, new PlayerSessionClaimedEventArgs(entityGuid, pointData.WorldPosition, new PlayerEntitySessionContext(context.PayloadSendService, context.Details.ConnectionId, context.ConnectionService))); await context.PayloadSendService.SendMessage(new ClientSessionClaimResponsePayload(ClientSessionClaimResponseCode.Success)) .ConfigureAwaitFalse(); }