347 lines
13 KiB
C#
347 lines
13 KiB
C#
/*
|
||
* Author: Nikolay Dvurechensky
|
||
* Site: https://www.dvurechensky.pro/
|
||
* Gmail: dvurechenskysoft@gmail.com
|
||
* Last Updated: 13 мая 2025 15:25:18
|
||
* Version: 1.0.1
|
||
*/
|
||
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Globalization;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Resources;
|
||
using FLCore;
|
||
using FLData;
|
||
using FLGenerateLibrary;
|
||
using Services;
|
||
|
||
[assembly: NeutralResourcesLanguage("ru")]
|
||
|
||
public enum TypeSearch
|
||
{
|
||
Id,
|
||
Value
|
||
}
|
||
|
||
public class Program
|
||
{
|
||
private static bool _initialized = true;
|
||
|
||
static void Main(string[] args)
|
||
{
|
||
Console.WriteLine("* По умолчанию файл ресурсов читается из папки проекта Properties");
|
||
Console.WriteLine("[g] - поиск уникальных значений поля в INI файле (Example: g example.ini progres_field)");
|
||
Console.WriteLine("[clear]/[c] - очистка файла ресурсов");
|
||
Console.WriteLine("[st] - генерация из папки с TXT (.dll Win32 -> Resource Hacker -> .rc файл -> .txt файлы) строк в .resx файл");
|
||
Console.WriteLine("[html] - генерация из папки HTML (.dll Win32 -> Resource Hacker -> .rc файл -> .txt файлы информационных карт) строк в .resx файл");
|
||
Console.WriteLine("[import][i] - импорт в папку INPUT тестовых данных для генерации .resx в папку OUTPUT");
|
||
Console.WriteLine("[all][a] - генерация сразу всех компонентов");
|
||
Console.WriteLine("[rhtml] - вывод текста сгенерированного в папке HTML после обработки в формате для Unity - TextMeshPro");
|
||
Console.WriteLine("[exit][e][q] - завершение работы");
|
||
Console.WriteLine("::[text] - поиск по тексту совпадения в ресурсах");
|
||
Console.WriteLine("!![id] - поиск по идентификатору совпадения в ресурсах");
|
||
Console.WriteLine("-----------------------------------------------------");
|
||
while (_initialized)
|
||
{
|
||
Console.WriteLine("Please Enter Command separated by space: [clear]/[c] or [string table]/[st] or [html]/[h] or [exit][e][q]");
|
||
var command = Console.ReadLine();
|
||
ApplyCommand(command);
|
||
}
|
||
Console.ReadLine();
|
||
}
|
||
|
||
static void ReimportHTML()
|
||
{
|
||
var files = Directory.GetFiles("HTML");
|
||
foreach (var file in files)
|
||
{
|
||
var name = file.Substring(file.LastIndexOf("\\") + 6);
|
||
var newName = "HTML" + name + "_1.txt";
|
||
var fullNewName = Path.Combine("HTML", newName);
|
||
File.Move(file, fullNewName);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Check Exist Tags RC
|
||
/// equipresources.rc - PUSH TRA JUST TEXT PARA POP
|
||
/// </summary>
|
||
static void ReadTagsHTML(string path)
|
||
{
|
||
if(!Directory.Exists(path))
|
||
{
|
||
Console.WriteLine($"Папка: {path} - не существует!");
|
||
return;
|
||
}
|
||
|
||
var text = string.Empty;
|
||
foreach (string f in Directory.GetFiles(path))
|
||
{
|
||
var d = File.ReadAllText(f, encoding: System.Text.Encoding.GetEncoding("UTF-16"));
|
||
var xd = new XMLtoUnityFormatConverter(text);
|
||
var data = xd.ReadXmlData(d, f);
|
||
if (data.Count > 1)
|
||
{
|
||
Console.WriteLine("\n ЗАМЕНЁННЫЕ ТЕГИ: \n" + data[1] + "\n---------------------\n" + data[0]);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void ApplyCommand(string command)
|
||
{
|
||
if (command.Contains("!!")) // поиск текста по идентификатору
|
||
{
|
||
Console.Clear();
|
||
Console.WriteLine("");
|
||
|
||
var searchStr = command.Substring(command.IndexOf("!!") + 2);
|
||
var data = Search(TypeSearch.Id, searchStr);
|
||
foreach (var item in data)
|
||
{
|
||
Console.WriteLine($"=> [{item.NameResources}] <{item.Key}> {item.Value}");
|
||
Console.WriteLine();
|
||
}
|
||
}
|
||
else if (command.Contains("::")) // поиск идентификатора по тексту
|
||
{
|
||
Console.Clear();
|
||
Console.WriteLine("");
|
||
|
||
if (command.Contains("|"))
|
||
{
|
||
var dll = command.Substring(command.IndexOf("|") + 1);
|
||
}
|
||
|
||
var searchStr = command.Substring(command.IndexOf("::") + 2);
|
||
var data = Search(TypeSearch.Value, searchStr);
|
||
foreach (var item in data)
|
||
{
|
||
Console.WriteLine($"=> [{item.NameResources}] <{item.Key}> {item.Value}");
|
||
Console.WriteLine();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var commands = command.Split(' ');
|
||
|
||
if (commands.Length > 0)
|
||
{
|
||
if (commands.Length == 2)
|
||
{
|
||
switch (commands[0])
|
||
{
|
||
case "clear":
|
||
case "c":
|
||
new ResourcesCreater(commands[1]).ClearAllData();
|
||
break;
|
||
case "rhtml":
|
||
ReadTagsHTML(commands[1]);
|
||
break;
|
||
}
|
||
}
|
||
if (commands.Length == 3)
|
||
{
|
||
switch (commands[0])
|
||
{
|
||
case "g": // ищет все уникальные значения поля INI файла
|
||
ApplyAnalisINI("Analis\\" + commands[1], commands[2]);
|
||
break;
|
||
case "st":
|
||
new ResourcesCreater(commands[1]).CreateStringTableData(commands[2]);
|
||
break;
|
||
case "html":
|
||
case "h":
|
||
new ResourcesCreater(commands[1]).CreateHTMLData(commands[2]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
switch (command)
|
||
{
|
||
case "exit":
|
||
case "q":
|
||
case "e":
|
||
_initialized = false;
|
||
break;
|
||
case "import":
|
||
case "i":
|
||
ImportTestData();
|
||
break;
|
||
case "all":
|
||
case "a":
|
||
FullCreateResx();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
private static void ImportTestData()
|
||
{
|
||
Console.WriteLine("Start import test data...");
|
||
string exePath = Assembly.GetExecutingAssembly().Location;
|
||
string source = Path.Combine(Path.GetDirectoryName(exePath), "TestData");
|
||
string target = Path.Combine(Path.GetDirectoryName(exePath), "INPUT");
|
||
|
||
CopyDirectory(source, target);
|
||
Console.WriteLine("Complete import test data");
|
||
}
|
||
|
||
public static void CopyDirectory(string sourceDir, string destinationDir, bool copySubDirs = true)
|
||
{
|
||
var dir = new DirectoryInfo(sourceDir);
|
||
if (!dir.Exists)
|
||
throw new DirectoryNotFoundException($"Исходная папка не найдена: {sourceDir}");
|
||
|
||
// Создаём целевую папку, если не существует
|
||
Directory.CreateDirectory(destinationDir);
|
||
|
||
// Копируем файлы
|
||
foreach (FileInfo file in dir.GetFiles())
|
||
{
|
||
string targetFilePath = Path.Combine(destinationDir, file.Name);
|
||
file.CopyTo(targetFilePath, overwrite: true);
|
||
}
|
||
|
||
// Рекурсивно копируем подпапки
|
||
if (copySubDirs)
|
||
{
|
||
foreach (DirectoryInfo subDir in dir.GetDirectories())
|
||
{
|
||
string newDestinationDir = Path.Combine(destinationDir, subDir.Name);
|
||
CopyDirectory(subDir.FullName, newDestinationDir, copySubDirs);
|
||
}
|
||
}
|
||
}
|
||
|
||
private static void ApplyAnalisINI(string path, string keyPair)
|
||
{
|
||
if (!File.Exists(path))
|
||
{
|
||
Console.WriteLine($"File: {path} not found");
|
||
return;
|
||
}
|
||
|
||
var data = File.ReadAllLines(path);
|
||
|
||
var list = new List<string>();
|
||
foreach( var item in data)
|
||
{
|
||
if(item.Contains("="))
|
||
{
|
||
var keyVal = item.Split('=');
|
||
var key = keyVal[0].Trim();
|
||
var value = keyVal[1].Trim().Split(',');
|
||
if(key == keyPair && !list.Contains(value[0]))
|
||
{
|
||
list.Add(value[0]);
|
||
Console.WriteLine(value[0]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static void FullCreateResx()
|
||
{
|
||
var inputFolder = "INPUT";
|
||
var _paths = GenerateOutputResx(); //пути до файлов ресурсов
|
||
var _listInputPaths = new List<string>();
|
||
|
||
var index = 0;
|
||
foreach (var path in _paths)
|
||
{
|
||
var _nameInputPath = path.Substring(path.IndexOf("\\") + 1, path.LastIndexOf('_') - (path.IndexOf("\\") + 1));
|
||
var nameInputPath = _nameInputPath.Substring(_nameInputPath.IndexOf("\\") + 1, _nameInputPath.Length - _nameInputPath.IndexOf("\\") - 1);
|
||
_listInputPaths.Add(nameInputPath);
|
||
GenerateResxData(inputFolder, nameInputPath, path, ref index, _paths.Count);
|
||
}
|
||
|
||
Console.WriteLine("[End] Please press Enter");
|
||
}
|
||
|
||
static void GenerateResxData(string inputFolder, string nameInputFolder, string nameOutputFolder, ref int index, int count)
|
||
{
|
||
var typeGenerate = nameOutputFolder.Substring(nameOutputFolder.LastIndexOf("_"));
|
||
var _pathInfo = Path.Combine(nameInputFolder, "HTML");
|
||
var pathInfo = Path.Combine(inputFolder, _pathInfo);
|
||
var _pathName = Path.Combine(nameInputFolder, "data.txt");
|
||
var pathName = Path.Combine(inputFolder, _pathName);
|
||
|
||
if(typeGenerate.Contains("name"))
|
||
{
|
||
if(File.Exists(pathName))
|
||
new ResourcesCreater(nameOutputFolder).CreateStringTableData(pathName);
|
||
}
|
||
else
|
||
{
|
||
if(Directory.Exists(pathInfo))
|
||
new ResourcesCreater(nameOutputFolder).CreateHTMLData(pathInfo);
|
||
}
|
||
|
||
index++;
|
||
Console.WriteLine($"[{index}/{count}]: {nameInputFolder}->{nameOutputFolder}");
|
||
}
|
||
|
||
static List<string> GenerateOutputResx()
|
||
{
|
||
var nameOut = "OUTPUT";
|
||
var dateName = DateTime.Now.ToString("dd.MM.yyyy.hh.mm.ss");
|
||
var dir = Path.Combine(nameOut, dateName);
|
||
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
|
||
var paths = new List<string>();
|
||
foreach(var name in ResourceData.NamesResorces)
|
||
{
|
||
var _path = Path.Combine(dir, name);
|
||
paths.Add(_path);
|
||
using (ResXResourceWriter resx = new ResXResourceWriter(_path)) { }
|
||
}
|
||
return paths;
|
||
}
|
||
|
||
static List<SearchInfo> Search(TypeSearch type, string value)
|
||
{
|
||
var searchInfo = new List<SearchInfo>();
|
||
foreach (var name in ResourceData.NamesResorces)
|
||
{
|
||
var nameRes = name.Substring(0, name.IndexOf("."));
|
||
var assembly = FLResources.ResControl.GetAssemblyByName(nameRes);
|
||
var resource = new DataSetter().GetResource(nameRes, ResourceData.NamesResorces, "FLResources", assembly);
|
||
var keys = resource.GetResourceSet(CultureInfo.InvariantCulture, true, true)
|
||
.Cast<DictionaryEntry>()
|
||
.Select(entry => entry.Key)
|
||
.Cast<string>();
|
||
var Data = keys.ToDictionary(
|
||
key => key,
|
||
key => resource.GetString(key, CultureInfo.GetCultureInfo("de")));
|
||
|
||
var val = new Dictionary<string, string>();
|
||
switch(type)
|
||
{
|
||
case TypeSearch.Id:
|
||
val = Data.Where(t => t.Key.ToLower() == value.ToLower()).ToDictionary(x => x.Key, x => x.Value);
|
||
break;
|
||
case TypeSearch.Value:
|
||
val = Data.Where(t => t.Value.ToLower().Contains(value.ToLower())).ToDictionary(x => x.Key, x => x.Value);
|
||
break;
|
||
}
|
||
|
||
if (val.Count > 0)
|
||
{
|
||
foreach (var kv in val)
|
||
{
|
||
searchInfo.Add(new SearchInfo()
|
||
{
|
||
Key = kv.Key,
|
||
Value = kv.Value,
|
||
NameResources = name
|
||
});
|
||
}
|
||
}
|
||
}
|
||
return searchInfo;
|
||
}
|
||
} |