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;
}
}