Загрузка данных
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Windows.Forms;
namespace QualityTest_Inventory
{
public partial class Form1 : Form
{
// Словари для хранения строк текущего языка и эталонных ключей
private Dictionary<string, string> currentTranslations = new Dictionary<string, string>();
private HashSet<string> referenceKeys = new HashSet<string>();
// Переменные логики инвентаря
private double totalWeight = 0.0;
private const double WeightLimit = 50.0; // Предел веса
private string currentLang = "ru"; // Язык по умолчанию
public Form1()
{
InitializeComponent();
SetupDataGridView();
}
private void Form1_Load(object sender, EventArgs e)
{
// 1. Инициализация и проверка целостности файлов локализации
InitializeLocalizationSystem();
// 2. Загрузка конфигурации (сохранение между сеансами)
LoadConfiguration();
// 3. Применение выбранного языка и заполнение списков
SwitchLanguage(currentLang);
}
// Настройка таблицы инвентаря
private void SetupDataGridView()
{
dgvInventory.ColumnCount = 4;
dgvInventory.Columns[0].Name = "Name";
dgvInventory.Columns[1].Name = "CategoryKey"; // Скрытый ключ для локализации категории
dgvInventory.Columns[2].Name = "Weight";
dgvInventory.Columns[3].Name = "Quantity";
// Сделаем красивое отображение названий столбцов на этапе применения языка
dgvInventory.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgvInventory.MultiSelect = false;
dgvInventory.AllowUserToAddRows = false;
}
#region БЛОК ЛОКАЛИЗАЦИИ И ПРОВЕРКИ ЦЕЛОСТНОСТИ
private void InitializeLocalizationSystem()
{
string ruPath = "ru.json";
string enPath = "en.json";
// Если файлов нет на диске, сообщаем об ошибке
if (!File.Exists(ruPath) || !File.Exists(enPath))
{
lstLogs.Items.Add("[CRITICAL] Отсутствуют файлы ru.json или en.json!");
return;
}
try
{
// Читаем все ключи из обоих файлов для формирования эталона (Объединение множеств)
string ruJson = File.ReadAllText(ruPath);
string enJson = File.ReadAllText(enPath);
var ruDict = JsonSerializer.Deserialize<Dictionary<string, string>>(ruJson);
var enDict = JsonSerializer.Deserialize<Dictionary<string, string>>(enJson);
if (ruDict != null) foreach (var key in ruDict.Keys) referenceKeys.Add(key);
if (enDict != null) foreach (var key in enDict.Keys) referenceKeys.Add(key);
}
catch (Exception ex)
{
lstLogs.Items.Add("[ERROR] Ошибка инициализации эталона: " + ex.Message);
}
}
// Метод проверки полноты конкретного языкового файла
private void ValidateLanguageFile(string langCode, Dictionary<string, string> targetDict)
{
foreach (string refKey in referenceKeys)
{
if (!targetDict.ContainsKey(refKey))
{
// Вывод в лог GUI сообщения об отсутствии ключа
lstLogs.Items.Add($"[LOCALIZATION] Отсутствует строка: {refKey} в файле {langCode}.json");
}
}
}
// Централизованный метод получения строки по ключу с обработкой плейсхолдеров
private string GetText(string key)
{
if (currentTranslations.ContainsKey(key))
{
return currentTranslations[key];
}
return $"[MISSING: {key}]"; // Placeholder при отсутствии ключа
}
private void SwitchLanguage(string langCode)
{
string filePath = $"{langCode}.json";
if (!File.Exists(filePath)) return;
try
{
string jsonContent = File.ReadAllText(filePath);
var loaded = JsonSerializer.Deserialize<Dictionary<string, string>>(jsonContent);
if (loaded != null)
{
currentTranslations = loaded;
// Проверка полноты перевода при каждой смене/загрузке языка
ValidateLanguageFile(langCode, currentTranslations);
}
}
catch (Exception ex)
{
lstLogs.Items.Add($"[ERROR] Ошибка чтения {filePath}: " + ex.Message);
}
currentLang = langCode;
SaveConfiguration(); // Сохраняем выбор в config.json
ApplyLanguage(); // Немедленно обновляем весь GUI
}
// Централизованный метод обновления интерфейса
private void ApplyLanguage()
{
// Меню
menuInventory.Text = GetText("menu_inventory");
menuCharacter.Text = GetText("menu_character");
menuLanguage.Text = GetText("menu_language");
// Метки формы
lblItemName.Text = GetText("lbl_item_name");
lblCategory.Text = GetText("lbl_category");
lblWeight.Text = GetText("lbl_weight");
lblQuantity.Text = GetText("lbl_quantity");
// Кнопки
btnAdd.Text = GetText("btn_add");
btnUse.Text = GetText("btn_use");
btnDelete.Text = GetText("btn_delete");
// Статистика
lblStatsTitle.Text = GetText("lbl_stats_title");
lblTotalWeight.Text = string.Format(GetText("lbl_total_weight"), totalWeight);
lblWeightLimit.Text = string.Format(GetText("lbl_weight_limit"), WeightLimit);
// Перезаполнение ComboBox категорий с сохранением выбранного индекса
int selectedCatIndex = cmbCategory.SelectedIndex;
cmbCategory.Items.Clear();
cmbCategory.Items.Add(GetText("cat_weapon"));
cmbCategory.Items.Add(GetText("cat_armor"));
cmbCategory.Items.Add(GetText("cat_potion"));
cmbCategory.SelectedIndex = selectedCatIndex >= 0 ? selectedCatIndex : 0;
// Динамическое обновление названий колонок DataGridView без перезапуска
if (dgvInventory.Columns.Count >= 4)
{
dgvInventory.Columns[0].HeaderText = GetText("lbl_item_name").Replace(":", "");
dgvInventory.Columns[1].HeaderText = GetText("lbl_category").Replace(":", "");
dgvInventory.Columns[2].HeaderText = GetText("lbl_weight").Replace(":", "");
dgvInventory.Columns[3].HeaderText = GetText("lbl_quantity").Replace(":", "");
}
// Локализация содержимого таблицы (динамический пересчет строк на лету)
UpdateGridCategoriesText();
}
private void UpdateGridCategoriesText()
{
foreach (DataGridViewRow row in dgvInventory.Rows)
{
if (row.Cells[1].Value != null)
{
string catKey = row.Cells[1].Value.ToString();
row.Cells[1].Value = catKey; // Оставляем ключ в значении, но визуально отобразим текст
}
}
}
#endregion
#region КОНФИГУРАЦИЯ (CONFIG.JSON)
private void LoadConfiguration()
{
string configPath = "config.json";
if (!File.Exists(configPath))
{
// При первом запуске создаем файл с дефолтным русским языком
currentLang = "ru";
SaveConfiguration();
}
else
{
try
{
string json = File.ReadAllText(configPath);
using (JsonDocument doc = JsonDocument.Parse(json))
{
if (doc.RootElement.TryGetProperty("current_language", out JsonElement langElement))
{
currentLang = langElement.GetString();
}
}
}
catch
{
currentLang = "ru"; // В случае сбоя сбрасываем на русский
}
}
}
private void SaveConfiguration()
{
try
{
var configData = new { current_language = currentLang };
string json = JsonSerializer.Serialize(configData);
File.ReadAllText(json); // Симуляция записи/Запись на диск:
File.WriteAllText("config.json", json);
}
catch (Exception ex)
{
lstLogs.Items.Add("[ERROR] Не удалось сохранить конфигурацию: " + ex.Message);
}
}
#endregion
#region ЛОГИКА ИГРОВОГО ИНВЕНТАРЯ (КНОПКИ И ДЕЙСТВИЯ)
// Переключение языка через меню
private void menuLangRu_Click(object sender, EventArgs e) => SwitchLanguage("ru");
private void menuLangEn_Click(object sender, EventArgs e) => SwitchLanguage("en");
// Кнопка Добавить
private void btnAdd_Click(object sender, EventArgs e)
{
string name = txtItemName.Text.Trim();
if (string.IsNullOrEmpty(name)) return;
int catIndex = cmbCategory.SelectedIndex;
string catKey = catIndex == 0 ? "cat_weapon" : (catIndex == 1 ? "cat_armor" : "cat_potion");
double weight = (double)numWeight.Value;
int quantity = (int)numQuantity.Value;
double itemTotalWeight = weight * quantity;
// Проверка превышения лимита
if (totalWeight + itemTotalWeight > WeightLimit)
{
MessageBox.Show(GetText("msg_overflow"), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Warning);
lstLogs.Items.Add($"[SYSTEM] {GetText("msg_overflow")}");
return;
}
// Добавление в таблицу: имя, текстовое представление категории, вес, количество
dgvInventory.Rows.Add(name, GetText(catKey), weight, quantity);
totalWeight += itemTotalWeight;
ApplyLanguage(); // Обновляем статистику веса
txtItemName.Clear();
numWeight.Value = 1;
numQuantity.Value = 1;
}
// Кнопка Использовать
private void btnUse_Click(object sender, EventArgs e)
{
if (dgvInventory.SelectedRows.Count > 0)
{
DataGridViewRow row = dgvInventory.SelectedRows[0];
string itemName = row.Cells[0].Value.ToString();
double itemWeight = Convert.ToDouble(row.Cells[2].Value);
int qty = Convert.ToInt32(row.Cells[3].Value);
MessageBox.Show(string.Format(GetText("msg_used"), itemName), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Information);
lstLogs.Items.Add($"[GAME] {string.Format(GetText("msg_used"), itemName)}");
if (qty > 1)
{
row.Cells[3].Value = qty - 1;
}
else
{
dgvInventory.Rows.Remove(row);
}
totalWeight -= itemWeight;
ApplyLanguage();
}
else
{
MessageBox.Show(GetText("msg_select_item"), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
// Кнопка Удалить
private void btnDelete_Click(object sender, EventArgs e)
{
if (dgvInventory.SelectedRows.Count > 0)
{
DataGridViewRow row = dgvInventory.SelectedRows[0];
double itemWeight = Convert.ToDouble(row.Cells[2].Value);
int qty = Convert.ToInt32(row.Cells[3].Value);
totalWeight -= (itemWeight * qty);
dgvInventory.Rows.Remove(row);
ApplyLanguage();
}
else
{
MessageBox.Show(GetText("msg_select_item"), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
#endregion
}
}