using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.SceneManagement;
using ValMod.Localization.DeepSeekApi;
using ValModLocalization.Data;
using local;
using 全局本地化.Data;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("全局本地化")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a1bcb304f805c35486011f12a5e86c4ac7217d27")]
[assembly: AssemblyProduct("全局本地化")]
[assembly: AssemblyTitle("全局本地化")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
public class MonsterPrefabFinder
{
public static GameObject FindMonsterPrefabByName(string monsterName)
{
if ((Object)(object)ZNetScene.instance == (Object)null)
{
return null;
}
int stableHashCode = StringExtensionMethods.GetStableHashCode(monsterName);
return ZNetScene.instance.GetPrefab(stableHashCode);
}
public static GameObject FindMonsterPrefabByHash(int monsterHash)
{
if ((Object)(object)ZNetScene.instance == (Object)null)
{
return null;
}
return ZNetScene.instance.GetPrefab(monsterHash);
}
public static List<GameObject> GetAllMonsterPrefabs()
{
List<GameObject> list = new List<GameObject>();
if ((Object)(object)ZNetScene.instance == (Object)null)
{
return list;
}
List<string> prefabNames = ZNetScene.instance.GetPrefabNames();
foreach (string item in prefabNames)
{
GameObject prefab = ZNetScene.instance.GetPrefab(item);
if ((Object)(object)prefab != (Object)null)
{
Humanoid component = prefab.GetComponent<Humanoid>();
MonsterAI component2 = prefab.GetComponent<MonsterAI>();
Character component3 = prefab.GetComponent<Character>();
if (((Object)(object)component != (Object)null && !Object.op_Implicit((Object)(object)prefab.GetComponent<Player>())) || (Object)(object)component2 != (Object)null || ((Object)(object)component3 != (Object)null && !component3.IsPlayer()))
{
list.Add(prefab);
}
}
}
return list;
}
}
namespace ValMod.Localization.DeepSeekApi
{
internal class DeepSeekTranslator
{
private static DeepSeekTranslator _instance;
private static readonly object _lock = new object();
private const string ApiEndpoint = "https://api.deepseek.com/chat/completions";
private const int TimeoutSeconds = 30;
private string _apiKey;
private readonly HttpClient _httpClient;
private readonly CancellationTokenSource _globalCts;
public static DeepSeekTranslator Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
{
_instance = new DeepSeekTranslator();
}
}
}
return _instance;
}
}
private DeepSeekTranslator()
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_httpClient.Timeout = TimeSpan.FromSeconds(30.0);
_globalCts = new CancellationTokenSource();
}
public void SetApiKey(string apiKey)
{
_apiKey = apiKey;
}
public async Task<string> TranslateAsync(string text, string targetLanguage, string context = null)
{
if (string.IsNullOrEmpty(_apiKey))
{
throw new InvalidOperationException("API密钥未设置");
}
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(new CancellationToken[1] { _globalCts.Token });
cts.CancelAfter(TimeSpan.FromSeconds(30.0));
try
{
string prompt = BuildPrompt(text, targetLanguage, context);
string systemMessage = BuildSystemMessage(context);
var requestBody = new
{
model = "deepseek-chat",
messages = new[]
{
new
{
role = "system",
content = systemMessage
},
new
{
role = "user",
content = prompt
}
},
stream = false,
temperature = 0.7
};
string jsonContent = JsonConvert.SerializeObject((object)requestBody);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://api.deepseek.com/chat/completions")
{
Content = (HttpContent)new StringContent(jsonContent, Encoding.UTF8, "application/json")
};
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey);
HttpResponseMessage response = await ((HttpMessageInvoker)_httpClient).SendAsync(request, cts.Token);
response.EnsureSuccessStatusCode();
return CleanTranslationResult(JsonConvert.DeserializeObject<DeepSeekResponse>(await response.Content.ReadAsStringAsync())?.choices?[0]?.message?.content) ?? text;
}
catch (TaskCanceledException)
{
throw new Exception("翻译请求超时");
}
catch (HttpRequestException val)
{
HttpRequestException val2 = val;
HttpRequestException ex2 = val2;
throw new Exception("HTTP请求失败: " + ((Exception)(object)ex2).Message, (Exception?)(object)ex2);
}
catch (Exception ex4)
{
Exception ex = ex4;
throw new Exception("翻译服务出错: " + ex.Message, ex);
}
}
private string BuildPrompt(string text, string targetLanguage, string context)
{
if (context != null && context.StartsWith("$"))
{
string text2 = text ?? "该物品";
return "为" + text2 + "设计一个简单的" + targetLanguage + "描述,要求简洁明了,符合维京游戏风格,直接返回描述内容不要其他文字";
}
return "请将以下游戏文本翻译成" + targetLanguage + ",保持专业准确,直接返回翻译结果:\n" + text;
}
private string BuildSystemMessage(string context)
{
return (context != null && context.StartsWith("$")) ? "你是一个游戏物品描述设计师,创作符合维京风格的描述。" : "你是一个专业的翻译助手,请准确翻译用户提供的文本。";
}
private string CleanTranslationResult(string result)
{
return result?.Trim('"', '\'', '“', '”', '。', ' ') ?? string.Empty;
}
public void CancelAllOperations()
{
_globalCts.Cancel();
}
public void Dispose()
{
_globalCts?.Cancel();
HttpClient httpClient = _httpClient;
if (httpClient != null)
{
((HttpMessageInvoker)httpClient).Dispose();
}
_globalCts?.Dispose();
}
}
internal class DeepSeekResponse
{
public List<DeepSeekChoice> choices { get; set; }
}
internal class DeepSeekChoice
{
public int index { get; set; }
public DeepSeekMessage message { get; set; }
public object logprobs { get; set; }
public string finish_reason { get; set; }
}
internal class DeepSeekMessage
{
public string role { get; set; }
public string content { get; set; }
}
}
namespace local
{
public class 翻译工具
{
public static Dictionary<string, EffectInfoData> 效果字典 = new Dictionary<string, EffectInfoData>();
public static Dictionary<string, iteminfodata> 物品字典 = new Dictionary<string, iteminfodata>();
public static Dictionary<string, monsterinfodata> 怪物字典 = new Dictionary<string, monsterinfodata>();
public static Dictionary<string, pieceInfoData> 工具字典 = new Dictionary<string, pieceInfoData>();
}
public class 缓存
{
public static Dictionary<string, GameObject> m_PrefabCache = new Dictionary<string, GameObject>();
public static Dictionary<int, GameObject> m_PrefabHashCache = new Dictionary<int, GameObject>();
public static Dictionary<string, string> monsterNameCache = new Dictionary<string, string>();
public static Dictionary<string, (string name, string desc)> pieceCache = new Dictionary<string, (string, string)>();
public static Dictionary<string, (string name, string desc)> statusEffectCache = new Dictionary<string, (string, string)>();
public static Dictionary<string, (string name, string desc, int hash)> itemTranslationCache = new Dictionary<string, (string, string, int)>();
}
}
namespace ValModLocalization.Data
{
public class 存放
{
public string 预制名 { get; set; } = string.Empty;
public string 名 { get; set; } = string.Empty;
public string 描述 { get; set; } = string.Empty;
public string 哈希 { get; set; } = string.Empty;
}
}
namespace 全局本地化
{
public static class TranslationProcessor
{
[Serializable]
private class SerializableDictionary
{
public List<string> keys = new List<string>();
public List<int> values = new List<int>();
public SerializableDictionary()
{
}
public SerializableDictionary(Dictionary<string, int> dict)
{
foreach (KeyValuePair<string, int> item in dict)
{
keys.Add(item.Key);
values.Add(item.Value);
}
}
public Dictionary<string, int> ToDictionary()
{
Dictionary<string, int> dictionary = new Dictionary<string, int>();
for (int i = 0; i < keys.Count && i < values.Count; i++)
{
dictionary[keys[i]] = values[i];
}
return dictionary;
}
}
public class TranslationTimer : IDisposable
{
private string _operationName;
private Stopwatch _stopwatch;
public TranslationTimer(string operationName)
{
_operationName = operationName;
_stopwatch = Stopwatch.StartNew();
}
public void Dispose()
{
_stopwatch.Stop();
Debug.Log((object)$"[TIMER] {_operationName} - 耗时: {_stopwatch.Elapsed.TotalSeconds:F2}秒");
}
}
private static Dictionary<string, int> translationStats = new Dictionary<string, int>();
private static Dictionary<string, int> progressTracker = new Dictionary<string, int>();
private static 存放 存 => 全局本地化.存;
public static string AiLocalizationFolder { get; set; }
public static int TranslationDelay { get; set; } = 50;
public static string ProgressFile => Path.Combine(AiLocalizationFolder, "translation_progress.txt");
public static async void ProcessAllTranslations()
{
try
{
if (string.IsNullOrEmpty(AiLocalizationFolder))
{
Debug.LogError((object)"翻译文件夹路径未设置!");
return;
}
if (!Directory.Exists(AiLocalizationFolder))
{
Debug.LogError((object)("翻译文件夹不存在: " + AiLocalizationFolder));
return;
}
Debug.Log((object)"开始批量翻译处理...");
LoadProgress();
translationStats.Clear();
string[] allFiles = (from f in Directory.GetFiles(AiLocalizationFolder, "*", SearchOption.AllDirectories)
where Path.GetExtension(f) == ".txt" && !Path.GetFileName(f).Contains("_translated")
select f).ToArray();
Debug.Log((object)$"找到 {allFiles.Length} 个待翻译文件");
string[] array = allFiles;
foreach (string filePath in array)
{
await ProcessSingleFile(filePath);
}
ClearProgress();
LogTranslationStats();
Debug.Log((object)"批量翻译处理完成!");
}
catch (Exception ex2)
{
Exception ex = ex2;
Debug.LogError((object)("批量翻译处理失败: " + ex.Message));
SaveProgress();
}
}
private static async Task ProcessSingleFile(string filePath)
{
try
{
string fileName = Path.GetFileNameWithoutExtension(filePath);
string translatedFilePath = GetTranslatedFilePath(filePath);
if (File.Exists(translatedFilePath))
{
string fileKey = Path.GetFileName(filePath);
if (!progressTracker.ContainsKey(fileKey) || progressTracker[fileKey] <= 0)
{
Debug.Log((object)("已翻译文件存在,跳过: " + fileName));
return;
}
Debug.Log((object)$"继续翻译文件: {fileName} (进度: {progressTracker[fileKey]})");
}
Debug.Log((object)("处理文件: " + fileName));
if (fileName.StartsWith("汉化信息_怪物"))
{
await ProcessMonsterTranslations(filePath);
}
else if (fileName.StartsWith("汉化信息_工具"))
{
await ProcessPieceTranslations(filePath);
}
else if (fileName.StartsWith("汉化信息_效果"))
{
await ProcessStatusEffectsTranslations(filePath);
}
else if (fileName.StartsWith("汉化信息_物品"))
{
await ProcessItemTranslations(filePath);
}
else
{
Debug.LogWarning((object)("未知文件类型,跳过: " + fileName));
}
}
catch (Exception ex2)
{
Exception ex = ex2;
Debug.LogError((object)("处理文件失败 " + filePath + ": " + ex.Message));
SaveProgress();
}
}
private static async Task ProcessItemTranslations(string filePath)
{
if (!File.Exists(filePath))
{
Debug.LogError((object)("文件不存在: " + filePath));
return;
}
string[] lines = File.ReadAllLines(filePath, Encoding.UTF8);
List<string> translatedLines = LoadPartialTranslation(filePath);
int translatedCount = 0;
string fileKey = Path.GetFileName(filePath);
int startIndex = (progressTracker.ContainsKey(fileKey) ? progressTracker[fileKey] : 0);
if (translatedLines.Count > 0)
{
Debug.Log((object)$"从临时文件继续翻译 {fileKey},已有 {translatedLines.Count} 行");
startIndex = Math.Max(startIndex, translatedLines.Count);
}
else
{
translatedLines = new List<string>();
for (int j = 0; j < Math.Min(startIndex, lines.Length); j++)
{
translatedLines.Add(lines[j]);
}
}
Debug.Log((object)$"开始处理文件 {fileKey},从第 {startIndex} 行开始,总行数: {lines.Length}");
for (int i = startIndex; i < lines.Length; i++)
{
try
{
string line = lines[i];
if (i < translatedLines.Count)
{
continue;
}
translatedLines.Add(line);
if (line.StartsWith(存.预制名) && i + 2 < lines.Length)
{
string prefabNameLine = line;
string nameLine = lines[i + 1];
string descLine = lines[i + 2];
string originalName = nameLine.Substring(存.名.Length).Trim();
string originalDesc = descLine.Substring(存.描述.Length).Trim();
if (!ContainsChinese(originalName) || !ContainsChinese(originalDesc))
{
using (new TranslationTimer("翻译物品 " + originalName))
{
var (translatedName, translatedDesc) = await TranslateWithRetry(originalName, originalDesc, "物品");
translatedLines[translatedLines.Count - 1] = prefabNameLine;
translatedLines.Add(存.名 + translatedName);
translatedLines.Add(存.描述 + translatedDesc);
translatedCount += 2;
i += 2;
}
}
else
{
translatedLines.Add(nameLine);
translatedLines.Add(descLine);
i += 2;
}
if (i + 1 < lines.Length && lines[i + 1].StartsWith(存.哈希))
{
translatedLines.Add(lines[i + 1]);
i++;
}
}
progressTracker[fileKey] = i + 1;
if (translatedCount > 0 && translatedCount % 10 == 0)
{
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
Debug.Log((object)$"已保存进度: {fileKey} - 第 {i + 1}/{lines.Length} 行");
}
}
catch (Exception ex)
{
Debug.LogError((object)$"处理第 {i} 行时出错: {ex.Message}");
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
throw;
}
}
string outputPath = GetTranslatedFilePath(filePath);
File.WriteAllLines(outputPath, translatedLines, Encoding.UTF8);
CleanTempFile(filePath);
translationStats["物品"] = translatedCount / 2;
Debug.Log((object)$"物品翻译完成: {translatedCount / 2} 个物品已翻译");
}
private static async Task ProcessMonsterTranslations(string filePath)
{
if (!File.Exists(filePath))
{
Debug.LogError((object)("文件不存在: " + filePath));
return;
}
string[] lines = File.ReadAllLines(filePath, Encoding.UTF8);
List<string> translatedLines = LoadPartialTranslation(filePath);
int translatedCount = 0;
string fileKey = Path.GetFileName(filePath);
int startIndex = (progressTracker.ContainsKey(fileKey) ? progressTracker[fileKey] : 0);
if (translatedLines.Count > 0)
{
startIndex = Math.Max(startIndex, translatedLines.Count);
}
else
{
translatedLines = new List<string>();
for (int j = 0; j < Math.Min(startIndex, lines.Length); j++)
{
translatedLines.Add(lines[j]);
}
}
Debug.Log((object)$"开始处理怪物文件 {fileKey},从第 {startIndex} 行开始");
for (int i = startIndex; i < lines.Length; i++)
{
try
{
string line = lines[i];
if (i < translatedLines.Count)
{
continue;
}
translatedLines.Add(line);
if (line.StartsWith(存.预制名) && i + 1 < lines.Length)
{
string prefabNameLine = line;
string nameLine = lines[i + 1];
string originalName = nameLine.Substring(存.名.Length).Trim();
if (!ContainsChinese(originalName))
{
using (new TranslationTimer("翻译怪物 " + originalName))
{
string translatedName = await TranslateWithRetry(originalName, "怪物");
translatedLines[translatedLines.Count - 1] = prefabNameLine;
translatedLines.Add(存.名 + translatedName);
translatedCount++;
i++;
}
}
else
{
translatedLines.Add(nameLine);
i++;
}
}
progressTracker[fileKey] = i + 1;
if (translatedCount > 0 && translatedCount % 10 == 0)
{
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
}
}
catch (Exception ex)
{
Debug.LogError((object)$"处理第 {i} 行时出错: {ex.Message}");
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
throw;
}
}
string outputPath = GetTranslatedFilePath(filePath);
File.WriteAllLines(outputPath, translatedLines, Encoding.UTF8);
CleanTempFile(filePath);
translationStats["怪物"] = translatedCount;
Debug.Log((object)$"怪物翻译完成: {translatedCount} 个怪物已翻译");
}
private static async Task ProcessPieceTranslations(string filePath)
{
if (!File.Exists(filePath))
{
Debug.LogError((object)("文件不存在: " + filePath));
return;
}
string[] lines = File.ReadAllLines(filePath, Encoding.UTF8);
List<string> translatedLines = LoadPartialTranslation(filePath);
int translatedCount = 0;
string fileKey = Path.GetFileName(filePath);
int startIndex = (progressTracker.ContainsKey(fileKey) ? progressTracker[fileKey] : 0);
if (translatedLines.Count > 0)
{
startIndex = Math.Max(startIndex, translatedLines.Count);
}
else
{
translatedLines = new List<string>();
for (int j = 0; j < Math.Min(startIndex, lines.Length); j++)
{
translatedLines.Add(lines[j]);
}
}
Debug.Log((object)$"开始处理工具文件 {fileKey},从第 {startIndex} 行开始");
for (int i = startIndex; i < lines.Length; i++)
{
try
{
string line = lines[i];
if (i < translatedLines.Count)
{
continue;
}
translatedLines.Add(line);
if (line.StartsWith(存.预制名) && i + 2 < lines.Length)
{
string prefabNameLine = line;
string nameLine = lines[i + 1];
string descLine = lines[i + 2];
string originalName = nameLine.Substring(存.名.Length).Trim();
string originalDesc = descLine.Substring(存.描述.Length).Trim();
if (!ContainsChinese(originalName) || !ContainsChinese(originalDesc))
{
using (new TranslationTimer("翻译工具 " + originalName))
{
var (translatedName, translatedDesc) = await TranslateWithRetry(originalName, originalDesc, "建造项目");
translatedLines[translatedLines.Count - 1] = prefabNameLine;
translatedLines.Add(存.名 + translatedName);
translatedLines.Add(存.描述 + translatedDesc);
translatedCount += 2;
i += 2;
}
}
else
{
translatedLines.Add(nameLine);
translatedLines.Add(descLine);
i += 2;
}
}
progressTracker[fileKey] = i + 1;
if (translatedCount > 0 && translatedCount % 10 == 0)
{
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
}
}
catch (Exception ex)
{
Debug.LogError((object)$"处理第 {i} 行时出错: {ex.Message}");
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
throw;
}
}
string outputPath = GetTranslatedFilePath(filePath);
File.WriteAllLines(outputPath, translatedLines, Encoding.UTF8);
CleanTempFile(filePath);
translationStats["工具"] = translatedCount / 2;
Debug.Log((object)$"工具翻译完成: {translatedCount / 2} 个工具已翻译");
}
private static async Task ProcessStatusEffectsTranslations(string filePath)
{
if (!File.Exists(filePath))
{
Debug.LogError((object)("文件不存在: " + filePath));
return;
}
string[] lines = File.ReadAllLines(filePath, Encoding.UTF8);
List<string> translatedLines = LoadPartialTranslation(filePath);
int translatedCount = 0;
string fileKey = Path.GetFileName(filePath);
int startIndex = (progressTracker.ContainsKey(fileKey) ? progressTracker[fileKey] : 0);
if (translatedLines.Count > 0)
{
startIndex = Math.Max(startIndex, translatedLines.Count);
}
else
{
translatedLines = new List<string>();
for (int j = 0; j < Math.Min(startIndex, lines.Length); j++)
{
translatedLines.Add(lines[j]);
}
}
Debug.Log((object)$"开始处理状态效果文件 {fileKey},从第 {startIndex} 行开始");
for (int i = startIndex; i < lines.Length; i++)
{
try
{
string line = lines[i];
if (i < translatedLines.Count)
{
continue;
}
translatedLines.Add(line);
if (line.StartsWith(存.预制名) && i + 2 < lines.Length)
{
string prefabNameLine = line;
string nameLine = lines[i + 1];
string descLine = lines[i + 2];
string originalName = nameLine.Substring(存.名.Length).Trim();
string originalDesc = descLine.Substring(存.描述.Length).Trim();
if (!ContainsChinese(originalName) || !ContainsChinese(originalDesc))
{
using (new TranslationTimer("翻译状态效果 " + originalName))
{
var (translatedName, translatedDesc) = await TranslateWithRetry(originalName, originalDesc, "角色状态效果");
translatedLines[translatedLines.Count - 1] = prefabNameLine;
translatedLines.Add(存.名 + translatedName);
translatedLines.Add(存.描述 + translatedDesc);
translatedCount += 2;
i += 2;
}
}
else
{
translatedLines.Add(nameLine);
translatedLines.Add(descLine);
i += 2;
}
}
progressTracker[fileKey] = i + 1;
if (translatedCount > 0 && translatedCount % 10 == 0)
{
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
}
}
catch (Exception ex)
{
Debug.LogError((object)$"处理第 {i} 行时出错: {ex.Message}");
SaveProgress();
SavePartialTranslation(filePath, translatedLines);
throw;
}
}
string outputPath = GetTranslatedFilePath(filePath);
File.WriteAllLines(outputPath, translatedLines, Encoding.UTF8);
CleanTempFile(filePath);
translationStats["状态效果"] = translatedCount / 2;
Debug.Log((object)$"状态效果翻译完成: {translatedCount / 2} 个效果已翻译");
}
private static async Task<string> TranslateWithRetry(string text, string fileType, int maxRetries = 3)
{
for (int retry = 0; retry < maxRetries; retry++)
{
try
{
return await TranslateText(text);
}
catch (Exception ex) when (retry < maxRetries - 1)
{
Debug.LogWarning((object)$"翻译重试 {retry + 1}/{maxRetries}: {ex.Message}");
await Task.Delay(1000 * (retry + 1));
}
}
Debug.LogError((object)("翻译失败,返回原始文本: " + text));
return text;
}
private static async Task<(string name, string desc)> TranslateWithRetry(string originalName, string originalDesc, string fileType, int maxRetries = 3)
{
for (int retry = 0; retry < maxRetries; retry++)
{
try
{
return await TranslateWithIntelligence(originalName, originalDesc, fileType);
}
catch (Exception ex) when (retry < maxRetries - 1)
{
Debug.LogWarning((object)$"翻译重试 {retry + 1}/{maxRetries}: {ex.Message}");
await Task.Delay(1000 * (retry + 1));
}
}
Debug.LogError((object)("翻译失败,返回原始文本: " + originalName));
return (originalName, originalDesc);
}
private static async Task<(string name, string desc)> TranslateWithIntelligence(string originalName, string originalDesc, string fileType)
{
try
{
string translatedName = await DeepSeekTranslator.Instance.TranslateAsync(originalName, 全局本地化.TARGET_LANGUAGE.Value);
string translatedDesc = (string.IsNullOrEmpty(originalDesc) ? (await DeepSeekTranslator.Instance.TranslateAsync(translatedName, 全局本地化.TARGET_LANGUAGE.Value, "$design_description")) : ((!originalDesc.StartsWith("$")) ? (await DeepSeekTranslator.Instance.TranslateAsync(originalDesc, 全局本地化.TARGET_LANGUAGE.Value)) : (await DeepSeekTranslator.Instance.TranslateAsync(translatedName, 全局本地化.TARGET_LANGUAGE.Value, originalDesc))));
if (string.IsNullOrEmpty(translatedDesc))
{
translatedDesc = translatedName + "的装备";
}
await Task.Delay(TranslationDelay);
return (translatedName, translatedDesc);
}
catch (Exception ex2)
{
Exception ex = ex2;
Debug.LogError((object)("智能翻译失败: " + ex.Message));
return (originalName, originalDesc);
}
}
private static void SavePartialTranslation(string originalPath, List<string> translatedLines)
{
try
{
string path = GetTranslatedFilePath(originalPath) + ".temp";
File.WriteAllLines(path, translatedLines, Encoding.UTF8);
}
catch (Exception ex)
{
Debug.LogWarning((object)("保存临时文件失败: " + ex.Message));
}
}
private static List<string> LoadPartialTranslation(string originalPath)
{
try
{
string path = GetTranslatedFilePath(originalPath) + ".temp";
if (File.Exists(path))
{
List<string> list = File.ReadAllLines(path, Encoding.UTF8).ToList();
Debug.Log((object)$"加载临时翻译文件: {Path.GetFileName(originalPath)},共 {list.Count} 行");
return list;
}
}
catch (Exception ex)
{
Debug.LogWarning((object)("加载临时文件失败: " + ex.Message));
}
return new List<string>();
}
private static void CleanTempFile(string originalPath)
{
try
{
string path = GetTranslatedFilePath(originalPath) + ".temp";
if (File.Exists(path))
{
File.Delete(path);
Debug.Log((object)("清理临时文件: " + Path.GetFileName(path)));
}
}
catch (Exception ex)
{
Debug.LogWarning((object)("清理临时文件失败: " + ex.Message));
}
}
private static void LoadProgress()
{
try
{
if (File.Exists(ProgressFile))
{
string text = File.ReadAllText(ProgressFile);
progressTracker = JsonUtility.FromJson<SerializableDictionary>(text)?.ToDictionary() ?? new Dictionary<string, int>();
Debug.Log((object)$"加载翻译进度,共 {progressTracker.Count} 个文件的进度");
}
}
catch (Exception ex)
{
Debug.LogWarning((object)("加载进度文件失败: " + ex.Message));
progressTracker = new Dictionary<string, int>();
}
}
private static void SaveProgress()
{
try
{
SerializableDictionary serializableDictionary = new SerializableDictionary(progressTracker);
string contents = JsonUtility.ToJson((object)serializableDictionary);
File.WriteAllText(ProgressFile, contents);
}
catch (Exception ex)
{
Debug.LogWarning((object)("保存进度文件失败: " + ex.Message));
}
}
private static void ClearProgress()
{
try
{
if (File.Exists(ProgressFile))
{
File.Delete(ProgressFile);
Debug.Log((object)"清理进度文件");
}
string[] files = Directory.GetFiles(AiLocalizationFolder, "*.temp", SearchOption.AllDirectories);
foreach (string text in files)
{
try
{
File.Delete(text);
}
catch (Exception ex)
{
Debug.LogWarning((object)("清理临时文件失败 " + text + ": " + ex.Message));
}
}
progressTracker.Clear();
}
catch (Exception ex2)
{
Debug.LogWarning((object)("清理进度文件失败: " + ex2.Message));
}
}
private static async Task<string> TranslateText(string text)
{
if (string.IsNullOrEmpty(text))
{
return text;
}
try
{
string translatedText = await DeepSeekTranslator.Instance.TranslateAsync(text, 全局本地化.TARGET_LANGUAGE.Value);
await Task.Delay(TranslationDelay);
return translatedText ?? text;
}
catch (Exception ex)
{
Debug.LogError((object)("翻译文本失败 '" + text + "': " + ex.Message));
return text;
}
}
private static string GetTranslatedFilePath(string originalPath)
{
string directoryName = Path.GetDirectoryName(originalPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(originalPath);
string extension = Path.GetExtension(originalPath);
return Path.Combine(directoryName, fileNameWithoutExtension + "_translated" + extension);
}
private static bool ContainsChinese(string text)
{
return !string.IsNullOrEmpty(text) && text.Any((char c) => c >= '一' && c <= '\u9fff');
}
private static void LogTranslationStats()
{
Debug.Log((object)"=== 翻译统计 ===");
foreach (KeyValuePair<string, int> translationStat in translationStats)
{
Debug.Log((object)$"{translationStat.Key}: {translationStat.Value} 个条目已翻译");
}
Debug.Log((object)"=================");
}
public static async void TestSingleFileTranslation(string fileName = "汉化信息_物品.txt")
{
try
{
string testFile = Path.Combine(AiLocalizationFolder, fileName);
if (File.Exists(testFile))
{
Debug.Log((object)("开始测试翻译文件: " + fileName));
await ProcessSingleFile(testFile);
}
else
{
Debug.LogError((object)("测试文件不存在: " + testFile));
}
}
catch (Exception ex2)
{
Exception ex = ex2;
Debug.LogError((object)("测试翻译失败: " + ex.Message));
}
}
public static async void ResumeTranslation()
{
Debug.Log((object)"恢复上次的翻译进度...");
LoadProgress();
ProcessAllTranslations();
}
public static void ResetProgress()
{
ClearProgress();
Debug.Log((object)"翻译进度已重置");
}
public static string GetProgressInfo()
{
if (progressTracker.Count == 0)
{
return "暂无翻译进度";
}
string text = "当前翻译进度:\n";
foreach (KeyValuePair<string, int> item in progressTracker)
{
text += $"{item.Key}: 第 {item.Value} 行\n";
}
return text;
}
public static bool HasProgress()
{
return progressTracker.Count > 0;
}
public static void ShowProgress()
{
string progressInfo = GetProgressInfo();
Debug.Log((object)progressInfo);
}
}
[BepInPlugin("lanlng_locailization", "懒濑的本地化", "1.6")]
public class 全局本地化 : BaseUnityPlugin
{
[HarmonyPatch(typeof(ObjectDB), "Awake")]
[HarmonyPriority(800)]
private class ObjectDBInitializationPatch
{
private static void Postfix(ObjectDB __instance)
{
InitializeAllData(__instance);
Debug.Log((object)"懒濑:初始化成功!");
if (finish2.Value)
{
ApplyAllTranslations(__instance);
}
}
}
internal const string mod_GUID = "lanlng_locailization";
internal const string mod_NAME = "懒濑的本地化";
internal const string mod_VERSION = "1.6";
internal readonly Harmony harmony = new Harmony("lanlng_locailization");
public static 存放 存 = new 存放();
internal static string[] searchFields = Array.Empty<string>();
internal static List<iteminfodata> 物品汉化结果 = new List<iteminfodata>();
internal static List<EffectInfoData> 效果汉化结果 = new List<EffectInfoData>();
internal static List<monsterinfodata> 怪物汉化结果 = new List<monsterinfodata>();
internal static int num1 = 0;
internal static int num2 = 0;
internal static int num3 = 0;
internal static int num4 = 0;
internal static string configFolder = "BepInEx/config";
internal static string modLocalizationFolder = Path.Combine(configFolder, "mod汉化");
internal static string savePath = Path.Combine(Application.dataPath, "../" + modLocalizationFolder + "/汉化信息_物品.txt");
internal static string monstersavePath = Path.Combine(Application.dataPath, "../" + modLocalizationFolder + "/汉化信息_怪物.txt");
internal static string effectsavePath = Path.Combine(Application.dataPath, "../" + modLocalizationFolder + "/汉化信息_效果.txt");
internal static string piecesavePath = Path.Combine(Application.dataPath, "../" + modLocalizationFolder + "/汉化信息_工具.txt");
internal static string modSearchSavePath = Path.Combine(Application.dataPath, "../" + modLocalizationFolder + "/汉化信息_Mod名称.txt");
private static ConfigEntry<string> apiKey;
private static ConfigEntry<bool> finish;
private static ConfigEntry<bool> finish2;
private static ConfigEntry<KeyboardShortcut> Shortcut;
private static ConfigEntry<KeyboardShortcut> modShortcut;
private static ConfigEntry<KeyboardShortcut> TranslateShortcut;
private static ConfigEntry<KeyboardShortcut> textup;
public static ConfigEntry<string> TARGET_LANGUAGE;
public static string[] ItemSearchFields;
public static string[] EffectSearchFields;
public static string[] MonsterSearchFields;
public static string[] PieceSearchFields;
private static bool isInitialized = false;
private const string FilterConfigFileName = "筛选条件.txt";
internal static string modNameConfigPath => Path.Combine(Application.dataPath, "../" + modLocalizationFolder + "/筛选条件_Mod名称.txt");
public void Awake()
{
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
apiKey = ((BaseUnityPlugin)this).Config.Bind<string>("General通用", "APIKey", "sk-eb0f2f33abc548219d36d05b39e23177", "你的API密钥");
TARGET_LANGUAGE = ((BaseUnityPlugin)this).Config.Bind<string>("General通用", "ai翻译的目标语言如Japanese,Korean,Spanish,French,German,Russian,Italian,Portuguese,Dutch等", "中文", "你想要翻译成什么语言");
finish = ((BaseUnityPlugin)this).Config.Bind<bool>("General通用", "是否开启文本收集", true, "是否开启文本收集");
finish2 = ((BaseUnityPlugin)this).Config.Bind<bool>("General通用", "是否应用文本翻译", true, "是否应用文本翻译");
TranslateShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys快捷键", "api翻译导出快捷键", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "api翻译快捷键");
Shortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys快捷键", "筛选条件导出快捷键", new KeyboardShortcut((KeyCode)293, Array.Empty<KeyCode>()), "筛选条件导出快捷键");
modShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys快捷键", "mod筛选导出快捷键", new KeyboardShortcut((KeyCode)292, Array.Empty<KeyCode>()), "mod筛选导出快捷键");
textup = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys快捷键", "更新翻译", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "mod筛选导出快捷键");
((BaseUnityPlugin)this).Logger.LogInfo((object)"初始化 插件 lanlng_locailization ");
Directory.CreateDirectory(Path.Combine(Application.dataPath, "../" + modLocalizationFolder));
TranslationProcessor.AiLocalizationFolder = Path.Combine(modLocalizationFolder, "ai翻译");
Directory.CreateDirectory(Path.Combine(Application.dataPath, "../" + TranslationProcessor.AiLocalizationFolder));
DeepSeekTranslator instance = DeepSeekTranslator.Instance;
instance.SetApiKey(apiKey.Value);
存.预制名 = "预制名:";
存.名 = "名字:";
存.描述 = "描述:";
存.哈希 = "哈希:";
harmony.PatchAll();
EnsureFilterFile("筛选条件.txt", new Dictionary<string, string[]>
{
{
"物品",
new string[2] { "_Ygg", "_Custom" }
},
{
"效果",
new string[1] { "SE_" }
},
{
"怪物",
new string[2] { "RRR", "Custom" }
},
{
"工具",
new string[2] { "_piece", "_Piece" }
}
});
EnsureFilterFile("筛选条件_Mod名称.txt", new Dictionary<string, string[]> {
{
"Mod名称",
new string[3] { "CustomMod", "Extended", "Additional" }
} });
}
private void EnsureFilterFile(string fileName, Dictionary<string, string[]> defaultSections)
{
try
{
string text = Path.Combine(Application.dataPath, "../" + modLocalizationFolder + "/" + fileName);
if (File.Exists(text))
{
return;
}
Directory.CreateDirectory(Path.GetDirectoryName(text));
List<string> list = new List<string>();
foreach (KeyValuePair<string, string[]> defaultSection in defaultSections)
{
list.Add("[" + defaultSection.Key + "]//filter condition for “" + defaultSection.Key + "”");
list.AddRange(defaultSection.Value);
list.Add("");
}
File.WriteAllLines(text, list, Encoding.UTF8);
((BaseUnityPlugin)this).Logger.LogInfo((object)("懒濑:已创建默认筛选文件 " + text));
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("懒濑:创建筛选文件 " + fileName + " 失败: " + ex.Message));
}
}
public static void InitializeAllData(ObjectDB instance)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (isInitialized || (Object)(object)instance == (Object)null)
{
return;
}
Scene activeScene = SceneManager.GetActiveScene();
if (!(((Scene)(ref activeScene)).name != "main"))
{
LoadAllSearchFields();
if (finish.Value)
{
CollectAllItems(instance);
CollectAllEffects(instance);
CollectAllMonsters();
CollectAllPieces();
Debug.Log((object)"懒濑:完整数据收集完成");
}
ModPrefabManager.InitializeModInfo();
isInitialized = true;
}
}
public static void ExportFilteredData()
{
try
{
LoadAllSearchFields();
ExportFilteredItems();
ExportFilteredEffects();
ExportFilteredMonsters();
ExportFilteredPieces();
Debug.Log((object)"懒濑:筛选数据导出完成");
}
catch (Exception ex)
{
Debug.LogError((object)("懒濑:导出数据时出错: " + ex.Message));
}
}
private static void CollectAllItems(ObjectDB instance)
{
foreach (KeyValuePair<int, GameObject> item in instance.m_itemByHash)
{
if ((Object)(object)item.Value == (Object)null)
{
continue;
}
ItemDrop component = item.Value.GetComponent<ItemDrop>();
if (!((Object)(object)component == (Object)null))
{
iteminfodata value = new iteminfodata
{
itemname = GetLocalizedText(component.m_itemData.m_shared.m_name),
itemdesc = GetLocalizedText(component.m_itemData.m_shared.m_description),
itemHash = item.Key
};
if (!翻译工具.物品字典.ContainsKey(((Object)item.Value).name))
{
翻译工具.物品字典.Add(((Object)item.Value).name, value);
}
}
}
Debug.Log((object)$"懒濑:收集到 {翻译工具.物品字典.Count} 个物品");
}
private static void CollectAllEffects(ObjectDB instance)
{
foreach (StatusEffect statusEffect in instance.m_StatusEffects)
{
if (!((Object)(object)statusEffect == (Object)null) && !翻译工具.效果字典.ContainsKey(((Object)statusEffect).name))
{
EffectInfoData value = new EffectInfoData
{
effectprename = ((Object)statusEffect).name,
effectname = GetLocalizedText(statusEffect.m_name),
effectdesc = GetLocalizedText(statusEffect.m_tooltip),
effecthash = statusEffect.m_nameHash
};
if (!翻译工具.效果字典.ContainsKey(((Object)statusEffect).name))
{
翻译工具.效果字典.Add(((Object)statusEffect).name, value);
}
}
}
Debug.Log((object)$"懒濑:收集到 {翻译工具.效果字典.Count} 个效果");
}
private static void CollectAllMonsters()
{
Humanoid[] array = Resources.FindObjectsOfTypeAll<Humanoid>();
Humanoid[] array2 = array;
foreach (Humanoid val in array2)
{
monsterinfodata value = new monsterinfodata
{
monsterprename = ((Object)val).name,
monstername = GetLocalizedText(((Character)((Component)val).GetComponent<Humanoid>()).m_name),
monsterhash = ((object)val).GetHashCode()
};
if (!翻译工具.怪物字典.ContainsKey(((Object)val).name))
{
翻译工具.怪物字典.Add(((Object)val).name, value);
}
}
Debug.Log((object)$"懒濑:收集到 {翻译工具.怪物字典.Count} 个怪物");
}
private static void CollectAllPieces()
{
Piece[] array = Resources.FindObjectsOfTypeAll<Piece>();
Piece[] array2 = array;
foreach (Piece val in array2)
{
if (!((Object)(object)val == (Object)null) && !翻译工具.工具字典.ContainsKey(((Object)val).name))
{
pieceInfoData value = new pieceInfoData
{
pieceprename = ((Object)val).name,
piecename = GetLocalizedText(val.m_name),
piecedesc = GetLocalizedText(val.m_description),
piecehash = ((object)val).GetHashCode()
};
if (!翻译工具.工具字典.ContainsKey(((Object)val).name))
{
翻译工具.工具字典.Add(((Object)val).name, value);
}
}
}
Debug.Log((object)$"懒濑:收集到 {翻译工具.工具字典.Count} 个工具");
}
private static string GetLocalizedText(string text)
{
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
try
{
if (Localization.instance == null)
{
return text;
}
string text2 = Localization.instance.Localize(text);
if (!string.IsNullOrEmpty(text2))
{
return text2;
}
return text;
}
catch (Exception ex)
{
Debug.LogWarning((object)("本地化文本失败: " + text + ", 错误: " + ex.Message));
return text;
}
}
private static void ExportFilteredItems()
{
Dictionary<string, iteminfodata> dictionary = FilterDictionary(翻译工具.物品字典, ItemSearchFields);
string filePath = Path.Combine(modLocalizationFolder, $"汉化信息_物品_{DateTime.Now:yyyyMMdd_HHmm}.txt");
SaveDictionaryToTxt(filePath, "物品", dictionary);
}
private static void ExportFilteredEffects()
{
Dictionary<string, EffectInfoData> dictionary = FilterDictionary(翻译工具.效果字典, EffectSearchFields);
string filePath = Path.Combine(modLocalizationFolder, $"汉化信息_效果_{DateTime.Now:yyyyMMdd_HHmm}.txt");
SaveDictionaryToTxt(filePath, "效果", dictionary);
}
private static void ExportFilteredMonsters()
{
Dictionary<string, monsterinfodata> dictionary = FilterDictionary(翻译工具.怪物字典, MonsterSearchFields);
string filePath = Path.Combine(modLocalizationFolder, $"汉化信息_怪物_{DateTime.Now:yyyyMMdd_HHmm}.txt");
SaveDictionaryToTxt(filePath, "怪物", dictionary);
}
private static void ExportFilteredPieces()
{
Dictionary<string, pieceInfoData> dictionary = FilterDictionary(翻译工具.工具字典, PieceSearchFields);
string filePath = Path.Combine(modLocalizationFolder, $"汉化信息_工具_{DateTime.Now:yyyyMMdd_HHmm}.txt");
SaveDictionaryToTxt(filePath, "工具", dictionary);
}
private static Dictionary<string, T> FilterDictionary<T>(Dictionary<string, T> source, string[] searchFields)
{
Dictionary<string, T> dictionary = new Dictionary<string, T>();
bool flag = searchFields == null || searchFields.Length == 0;
foreach (KeyValuePair<string, T> item in source)
{
if (flag)
{
dictionary.Add(item.Key, item.Value);
continue;
}
foreach (string value in searchFields)
{
if (item.Key.Contains(value))
{
dictionary.Add(item.Key, item.Value);
break;
}
}
}
return dictionary;
}
private static void LoadAllSearchFields()
{
Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>();
dictionary.Add("物品", new string[3] { "_Ygg", "_Custom", "//Filtering conditions for items(This bank's note can be deleted.)" });
dictionary.Add("效果", new string[2] { "SE_", "//Filtering conditions for effects(This bank's note can be deleted.)" });
dictionary.Add("怪物", new string[2] { "RRR", "//Filtering conditions for creature(This bank's note can be deleted.)" });
dictionary.Add("工具", new string[3] { "_piece", "_Piece", "//Filtering conditions for pieces(This bank's note can be deleted.)" });
Dictionary<string, string[]> defaultFilters = dictionary;
(string[], string[], string[], string[]) tuple = LoadAllFiltersFromFile(defaultFilters);
string[] item = tuple.Item1;
string[] item2 = tuple.Item2;
string[] item3 = tuple.Item3;
string[] item4 = tuple.Item4;
ItemSearchFields = item;
EffectSearchFields = item2;
MonsterSearchFields = item3;
PieceSearchFields = item4;
}
private static (string[], string[], string[], string[]) LoadAllFiltersFromFile(Dictionary<string, string[]> defaultFilters)
{
try
{
string path = Path.Combine(modLocalizationFolder, "筛选条件.txt");
Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>
{
{
"物品",
new List<string>()
},
{
"效果",
new List<string>()
},
{
"怪物",
new List<string>()
},
{
"工具",
new List<string>()
}
};
string text = null;
if (!File.Exists(path))
{
string directoryName = Path.GetDirectoryName(path);
if (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
List<string> list = new List<string>();
string[] array = new string[4] { "物品", "效果", "怪物", "工具" };
foreach (string text2 in array)
{
list.Add("[" + text2 + "]//filter condition");
if (defaultFilters.ContainsKey(text2) && defaultFilters[text2].Length != 0)
{
list.AddRange(defaultFilters[text2]);
}
list.Add("");
}
File.WriteAllLines(path, list);
Debug.Log((object)"懒濑:配置文件不存在,已创建默认配置文件");
return (defaultFilters["物品"], defaultFilters["效果"], defaultFilters["怪物"], defaultFilters["工具"]);
}
string[] array2 = File.ReadAllLines(path);
foreach (string text3 in array2)
{
string text4 = text3.Trim();
if (!string.IsNullOrWhiteSpace(text4))
{
if (text4.StartsWith("[") && text4.Contains("]"))
{
text = text4.Trim('[', ']').Trim();
}
else if (text != null && dictionary.ContainsKey(text))
{
dictionary[text].Add(text4);
}
}
}
return (dictionary["物品"].ToArray(), dictionary["效果"].ToArray(), dictionary["怪物"].ToArray(), dictionary["工具"].ToArray());
}
catch (Exception ex)
{
Debug.LogError((object)("懒濑:加载配置文件 筛选条件.txt 失败: " + ex.Message));
return (defaultFilters["物品"], defaultFilters["效果"], defaultFilters["怪物"], defaultFilters["工具"]);
}
}
private static void SaveDictionaryToTxt<T>(string filePath, string dictionaryType, Dictionary<string, T> dictionary)
{
try
{
using (StreamWriter streamWriter = new StreamWriter(filePath, append: false, Encoding.UTF8))
{
streamWriter.WriteLine(dictionaryType + "信息列表 - " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
streamWriter.WriteLine("使用说明Instructions:汉化名字和描述后面的内容,然后重启游戏即可,本mod只读取以“汉化信息_怪物”等形式开头的本地化文件");
streamWriter.WriteLine("Locate the content after \"名字:\" and \"描述:\", then restart the game.This mod only reads the localized files that start with \"汉化信息_物品\"、\"汉化信息_工具\"、\"汉化信息_怪物\"、\"汉化信息_效果\"");
streamWriter.WriteLine("==========================================");
foreach (KeyValuePair<string, T> item in dictionary)
{
if (typeof(T) == typeof(iteminfodata))
{
iteminfodata iteminfodata = item.Value as iteminfodata;
streamWriter.WriteLine(存.预制名 + item.Key);
streamWriter.WriteLine(存.名 + iteminfodata.itemname);
streamWriter.WriteLine(存.描述 + iteminfodata.itemdesc);
streamWriter.WriteLine($"{存.哈希}{iteminfodata.itemHash}");
}
else if (typeof(T) == typeof(EffectInfoData))
{
EffectInfoData effectInfoData = item.Value as EffectInfoData;
streamWriter.WriteLine(存.预制名 + effectInfoData.effectprename);
streamWriter.WriteLine(存.名 + effectInfoData.effectname);
streamWriter.WriteLine(存.描述 + effectInfoData.effectdesc);
streamWriter.WriteLine($"{存.哈希}{effectInfoData.effecthash}");
}
else if (typeof(T) == typeof(monsterinfodata))
{
monsterinfodata monsterinfodata = item.Value as monsterinfodata;
streamWriter.WriteLine(存.预制名 + monsterinfodata.monsterprename);
streamWriter.WriteLine(存.名 + monsterinfodata.monstername);
streamWriter.WriteLine($"{存.哈希}{monsterinfodata.monsterhash}");
}
else if (typeof(T) == typeof(pieceInfoData))
{
pieceInfoData pieceInfoData = item.Value as pieceInfoData;
streamWriter.WriteLine(存.预制名 + pieceInfoData.pieceprename);
streamWriter.WriteLine(存.名 + pieceInfoData.piecename);
streamWriter.WriteLine(存.描述 + pieceInfoData.piecedesc);
streamWriter.WriteLine($"{存.哈希}{pieceInfoData.piecehash}");
}
streamWriter.WriteLine("------------------------------------------");
}
}
Debug.Log((object)("懒濑:" + dictionaryType + "字典已成功保存到: " + filePath));
}
catch (Exception ex)
{
Debug.LogError((object)("懒濑:保存" + dictionaryType + "字典时出错: " + ex.Message));
}
}
public static void ApplyAllTranslations(ObjectDB objectDB)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
Stopwatch stopwatch = Stopwatch.StartNew();
num1 = 0;
num2 = 0;
num3 = 0;
num4 = 0;
string[] files = Directory.GetFiles(modLocalizationFolder, "*", SearchOption.AllDirectories);
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name != "main")
{
return;
}
string[] array = files;
foreach (string text in array)
{
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
string extension = Path.GetExtension(text);
if (!(extension != ".txt"))
{
if (fileNameWithoutExtension.StartsWith("汉化信息_怪物"))
{
Stopwatch stopwatch2 = Stopwatch.StartNew();
ApplyMonsterTranslations(objectDB, text);
stopwatch2.Stop();
Debug.Log((object)$"懒:怪物翻译耗时 {stopwatch2.Elapsed.TotalSeconds:F2}秒,处理文件:{text}");
}
else if (fileNameWithoutExtension.StartsWith("汉化信息_效果"))
{
Stopwatch stopwatch3 = Stopwatch.StartNew();
ApplyStatusEffects1(objectDB, text);
stopwatch3.Stop();
Debug.Log((object)$"懒:效果翻译耗时 {stopwatch3.Elapsed.TotalSeconds:F2}秒,处理文件:{text}");
}
else if (fileNameWithoutExtension.StartsWith("汉化信息_物品"))
{
Stopwatch stopwatch4 = Stopwatch.StartNew();
ApplyItemTranslations(objectDB, text);
stopwatch4.Stop();
Debug.Log((object)$"懒:物品翻译耗时 {stopwatch4.Elapsed.TotalSeconds:F2}秒,处理文件:{text}");
}
else if (fileNameWithoutExtension.StartsWith("汉化信息_工具"))
{
Stopwatch stopwatch5 = Stopwatch.StartNew();
ApplyPicecTranslations(objectDB, text);
stopwatch5.Stop();
Debug.Log((object)$"懒:工具翻译耗时 {stopwatch5.Elapsed.TotalSeconds:F2}秒,处理文件:{text}");
}
}
}
stopwatch.Stop();
Debug.Log((object)$"懒:翻译完成 - 总耗时 {stopwatch.Elapsed.TotalSeconds:F2}秒");
Debug.Log((object)$"懒:翻译统计 - 物品:{num1} 个,怪物:{num2} 个,工具:{num3} 个,效果:{num4} 个");
}
public static void ApplyItemTranslations(ObjectDB objectDB, string filePath)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name != "main" || !File.Exists(filePath))
{
return;
}
string[] array = File.ReadAllLines(filePath, Encoding.UTF8);
for (int i = 0; i < array.Length - 3; i++)
{
if (!array[i].StartsWith(存.预制名))
{
continue;
}
string prefabName = array[i].Substring(存.预制名.Length).Trim();
string text = array[i + 1].Substring(存.名.Length).Trim();
string description = array[i + 2].Substring(存.描述.Length).Trim();
int result = 0;
if (i + 3 < array.Length && array[i + 3].StartsWith(存.哈希))
{
int.TryParse(array[i + 3].Substring(存.哈希.Length).Trim(), out result);
}
GameObject itemPrefab = GetItemPrefab(objectDB, result, prefabName, text);
if (!((Object)(object)itemPrefab == (Object)null))
{
ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
if (component?.m_itemData?.m_shared != null)
{
component.m_itemData.m_shared.m_name = text;
component.m_itemData.m_shared.m_description = description;
num1++;
}
}
}
}
public static void ApplyMonsterTranslations(ObjectDB objectDB, string filePath)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name != "main" || !File.Exists(filePath))
{
return;
}
string[] array = File.ReadAllLines(filePath);
for (int i = 0; i < array.Length - 1; i++)
{
if (!array[i].StartsWith(存.预制名))
{
continue;
}
string text = array[i].Substring(存.预制名.Length);
string text2 = array[i + 1].Substring(存.名.Length);
int result = 0;
if (i + 2 < array.Length && array[i + 2].StartsWith(存.哈希))
{
int.TryParse(array[i + 2].Substring(存.哈希.Length).Trim(), out result);
}
GameObject itemPrefab = GetItemPrefab(objectDB, result, text, text2);
Humanoid val = ((itemPrefab != null) ? itemPrefab.GetComponent<Humanoid>() : null);
if (val != null)
{
((Character)val).m_name = text2;
num2++;
continue;
}
Humanoid[] array2 = Resources.FindObjectsOfTypeAll<Humanoid>();
foreach (Humanoid val2 in array2)
{
if (((Object)val2).name == text)
{
((Character)val2).m_name = text2;
num2++;
}
}
}
}
public static void ApplyPicecTranslations(ObjectDB objectDB, string filePath)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name != "main" || !File.Exists(filePath))
{
return;
}
string[] array = File.ReadAllLines(filePath);
for (int i = 0; i < array.Length - 1; i++)
{
if (!array[i].StartsWith(存.预制名))
{
continue;
}
string text = array[i].Substring(存.预制名.Length);
string text2 = array[i + 1].Substring(存.名.Length);
string description = array[i + 2].Substring(存.描述.Length);
int result = 0;
if (i + 3 < array.Length && array[i + 3].StartsWith(存.哈希))
{
int.TryParse(array[i + 3].Substring(存.哈希.Length).Trim(), out result);
}
GameObject itemPrefab = GetItemPrefab(objectDB, result, text, text2);
Piece val = ((itemPrefab != null) ? itemPrefab.GetComponent<Piece>() : null);
if (val != null)
{
val.m_name = text2;
val.m_description = description;
num3++;
continue;
}
Piece[] array2 = Resources.FindObjectsOfTypeAll<Piece>();
foreach (Piece val2 in array2)
{
if (((Object)val2).name == text)
{
val2.m_name = text2;
val2.m_description = description;
num3++;
}
}
}
}
public static void ApplyStatusEffects1(ObjectDB objectDB, string filePath)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name != "main" || !File.Exists(filePath))
{
return;
}
string[] array = File.ReadAllLines(filePath);
for (int i = 0; i < array.Length - 1; i++)
{
if (!array[i].StartsWith(存.预制名))
{
continue;
}
string text = array[i].Substring(存.预制名.Length);
string text2 = array[i + 1].Substring(存.名.Length);
string text3 = array[i + 2].Substring(存.描述.Length);
int result = 0;
if (i + 3 < array.Length && array[i + 3].StartsWith(存.哈希))
{
int.TryParse(array[i + 3].Substring(存.哈希.Length).Trim(), out result);
}
Dictionary<int, EffectInfoData> dictionary = new Dictionary<int, EffectInfoData>();
Dictionary<string, EffectInfoData> dictionary2 = new Dictionary<string, EffectInfoData>();
dictionary[result] = new EffectInfoData
{
effectprename = text,
effectdesc = text3,
effectname = text2,
effecthash = result
};
dictionary2[text] = new EffectInfoData
{
effectprename = text,
effectdesc = text3,
effectname = text2,
effecthash = result
};
foreach (StatusEffect item in objectDB.m_StatusEffects.Where((StatusEffect se) => (Object)(object)se != (Object)null))
{
EffectInfoData value;
EffectInfoData effectInfoData = (dictionary.TryGetValue(item.NameHash(), out value) ? value : (dictionary2.TryGetValue(((Object)item).name, out value) ? value : null));
if (effectInfoData != null)
{
item.m_name = text2;
item.m_tooltip = text3;
num4++;
}
}
}
}
private static GameObject GetItemPrefab(ObjectDB objectDB, int hash, string prefabName, string itemName)
{
string prefabName2 = prefabName;
string itemName2 = itemName;
if (hash != 0)
{
GameObject val = GetGameObject(hash) ?? ((objectDB != null) ? objectDB.GetItemPrefab(hash) : null);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
if (!string.IsNullOrEmpty(prefabName2))
{
GameObject val2 = GetGameObject(prefabName2) ?? ((IEnumerable<GameObject>)objectDB?.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject item) => ((item != null) ? ((Object)item).name : null) == prefabName2));
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
if (!string.IsNullOrEmpty(itemName2))
{
return GetGameObject(itemName2) ?? ((IEnumerable<GameObject>)objectDB?.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject item) => ((item != null) ? ((Object)item).name : null) == itemName2));
}
return null;
}
public static GameObject GetGameObject(string name)
{
if (string.IsNullOrEmpty(name))
{
Debug.LogError((object)"获取预制件名时,传入了空字符");
return null;
}
if (缓存.m_PrefabCache.ContainsKey(name))
{
return 缓存.m_PrefabCache[name];
}
GameObject val = ZNetScene.instance.GetPrefab(name) ?? ObjectDB.instance.GetItemPrefab(name) ?? ResourcesGetGameObject(name);
if ((Object)(object)val == (Object)null)
{
return null;
}
if (!缓存.m_PrefabCache.ContainsKey(((Object)val).name))
{
缓存.m_PrefabCache.Add(((Object)val).name, val);
}
return val;
}
public static GameObject GetGameObject(int hash)
{
GameObject val = ZNetScene.instance.GetPrefab(hash) ?? ObjectDB.instance.GetItemPrefab(hash);
if ((Object)(object)val == (Object)null)
{
return null;
}
if (!缓存.m_PrefabCache.ContainsKey(((Object)val).name))
{
缓存.m_PrefabCache.Add(((Object)val).name, val);
}
return val;
}
private static GameObject ResourcesGetGameObject(string name)
{
GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
GameObject[] array2 = array;
foreach (GameObject val in array2)
{
if (((Object)val).name == name)
{
return val;
}
}
return null;
}
public void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
KeyboardShortcut value = Shortcut.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
ExportFilteredData();
}
value = modShortcut.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
LoadModNamesFromConfig();
string[] array = LoadModNamesFromConfig();
string[] array2 = array;
foreach (string modName in array2)
{
ExportByModSearch(modName);
}
}
value = TranslateShortcut.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
if (TranslationProcessor.HasProgress())
{
TranslationProcessor.ResumeTranslation();
}
else
{
TranslationProcessor.ProcessAllTranslations();
}
}
value = TranslateShortcut.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && Input.GetKey((KeyCode)306))
{
TranslationProcessor.ResetProgress();
TranslationProcessor.ProcessAllTranslations();
}
value = TranslateShortcut.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && Input.GetKey((KeyCode)308))
{
TranslationProcessor.ShowProgress();
}
value = textup.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
ObjectDB instance = ObjectDB.instance;
if ((Object)(object)instance != (Object)null)
{
ApplyAllTranslations(instance);
}
else
{
Debug.LogError((object)"懒濑:按键触发时无法获取 ObjectDB 实例");
}
}
}
private async void TestTranslation()
{
try
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"开始测试翻译功能...");
string testText = "Hello world! This is a translation test.";
string translatedText = await DeepSeekTranslator.Instance.TranslateAsync(testText, "中文");
if (!string.IsNullOrEmpty(translatedText))
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("翻译前: " + testText));
((BaseUnityPlugin)this).Logger.LogInfo((object)("翻译后: " + translatedText));
((BaseUnityPlugin)this).Logger.LogInfo((object)"翻译测试成功完成!");
}
else
{
((BaseUnityPlugin)this).Logger.LogError((object)"翻译测试失败:返回结果为空");
}
}
catch (Exception ex2)
{
Exception ex = ex2;
((BaseUnityPlugin)this).Logger.LogError((object)("翻译测试过程中发生异常: " + ex.Message));
}
}
private string[] LoadModNamesFromConfig()
{
try
{
if (File.Exists(modNameConfigPath))
{
return (from line in File.ReadAllLines(modNameConfigPath)
where !string.IsNullOrWhiteSpace(line)
select line.Trim()).ToArray();
}
string[] array = new string[2] { "//Please enter the name of the mod to which the text you want to export belongs.for example, SouthsilArmor,Multiple entries, please press enter to continue.", "SouthsilArmor" };
File.WriteAllLines(modNameConfigPath, array);
Debug.Log((object)("已创建默认Mod名称筛选文件: " + modNameConfigPath));
return array;
}
catch (Exception ex)
{
Debug.LogError((object)("加载Mod名称配置文件失败: " + ex.Message));
return new string[0];
}
}
private void ExportByModSearch(string modName)
{
if (string.IsNullOrWhiteSpace(modName))
{
Debug.LogWarning((object)"跳过空的Mod名称筛选条件");
return;
}
int num = 0;
bool flag = false;
bool flag2 = false;
bool flag3 = false;
bool flag4 = false;
bool flag5 = false;
try
{
ModPrefabManager.InitializeModInfo();
List<string> list = ModPrefabManager.SearchPrefabsByModName(modName);
if (list.Count == 0)
{
Debug.LogWarning((object)("未找到Mod '" + modName + "' 相关的预制件"));
return;
}
string path = $"汉化信息__{modName}_{DateTime.Now:yyyyMMdd_HHmm}.txt";
string text = Path.Combine(modLocalizationFolder, path);
using (StreamWriter streamWriter = new StreamWriter(text, append: false, Encoding.UTF8))
{
streamWriter.WriteLine("Mod名称/modname: " + modName);
streamWriter.WriteLine($"导出时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
streamWriter.WriteLine($"找到预制件数量: {list.Count}");
streamWriter.WriteLine("这里是根据mod名导出的文本,例如SouthsilArmor。");
streamWriter.WriteLine("This is the text derived based on the mod name. ");
streamWriter.WriteLine("本地化后将其中内容按板块分别复制到以\"汉化信息_物品\\\"、\\\"汉化信息_工具\\\"、\\\"汉化信息_怪物\\\"、\\\"汉化信息_效果\\\"开头的文件。 ");
streamWriter.WriteLine("完成后重启生效");
streamWriter.WriteLine("After localization, the contents should be copied to separate files starting with \"汉化信息_物品\"、\"汉化信息_工具\"、\"汉化信息_怪物\"and\"汉化信息_效果\", respectively.");
streamWriter.WriteLine("After completion, restart to make the localization take effect.");
streamWriter.WriteLine("==========================================");
streamWriter.WriteLine();
foreach (string item in list)
{
EffectInfoData value2;
monsterinfodata value3;
pieceInfoData value4;
if (翻译工具.物品字典.TryGetValue(item, out iteminfodata value))
{
if (!flag)
{
streamWriter.WriteLine("【物品item】");
streamWriter.WriteLine("------------------------------------------");
flag = true;
}
streamWriter.WriteLine(存.预制名 + item);
streamWriter.WriteLine(存.名 + value.itemname);
streamWriter.WriteLine(存.描述 + value.itemdesc);
streamWriter.WriteLine($"{存.哈希}{value.itemHash}");
streamWriter.WriteLine("------------------------------------------");
num++;
}
else if (翻译工具.效果字典.TryGetValue(item, out value2))
{
if (!flag2)
{
streamWriter.WriteLine("【效果effect】");
streamWriter.WriteLine("------------------------------------------");
flag2 = true;
}
streamWriter.WriteLine(存.预制名 + item);
streamWriter.WriteLine(存.名 + value2.effectname);
streamWriter.WriteLine(存.描述 + value2.effectdesc);
streamWriter.WriteLine($"{存.哈希}{value2.effecthash}");
streamWriter.WriteLine("------------------------------------------");
num++;
}
else if (翻译工具.怪物字典.TryGetValue(item, out value3))
{
if (!flag3)
{
streamWriter.WriteLine("【怪物creature】");
streamWriter.WriteLine("------------------------------------------");
flag3 = true;
}
streamWriter.WriteLine(存.预制名 + item);
streamWriter.WriteLine(存.名 + value3.monstername);
streamWriter.WriteLine($"{存.哈希}{value3.monsterhash}");
streamWriter.WriteLine("------------------------------------------");
num++;
}
else if (翻译工具.工具字典.TryGetValue(item, out value4))
{
if (!flag4)
{
streamWriter.WriteLine("【工具pieces】");
streamWriter.WriteLine("------------------------------------------");
flag4 = true;
}
streamWriter.WriteLine(存.预制名 + item);
streamWriter.WriteLine(存.名 + value4.piecename);
streamWriter.WriteLine(存.描述 + value4.piecedesc);
streamWriter.WriteLine($"{存.哈希}{value4.piecehash}");
streamWriter.WriteLine("------------------------------------------");
num++;
}
else
{
if (!flag5)
{
streamWriter.WriteLine("【未知unknown】");
streamWriter.WriteLine("------------------------------------------");
flag5 = true;
}
streamWriter.WriteLine(存.预制名 + item);
streamWriter.WriteLine(存.名 + "未找到本地化信息");
streamWriter.WriteLine(存.描述 + "未找到本地化信息");
streamWriter.WriteLine(存.哈希 + "未找到本地化信息");
streamWriter.WriteLine("------------------------------------------");
num++;
}
}
streamWriter.WriteLine();
streamWriter.WriteLine($"成功导出: {num} 个预制件");
}
Debug.Log((object)$"懒濑:已导出Mod '{modName}' 的 {num} 个预制件到: {text}");
}
catch (Exception ex)
{
Debug.LogError((object)("懒濑:导出Mod '" + modName + "' 时出错: " + ex.Message));
}
}
public void OnDestroy()
{
}
}
}
namespace 全局本地化.Data
{
public class EffectInfoData
{
public string effectprename { get; set; } = string.Empty;
public string effectname { get; set; } = string.Empty;
public string effectdesc { get; set; } = string.Empty;
public int effecthash { get; set; } = 0;
}
public class EffectInfoData1
{
public string effectprename { get; set; }
public string effectdesc { get; set; }
public string effectname { get; set; }
public string effecthash { get; set; }
}
public class iteminfodata
{
public string itemname { get; set; } = string.Empty;
public string itemdesc { get; set; } = string.Empty;
public int itemHash { get; set; } = 0;
}
public class ModInfoData
{
public string ModName { get; set; } = "";
public string ModGUID { get; set; } = "";
public List<string> PrefabNames { get; set; } = new List<string>();
}
public static class ModPrefabManager
{
public static readonly Dictionary<string, ModInfoData> ModInfoDict = new Dictionary<string, ModInfoData>();
public static readonly Dictionary<string, string> PrefabToModMap = new Dictionary<string, string>();
public static void InitializeModInfo()
{
ModInfoDict.Clear();
PrefabToModMap.Clear();
foreach (IModPrefab prefab in ModQuery.GetPrefabs())
{
if (prefab != null && Object.op_Implicit((Object)(object)prefab.Prefab) && prefab.SourceMod != null)
{
string gUID = prefab.SourceMod.GUID;
string name = ((Object)prefab.Prefab).name;
if (!ModInfoDict.ContainsKey(gUID))
{
ModInfoDict[gUID] = new ModInfoData
{
ModName = prefab.SourceMod.Name,
ModGUID = gUID,
PrefabNames = new List<string>()
};
}
if (!ModInfoDict[gUID].PrefabNames.Contains(name))
{
ModInfoDict[gUID].PrefabNames.Add(name);
}
if (!PrefabToModMap.ContainsKey(name))
{
PrefabToModMap[name] = gUID;
}
}
}
}
public static List<string> SearchPrefabsByModName(string modName)
{
List<string> list = new List<string>();
foreach (ModInfoData value in ModInfoDict.Values)
{
if (value.ModName.IndexOf(modName, StringComparison.OrdinalIgnoreCase) >= 0 || value.ModGUID.IndexOf(modName, StringComparison.OrdinalIgnoreCase) >= 0)
{
list.AddRange(value.PrefabNames);
}
}
return list.Distinct().ToList();
}
public static List<string> GetAllModNames()
{
return ModInfoDict.Values.Select((ModInfoData mod) => mod.ModName).Distinct().ToList();
}
public static ModInfoData GetModByPrefabName(string prefabName)
{
if (PrefabToModMap.TryGetValue(prefabName, out string value) && ModInfoDict.TryGetValue(value, out ModInfoData value2))
{
return value2;
}
return null;
}
}
public class monsterinfodata
{
public string monstername { get; set; } = string.Empty;
public string monsterprename { get; set; } = string.Empty;
public int monsterhash { get; set; } = 0;
}
public class pieceInfoData
{
public string pieceprename { get; set; } = string.Empty;
public string piecename { get; set; } = string.Empty;
public string piecedesc { get; set; } = string.Empty;
public int piecehash { get; set; } = 0;
}
}