public async Task <SessionToken> BeginSessionAsync( AuthToken token, string clientVersion, string accessKey, bool isLocal, float syncTime) { var game = gameData.Client; var user = gameData.GetUser(token.UserId); if (game == null) { return(null); } if (game.AccessKey != accessKey) { return(null); } var userId = token.UserId; var activeSession = gameData.GetUserSession(userId); // x => x.UserId == userId && x.Status == (int)SessionStatus.Active if (activeSession != null) { EndSession(activeSession); } var newGameSession = gameData.CreateSession(userId); gameData.Add(newGameSession); var sessionState = gameData.GetSessionState(newGameSession.Id); sessionState.SyncTime = syncTime; var isAdmin = user.IsAdmin.GetValueOrDefault(); var isModerator = user.IsModerator.GetValueOrDefault(); var subInfo = await twitchClient.GetSubscriberAsync(user.UserId); var subscriptionTier = 0; var expMultiplierLimit = 0; if (subInfo != null && int.TryParse(subInfo.Tier, out subscriptionTier)) { subscriptionTier /= 1000; expMultiplierLimit = subscriptionTier == 1 ? 10 : (subscriptionTier - 1) * 25; } if (isModerator) { subscriptionTier = 3; expMultiplierLimit = 50; } if (isAdmin) { subscriptionTier = 3; expMultiplierLimit = 5000; } if (isAdmin || isModerator || subInfo != null) { var permissionEvent = gameData.CreateSessionEvent( GameEventType.PermissionChange, newGameSession, new Permissions { IsAdministrator = user.IsAdmin ?? false, IsModerator = user.IsModerator ?? false, SubscriberTier = subscriptionTier, ExpMultiplierLimit = expMultiplierLimit, }); gameData.Add(permissionEvent); } var village = gameData.GetOrCreateVillageBySession(newGameSession); var villageHouses = gameData.GetOrCreateVillageHouses(village); var villageInfoEvent = gameData.CreateSessionEvent( GameEventType.VillageInfo, newGameSession, new VillageInfo { Name = village.Name, Level = village.Level, Experience = village.Experience, Houses = villageHouses.Select(x => new VillageHouseInfo { Owner = x.UserId != null ? gameData.GetUser(x.UserId.Value).UserId : null, Slot = x.Slot, Type = x.Type } ).ToList() } ); gameData.Add(villageInfoEvent); return(GenerateSessionToken(token, newGameSession)); }