| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- using CSRedis;
- using dodohold.core;
- namespace molilian.core
- {
- /// <summary>
- /// 隐藏号判断:隐藏号命中的转链只返回 deeplink,不产生任何日志、统计、上报数据
- /// </summary>
- public static class HiddenAccountCore
- {
- // 同一隐藏号当天同 ip / oaid 只转成功一次
- private const int OnceDoneExpireSeconds = 86400;
- // 转链进行中的占位,防止同一用户并发请求重复转成功
- private const int OncePendingExpireSeconds = 120;
- public static Task<bool> IsHiddenAsync(TkChannelEnum channel, int accountId)
- {
- return IsHiddenAsync(channel.ToString(), accountId);
- }
- public static async Task<bool> IsHiddenAsync(string channel, int accountId)
- {
- if (accountId <= 0) return false;
- switch ((channel ?? string.Empty).ToLowerInvariant())
- {
- case "tb":
- var tbAccount = await TkPoolCore.ALLGetOneAsync(accountId);
- return tbAccount != null && tbAccount.is_hide;
- case "pdd":
- var pddAccounts = await PddPoolCore.AllListAsync();
- var pddAccount = pddAccounts?.FirstOrDefault(e => e.id == accountId);
- return pddAccount != null && pddAccount.is_hide;
- default:
- return false;
- }
- }
- /// <summary>
- /// 占用隐藏号当天的 ip / oaid 名额。当天已转成功或正在转链时返回 false。
- /// </summary>
- public static bool TryReserveOnce(TkChannelEnum channel, int accountId, string ip, string oaid)
- {
- var keys = BuildOnceKeys(channel, accountId, ip, oaid);
- var reserved = new List<string>();
- foreach (var key in keys)
- {
- if (!RedisHelper.Set(key, "pending", OncePendingExpireSeconds, RedisExistence.Nx))
- {
- if (reserved.Count > 0) RedisHelper.Del(reserved.ToArray());
- return false;
- }
- reserved.Add(key);
- }
- return true;
- }
- /// <summary>
- /// 转链结束:成功则标记当天已转(同步到所有节点),失败则释放占位
- /// </summary>
- public static async Task CompleteOnceAsync(TkChannelEnum channel, int accountId, string ip, string oaid, bool success)
- {
- var keys = BuildOnceKeys(channel, accountId, ip, oaid);
- if (keys.Count == 0) return;
- try
- {
- if (!success)
- {
- RedisHelper.Del(keys.ToArray());
- return;
- }
- foreach (var key in keys) RedisHelper.Set(key, "done", OnceDoneExpireSeconds);
- await EndPointCore.ProcessEndPointNodesAsync(node =>
- {
- if (string.IsNullOrEmpty(node.redis_server)) return Task.CompletedTask;
- if (!node.is_public_api) return Task.CompletedTask;
- try
- {
- var redis = RedisClientManager.GetRedisClient(node.redis_server);
- foreach (var key in keys) redis.Set(key, "done", OnceDoneExpireSeconds);
- }
- catch (Exception ex)
- {
- _ = new LoggerLibrary("HiddenAccountCore", "CompleteOnce")
- .Info(node.name, ex.Message)
- .SaveAsync();
- }
- return Task.CompletedTask;
- });
- }
- catch (Exception ex)
- {
- _ = new LoggerLibrary("HiddenAccountCore", "CompleteOnce")
- .Info(ex.Message, ex.StackTrace)
- .SaveAsync();
- }
- }
- private static List<string> BuildOnceKeys(TkChannelEnum channel, int accountId, string ip, string oaid)
- {
- string prefix = $":hide_once:{channel}_{accountId}:{DateTime.Now:yyyyMMdd}";
- var keys = new List<string>();
- if (!string.IsNullOrEmpty(ip)) keys.Add($"{prefix}:ip:{ip}");
- if (!string.IsNullOrEmpty(oaid)) keys.Add($"{prefix}:oaid:{oaid}");
- return keys;
- }
- }
- }
|