/// <summary> /// 当用户与机器人不再为好友时,通过此方法通知协调器 /// </summary> /// <param name="userSteamId">用户 Steam ID</param> /// <param name="botId">机器人 ID</param> public async Task OnUserBotRelationshipNone(string userSteamId, string botId) { using (var dbContext = new KeylolDbContext()) { var userManager = new KeylolUserManager(dbContext); var user = await userManager.FindBySteamIdAsync(userSteamId); if (user == null) { // 非会员不再为好友时,如果存在已绑定的 SteamBindingToken 则清除之 var bindingTokens = await dbContext.SteamBindingTokens .Where(t => t.SteamId == userSteamId && t.BotId == botId) .ToListAsync(); dbContext.SteamBindingTokens.RemoveRange(bindingTokens); await dbContext.SaveChangesAsync(KeylolDbContext.ConcurrencyStrategy.DatabaseWin); } else if (user.SteamBotId == botId) { // 会员与自己的机器人不再为好友时,解除机器人绑定 user.SteamBotId = null; await dbContext.SaveChangesAsync(KeylolDbContext.ConcurrencyStrategy.DatabaseWin); } } }
/// <summary> /// 判断指定 Steam 账户是不是其乐用户并且匹配指定机器人 /// </summary> /// <param name="steamId">Steam ID</param> /// <param name="botId">机器人 ID</param> /// <returns><c>true</c> 表示是其乐用户并于目标机器人匹配,<c>false</c> 表示不是</returns> public async Task <bool> IsKeylolUser(string steamId, string botId) { using (var dbContext = new KeylolDbContext()) { var userManager = new KeylolUserManager(dbContext); var user = await userManager.FindBySteamIdAsync(steamId); return(user != null && user.SteamBotId == botId); } }
/// <summary> /// 更新指定用户的属性 /// </summary> /// <param name="steamId">要更新的用户 Steam ID</param> /// <param name="profileName">Steam 昵称,<c>null</c> 表示不更新</param> public async Task UpdateUser(string steamId, string profileName) { using (var dbContext = new KeylolDbContext()) { var userManager = new KeylolUserManager(dbContext); var user = await userManager.FindBySteamIdAsync(steamId); if (user == null) { return; } if (profileName != null) { user.SteamProfileName = profileName; } await dbContext.SaveChangesAsync(KeylolDbContext.ConcurrencyStrategy.DatabaseWin); } }
/// <summary> /// 当机器人收到新的聊天消息时,通过此方法通知协调器 /// </summary> /// <param name="senderSteamId">消息发送人 Steam ID</param> /// <param name="botId">机器人 ID</param> /// <param name="message">聊天消息内容</param> public async Task OnBotNewChatMessage(string senderSteamId, string botId, string message) { using (var dbContext = new KeylolDbContext()) { var userManager = new KeylolUserManager(dbContext); var user = await userManager.FindBySteamIdAsync(senderSteamId); if (user == null) { // 非会员,只接受绑定验证码 var code = message.Trim(); var token = await dbContext.SteamBindingTokens .SingleOrDefaultAsync(t => t.Code == code && t.SteamId == null); if (token == null) { await Client.SendChatMessage(botId, senderSteamId, "你的输入无法被识别,请确认登录验证码的长度和格式。如果需要帮助,请与其乐职员取得联系。"); } else { token.BotId = botId; token.SteamId = senderSteamId; await dbContext.SaveChangesAsync(KeylolDbContext.ConcurrencyStrategy.DatabaseWin); NotificationProvider.Hub <SteamBindingHub, ISteamBindingHubClient>() .Client(token.BrowserConnectionId)? .OnBind(await Client.GetUserProfileName(botId, senderSteamId), await Client.GetUserAvatarHash(botId, senderSteamId)); await Client.SendChatMessage(botId, senderSteamId, "绑定成功,欢迎加入其乐!今后你可以向机器人发送对话快速登录社区,请勿将机器人从好友列表移除。"); await Task.Delay(TimeSpan.FromSeconds(5)); await Client.SendChatMessage(botId, senderSteamId, "若希望在其乐上获得符合游戏兴趣的据点推荐,请避免将 Steam 资料隐私设置为「仅自己可见」。"); } } else { // 已有会员,接受登录验证码和调侃调戏 var match = Regex.Match(message, @"^\s*(\d{4})\s*$"); if (match.Success) { var code = match.Groups[1].Value; try { var connectionId = await _oneTimeToken.Consume <string>(code, OneTimeTokenPurpose.SteamLogin); var loginToken = await _oneTimeToken.Generate(user.Id, TimeSpan.FromMinutes(1), OneTimeTokenPurpose.UserLogin); NotificationProvider.Hub <SteamLoginHub, ISteamLoginHubClient>() .Client(connectionId).OnLoginOneTimeToken(loginToken, user.UserName, user.AvatarImage); await Client.SendChatMessage(botId, senderSteamId, "欢迎回来,你已成功登录其乐社区。"); } catch (Exception) { await Client.SendChatMessage(botId, senderSteamId, "你的输入无法被识别,请确认登录验证码的长度和格式。如果需要帮助,请与其乐职员取得联系。"); } } else { if (!AutoChatDisabledBots.ContainsKey(botId)) { await Client.SendChatMessage(botId, senderSteamId, await AskTulingBotAsync(message, user.Id), true); } } } } }
/// <summary> /// 当机器人接收到用户好友请求时,通过此方法通知协调器 /// </summary> /// <param name="userSteamId">用户 Steam ID</param> /// <param name="botId">机器人 ID</param> public async Task OnBotNewFriendRequest(string userSteamId, string botId) { await Client.AddFriend(botId, userSteamId); // 先接受请求 using (var dbContext = new KeylolDbContext()) { var userManager = new KeylolUserManager(dbContext); var user = await userManager.FindBySteamIdAsync(userSteamId); if (user == null) { // 非会员,在注册时绑定机器人 NotificationProvider.Hub <SteamBindingHub, ISteamBindingHubClient>() .Clients(await dbContext.SteamBindingTokens.Where(t => t.BotId == botId) .Select(t => t.BrowserConnectionId) .ToListAsync())? .OnFriend(); await Task.Delay(TimeSpan.FromSeconds(3)); await Client.SendChatMessage(botId, userSteamId, "欢迎使用当前 Steam 账号加入其乐,请输入你在网页上获取的 8 位绑定验证码。"); var queueName = MqClientProvider.SteamBotDelayedActionQueue(botId); _mqChannel.QueueDeclare(queueName, true, false, false, null); _mqChannel.SendMessage(MqClientProvider.DelayedMessageExchange, queueName, new SteamBotDelayedActionDto { Type = SteamBotDelayedActionType.RemoveFriend, Properties = new { OnlyIfNotKeylolUser = true, Message = "抱歉,你的会话因超时被强制结束,机器人已将你从好友列表中暂时移除。若要加入其乐,请重新按照网页指示注册账号。", SteamId = userSteamId } }, 300000); } else { // 现有会员添加机器人为好友 var bot = await dbContext.SteamBots.FindAsync(botId); if (user.SteamBotId == null && bot != null && bot.FriendCount < bot.FriendUpperLimit) { // 用户此前删除了机器人好友,重新设定当前机器人为绑定的机器人 user.SteamBotId = botId; user.SteamBindingTime = DateTime.Now; await dbContext.SaveChangesAsync(KeylolDbContext.ConcurrencyStrategy.DatabaseWin); await Task.Delay(TimeSpan.FromSeconds(3)); await Client.SendChatMessage(botId, userSteamId, "你已成功与其乐机器人再次绑定,请务必不要将其乐机器人从好友列表中移除。"); } else { // 用户状态正常但是添加了新的机器人好友,应当移除好友 await Task.Delay(TimeSpan.FromSeconds(3)); await Client.SendChatMessage(botId, userSteamId, "你已绑定另一其乐机器人,当前机器人已拒绝你的好友请求。如有需要,你可以在其乐设置表单中找到你绑定的机器人帐号。"); await Client.RemoveFriend(botId, userSteamId); } } } }