using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace BarrageGrab { /// /// 快手礼物ID→名称映射表,通过代理嗅探自动收集 /// public static class KsGiftHelper { private static readonly ConcurrentDictionary GiftNames = new ConcurrentDictionary(); private static readonly string GiftCachePath; static KsGiftHelper() { GiftCachePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ks_gifts.json"); LoadMapping(); } /// /// 获取礼物名称,找不到返回 null /// public static string GetGiftName(uint giftId) { GiftNames.TryGetValue(giftId, out var name); return name; } /// /// 尝试从任意 JSON 字符串中解析礼物映射 /// 支持多种快手 API 返回格式: /// - giftList: [{id:1, name:"小红花"}, ...] /// - giftPanelList: [{id:1, giftName:"小红花"}, ...] /// - allGifts: {"1": {name:"小红花"}, ...} /// 返回是否解析到了新数据 /// public static bool TryParseGiftData(string json) { if (string.IsNullOrWhiteSpace(json)) return false; json = json.Trim(); if (json.Length < 10) return false; bool added = false; try { // 如果 JSON 以数组开头,需要特殊处理 if (json.StartsWith("[")) { var arr = JArray.Parse(json); added = ParseGiftArray(arr) || added; return added; } var obj = JObject.Parse(json); // 方式1: giftList → [{id, name}] 或 giftList → [{id, giftName}] var giftList = obj["giftList"] as JArray; if (giftList != null) { added = ParseGiftArray(giftList) || added; } // 方式2: giftPanelList → [{id, name}] var giftPanelList = obj["giftPanelList"] as JArray; if (giftPanelList != null) { added = ParseGiftArray(giftPanelList) || added; } // 方式3: allGifts → {"1": {name:"xxx"}, "2": {...}} var allGifts = obj["allGifts"] as JObject; if (allGifts != null) { foreach (var kv in allGifts) { if (uint.TryParse(kv.Key, out var gid)) { var name = kv.Value?["name"]?.Value() ?? kv.Value?["giftName"]?.Value() ?? kv.Value?["title"]?.Value(); if (!string.IsNullOrWhiteSpace(name)) { added = UpdateMapping(gid, name) || added; } } } } // 方式4: data.giftList / data.giftPanelList / result.giftList var data = obj["data"] ?? obj["result"]; if (data is JObject dataObj) { var dataGiftList = dataObj["giftList"] as JArray; if (dataGiftList != null) { added = ParseGiftArray(dataGiftList) || added; } var dataGiftPanel = dataObj["giftPanelList"] as JArray; if (dataGiftPanel != null) { added = ParseGiftArray(dataGiftPanel) || added; } } } catch { // 不是有效 JSON,忽略 } return added; } private static bool ParseGiftArray(JArray arr) { bool added = false; foreach (var item in arr) { if (item is JObject giftObj) { var idToken = giftObj["id"] ?? giftObj["giftId"]; var nameToken = giftObj["giftName"] ?? giftObj["name"] ?? giftObj["title"] ?? giftObj["displayName"]; if (idToken != null && nameToken != null) { uint id = 0; if (idToken.Type == JTokenType.Integer) id = idToken.Value(); else if (idToken.Type == JTokenType.String && uint.TryParse(idToken.Value(), out var sid)) id = sid; else continue; var name = nameToken.Value(); if (!string.IsNullOrWhiteSpace(name) && id > 0) { added = UpdateMapping(id, name) || added; } } } } return added; } private static bool UpdateMapping(uint giftId, string giftName) { if (GiftNames.TryGetValue(giftId, out var existing) && existing == giftName) return false; GiftNames[giftId] = giftName; Logger.LogInfo($"KS礼物映射: #{giftId} → {giftName}"); return true; } /// /// 保存映射到本地文件 /// public static void SaveMapping() { if (GiftNames.Count == 0) return; try { var dict = new Dictionary(); foreach (var kv in GiftNames) dict[kv.Key] = kv.Value; var json = JsonConvert.SerializeObject(dict, Formatting.Indented); File.WriteAllText(GiftCachePath, json); Logger.LogInfo($"KS礼物映射已保存 ({GiftNames.Count} 个) → {GiftCachePath}"); } catch (Exception ex) { Logger.LogWarn($"保存KS礼物映射失败: {ex.Message}"); } } /// /// 从本地文件加载映射 /// private static void LoadMapping() { try { if (!File.Exists(GiftCachePath)) return; var json = File.ReadAllText(GiftCachePath); var dict = JsonConvert.DeserializeObject>(json); if (dict != null) { foreach (var kv in dict) { GiftNames[kv.Key] = kv.Value; } Logger.LogInfo($"KS礼物映射已加载 ({GiftNames.Count} 个) → {GiftCachePath}"); } } catch (Exception ex) { Logger.LogWarn($"加载KS礼物映射失败: {ex.Message}"); } } /// /// 获取当前映射数量 /// public static int Count => GiftNames.Count; } }