ВНИМАНИЕ! Наша конференция посвящена космической тематике и компьютерным играм. Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!
|
| » [SOFT] X4:Полезный софт и модули для разработчиков | страница 1 |
|
|
|
|
Канал X4: Foundations: «[SOFT] X4:Полезный софт и модули для разработчиков» |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
Приветы всем пилотам и камрадам!
Решил я, все-таки, открыть свой топик с полезным и не очень софтом, а так же всякими мыслями по этому поводу. Думаю, хватит уже "сорить" в чужих темах )).
По мере появления чего-то такого - буду выкладывать эти вещи здесь.
С момента моей последней активности по этим вопросам (в ветке от Алексея alexusvm про Билдер) прошло довольно много времени. Кое-какие наработки я тогда начинал, но пришлось "соскочить" с темы, т.к. погряз в основных рабочих процессах..
Сейчас стали появляться свободные "окна", т.о. думаю, смогу иногда тоже поучаствовать в коллективном "ломании" игры X4 )).
Считаю, что мои разработки/мысли/советы будут полезны и другим разработчикам/игрокам.
добавлено спустя 11 минут:
И начну я, пожалуй, с небольшой утилитки для чтения параметров файлов сохранения "X4 ProfilerViewer".
Написал сегодня утром, буквально за час-полтора. Это будет задел для дальнейшей работы по теме поиска брошенных (ничейных) объектов по вселенной X4.
Особенности:
- находит вхождения папки "Save" в указанном каталоге или корневом каталоге по умолчанию "..\\Egosoft\X4\".
- в каталоге по умолчанию (или указанном) находит все "номерные" папки от стима и просматривает их на предмет наличия папки "Save".
- валидные файлы сохранений формата: "quicksave.xml" и "save_NNN.xml".
- найденные профили игроков отображаются в древовидном списке по имени профиля.
- при выделении конкретного файла сохранки из профиля в списке - справа выводится информация о данном сохранении (имя, дата/время, имя игрока, деньги, текущая локация, версия игры, стартовый сюжет, модифицированность "да/нет").
Т.е. софтина находит все профили и их сохранки, обычные стоковые и/или стим-версий.
|
Скрин (кликните здесь для просмотра)
|
К сожалению, мои прошлые наработки по теме X4 канули в лету, поэтому приходится сейчас изучать/вспоминать иерархию файлов игры X4 (CAT/DAT), что где находится и все такое. Т.е. фактически начинать с начала.
| X4 ProfileViewer.7z |
| Описание: |
| Читалка SAVE-файлов. Ver.1.0.0.1. |
|
| Имя файла: |
X4 ProfileViewer.7z |
| Размер файла: |
221.75 KB |
| Скачано: |
19 раз(а) |
Последний раз редактировалось: igorVL (19:31 04-06-2026), всего редактировалось 4 раз(а) |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
Разработал две легкие библиотеки для быстрого поиска и извлечения XML-ресурсов игры (файлы CAT/DAT).
Библиотеки могут быть подключены к любым другим проектам (C#, VB, Java ...) и выполнять функции "извлекаторов" необходимой информации из DAT-каталогов игры X4.
Суть работы следующая:
CAT-библиотека производит поиск всех значимых CAT-файлов внутри папки игры X4 и считывает их содержимое. Имеется настройка игнорирования файлов, т.е. тех CAT-файлов, читать которые не нужно (напр. 03.dat, 04.dat).
После прочтения всех найденных CAT-файлов, внутри объекта "CatDataList" содержится список объектов "CatData", в каждом из которых содержится информация о конкретной игровой модели (путь внутри DAT, имя ресурса, смещение от начала DAT-файла, размер).
Реализован метод поиска "Search()" конкретной игровой модели по ее пути и имени. Результатом поиска будет объект "CatData", содержащий необходимые сведения для извлечения этой модели из соответствующего DAT-файла.
DAT-библиотека имеет методы для бинарного чтения конкретной модели из соответствующего DAT-файла. В аргумент метода передается объект "CatData", который следует извлечь. Результат чтения - массив прочитанных байт конкретной игровой модели.
Далее, в зависимости от алгоритма текущего контекста проекта, результат можно преобразовать в различные общепринятые форматы (XML-Document, Stream, MemoryStream, string и т.п.) и использовать в своем коде.
Чтение из DAT-файла происходит "кусочно" (бинарный доступ), т.е. вычитывается конкретная часть (модель) по известному смещению и размеру. Таким образом, загружать весь километровый DAT-файл в память нет необходимости. Время доступа и извлечения необходимой информации минимально (доли сек).
добавлено спустя 33 минуты:
Попутно с разработкой вышеназванных библиотек, создается оконное приложение для их тестирования, аля "Проводник ресурсов X4":
|
Скрин X4 Resource Explorer (кликните здесь для просмотра)
|
Само это приложение, в последствии, возможно будет полезно для чего-нибудь само по себе.
Последний раз редактировалось: igorVL (19:21 01-06-2026), всего редактировалось 1 раз |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
+ Добавлены CAT/DAT DLC (extensions):
|
Cкрытый текст (кликните здесь для просмотра)
|
Последний раз редактировалось: igorVL (14:52 02-06-2026), всего редактировалось 1 раз |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
X4 Save Backup - легкий шустрый бэкапер сэйвов X4.
|
Скрины (кликните здесь для просмотра)
|
Суть работы:
Автоматически находит папки профилей игроков в указанном каталоге.
Следит за изменениями файлов "*.xml", "*.xml.gz" в папке "save" каждого пользователя, отмеченного в чек-листе.
Измененные файлы копируются по пути "профиль_пользователя\save\backup\имя_измененного_файла_дата_время\измененный_файл.xml(.gz)".
Т.е. каждый измененный (бэкап) файл находится в своей отдельной папке с именем, возрастающем по времени бэкапа.
Захваченные события отображаются в логе в окне программы. При достижении кол-ва отображаемых записей (линий) 10 (десяти) и срабатывании очередного события - лог очищается и запись становится первой.
Тема разработки этой мини-приложухи навеяна "совместной" с пилотом alexalsp работой над тулзой "X4SaveAutoBackup".
В качестве "немного отвлечься" от рутины... ))
| X4 Save Backup.7z |
| Описание: |
|
| Имя файла: |
X4 Save Backup.7z |
| Размер файла: |
475.44 KB |
| Скачано: |
15 раз(а) |
|
|
|
|
alexalsp
541 EGP
      Рейтинг канала: 14(2323) Репутация: 56 Сообщения: 4817
Зарегистрирован: 12.08.2014
 |
|
Не знаю, как кому, но я уже старый и слепой, мне на 8 шрифт смотреть тяжело 10 11 это нормально
_________________ CMDR: Fallout(EG)
ED - если застряли: https://discord.gg/yZqwPbJaCq
https://t.me/+ApizhYp4JD9kMjU6
Пользуйте мои моды как хотите.... |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
Тогда 9
|
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
| alexalsp : |
|
я уже старый и слепой
|
Я тоже не молодой, но в очках еще вижу 8-й шрифт
|
|
|
|
alexalsp
541 EGP
      Рейтинг канала: 14(2323) Репутация: 56 Сообщения: 4817
Зарегистрирован: 12.08.2014
 |
|
9 мало, это не 10 ну и почти 8+, что погоды не делает. А очки они для молодых
_________________ CMDR: Fallout(EG)
ED - если застряли: https://discord.gg/yZqwPbJaCq
https://t.me/+ApizhYp4JD9kMjU6
Пользуйте мои моды как хотите.... |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
Обновление библиотеки DatReaderLib!
По ходу разбора различных XML-ресурсов игры X4, нередко в атрибутах и узлах встречаются "ссылки" на конкретное описание объектов из библиотеки словарей (09.dat), например "name={1021,306}".
Встречая подобную ссылку, приходится "отвлекать" текущий ридер на чтение этих данных (загружать блок данных из 9.dat) и считывать текст из этой ссылки, причем согласно текущему выбранному языку.
Чтобы не "дергать" ридер туда-сюда (.Read(file, offset, size)), в библиотеку DatReaderLib добавлен новый класс DescriptionReader, который только этим и занимается, что считывает описания по ссылке из 09.dat, согласно текущему языку.
Класс имеет всего два метода:
- Инициализация (Init), куда передается путь к каталогу игры и код текущего языка, описания на котором нужно вычитывать.
- Метод чтения текста (GetText), в аргументы которого передаются значения page и id.
Метод GetText перегруженный - принимает в аргументы как ((int)page, (int)id), так и строковый вариант, каким он был получен из атрибутов XML-файла ({page,id}).
То есть, сработают оба варианта:
| Код: |
var x = reader.GetText(1021, 306);
var y = reader.GetText("{1021,306}");
|
Так же, метод GetText рекурсивный. Если в результате чтения в строке попадаются еще ссылки вида {xxx,yyy}, то все они будут извлечены и вставлены в результат.
|
Пример (кликните здесь для просмотра)
DescriptionReader инициализирован Русским языком (код = 7).
На странице <page=1021...> и <t id=306> находится текст: " 1x {20108,3001}, 1x {20108,1041}"
Считываем этот текст обоими вариантами:
| Код: |
Console.WriteLine(descriptionReader.GetText(1021, 306));
Console.WriteLine(descriptionReader.GetText("{1021,306}"));
|
Результат будет одинаков:
| Код: |
1x Расширение системы наведения Мк1, 1x Базовый сканер
1x Расширение системы наведения Мк1, 1x Базовый сканер
|
|
Таким образом, при разборе ресурсов игры, в случае "встречи" с такими ссылками - можно сразу скармливать их объекту DescriptionReader и тут же получать результат в виде нормального текста в текущей локали (выбранном языке). Без лишних телодвижений.
|
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
X4 ProfileViewer - Обновлено (версия 1.0.0.1)!
Добавлено:
- вычитка "человеческого" названия старта игры;
- вычитка текущей локации в текстовом виде;
- добавлена поддержка файлов ".gz" (сжатых);
- прочие мелкие исправления и добавления.
|
Скрин (кликните здесь для просмотра)
|
Последний раз редактировалось: igorVL (19:37 04-06-2026), всего редактировалось 2 раз(а) |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
X4ResourceExplorer (Проводник ресурсов X4) - обновление.
Библиотеки CatReaderLib и DatReaderLib дополнены.
|
Проводник теперь умеет в языки X4 (кликните здесь для просмотра)
|
|
Можно разобрать ресурсы X4 до самого последнего узла (кликните здесь для просмотра)
|
... и посмотреть содержимое каждого.
DescriptionReader теперь возвращает текст (GetText()) в "чистом" виде, т.е. без комментариев и содержимого в скобках (как это делает сама игра X4).
|
|
|
|
alexalsp
541 EGP
      Рейтинг канала: 14(2323) Репутация: 56 Сообщения: 4817
Зарегистрирован: 12.08.2014
 |
|
Это типа, давай на перегонки
Хотя мне гоняться с профи , как то бессмысленно
_________________ CMDR: Fallout(EG)
ED - если застряли: https://discord.gg/yZqwPbJaCq
https://t.me/+ApizhYp4JD9kMjU6
Пользуйте мои моды как хотите....
Последний раз редактировалось: alexalsp (22:07 04-06-2026), всего редактировалось 1 раз |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
| alexalsp : |
|
типа, давай на перегонки
|
Да ну, какие тут гонки. Просто наверстываю упущенное...
Пока есть свободное время, вот ковыряюсь. Заинтересовало как-то.
|
|
|
|
alexalsp
541 EGP
      Рейтинг канала: 14(2323) Репутация: 56 Сообщения: 4817
Зарегистрирован: 12.08.2014
 |
|
| igorVL : |
|
Если есть время и желание - подключайся к вопросу
|
Это надо ковырять сейв , этот вопрос возможно разъяснит alexusvm, он там билдер ваяет, может и с севами разбирался.
ну на вскидку , когда я ваял каталог тулз, читал про разные способы обработки больших фалов, из огромных, больше подходил для поиска ничейных кораблей - только XmlReader. Всё остальное убьёт память или будет слишком медленно. Возможно что то есть еще проще не знаю.
На вскидку предполагая что оно возможно там по своим местам ...
|
Cкрытый текст (кликните здесь для просмотра)
| Код: |
private List<AbandonedShip> FindAbandonedShips(string savePath)
{
// Результат - список найденных кораблей
var ships = new List<AbandonedShip>();
// Открываем файловый поток для чтения
using (var fs = new FileStream(savePath, FileMode.Open, FileAccess.Read, FileShare.Read))
// Распаковываем GZip (сейвы X4 всегда сжатые)
using (var gz = new GZipStream(fs, CompressionMode.Decompress))
// Создаём XML ридер с настройками для максимальной производительности
using (var reader = XmlReader.Create(gz, new XmlReaderSettings
{
IgnoreWhitespace = true, // Игнорируем пробелы и переносы строк
IgnoreComments = true, // Игнорируем комментарии
IgnoreProcessingInstructions = true // Игнорируем инструкции типа <?xml version="1.0"?>
}))
{
// Текущие контекстные данные - где мы сейчас находимся в иерархии
string currentZone = ""; // Текущая зона (внутри сектора)
string currentSector = ""; // Текущий сектор
// Читаем XML элемент за элементом (НЕ загружаем весь файл!)
while (reader.Read())
{
// Нас интересуют только открывающие теги (<sector>, <zone>, <component>)
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
// ========== ОТСЛЕЖИВАЕМ ГДЕ МЫ НАХОДИМСЯ ==========
case "sector":
// При входе в сектор - запоминаем его название или ID
// Используем name если есть, иначе id, иначе пустую строку
currentSector = reader.GetAttribute("name") ?? reader.GetAttribute("id") ?? "";
// Сбрасываем зону - новый сектор, новая иерархия
currentZone = "";
break;
case "zone":
// При входе в зону - запоминаем её название или ID
currentZone = reader.GetAttribute("name") ?? reader.GetAttribute("id") ?? "";
break;
// ========== ИЩЕМ КОРАБЛИ ==========
case "component":
// Получаем класс компонента (ship_s, ship_m, station и т.д.)
string componentClass = reader.GetAttribute("class") ?? "";
// Если это корабль (класс начинается с "ship_")
if (componentClass.StartsWith("ship_"))
{
// Проверяем владельца
string owner = reader.GetAttribute("owner") ?? "";
// Если корабль ничейный или нейтральный
if (owner == "ownerless" || owner == "neutral")
{
// Создаём запись о найденном корабле
ships.Add(new AbandonedShip
{
ShipClass = componentClass, // Тип корабля (ship_s, ship_m)
Macro = reader.GetAttribute("macro") ?? "", // Модель корабля
Owner = owner, // Владелец (ownerless/neutral)
Sector = currentSector, // В каком секторе
Zone = currentZone, // В какой зоне
// TODO: Позицию можно достать из вложенных узлов <position>
// Потребуется дополнительный парсинг или чтение дочерних элементов
});
}
}
break;
}
}
}
}
return ships;
}
// Класс для хранения информации о ничейном корабле
public class AbandonedShip
{
public string ShipClass { get; set; } // Тип: "ship_s", "ship_m", "ship_l"
public string Macro { get; set; } // Модель: "ship_xen_m_macro" и т.д.
public string Owner { get; set; } // Владелец: "ownerless", "neutral"
public string Sector { get; set; } // Название сектора
public string Zone { get; set; } // Название зоны
public Vector3 Position { get; set; } // Точные координаты (если добавить)
}
// Пример структуры для координат
public struct Vector3
{
public float X, Y, Z;
public override string ToString() => $"({X:F2}, {Y:F2}, {Z:F2})";
}
|
|
Zone = currentZone, // В какой зоне
зона тут дело такое , не понятно она есть или это просто фантомы сектора разделённые на шестигранники , с именем или без, тут надо смотреть.
как это , типа должно работать
Сейв X4 (2 ГБ)
GZipStream (распаковка на лету)
XmlReader (читает элемент за элементом, а не весь файл)
| Код: |
Читает последовательно:
<sector> запомнили название сектора
<zone> запомнили название зоны
<component class="ship_m" owner="ownerless"> НАШЛИ КОРАБЛЬ!
</component>
</zone>
</sector> |
Память: ~несколько килобайт (только текущий элемент и контекст)
Результат: список всех ничейных кораблей
В теории, но на практике , как и сказал, надо разобрать сам сейв.
_________________ CMDR: Fallout(EG)
ED - если застряли: https://discord.gg/yZqwPbJaCq
https://t.me/+ApizhYp4JD9kMjU6
Пользуйте мои моды как хотите.... |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
Поразбираюсь...
XmlReader - прошлый век. Сейчас у XML.LINQ есть инструменты получше..
| Цитата: |
| Код: |
<sector> запомнили название сектора
<zone> запомнили название зоны
<component class="ship_m" owner="ownerless"> НАШЛИ КОРАБЛЬ!
</component>
</zone>
</sector> |
|
Вот как раз <sector> - такого тега в нынешних сохранках я не вижу...
добавлено спустя 47 минут:
Провел небольшой эксперимент с XDocument...
Мда, на савке памяти жрет немало.. 3 Гига почти
|
Cкрытый текст (кликните здесь для просмотра)
|
|
код теста (.NET10) (кликните здесь для просмотра)
| Код: |
const string saveFile = @"f:\X4_Save\save\save_001.xml.gz";
XDocument xmlContent;
using (FileStream fs = new(saveFile, FileMode.Open, FileAccess.Read, FileShare.Read))
using (GZipStream gzs = new(fs, CompressionMode.Decompress))
xmlContent = XDocument.Load(gzs);
var root = xmlContent.Root;
var ownerlessNodes = FindByAttributeRecursive(root!, "owner", "ownerless");
Console.WriteLine($"Всего ничейных объектов: {ownerlessNodes.Count()}"); //319
|
| Код: |
static IEnumerable<XElement> FindByAttributeRecursive(XElement element, string attrName, string? attrValue = null)
{
XAttribute attr = element.Attribute(attrName)!;
if (attr != null && (attrValue == null || attr.Value == attrValue))
yield return element;
foreach (XElement child in element.Elements())
{
foreach (var found in FindByAttributeRecursive(child, attrName, attrValue))
yield return found;
}
}
|
|
Интересный момент: это последняя расковыренная савка (.gz) из игры. В ней нашлось 319 ничейных объектов.
В предыдущей савке (недельной давности) - таких объектов 315.
Стало быть, они рандомно добавляются/исчезают при каждом запуске игры..
добавлено спустя 41 минуту:
Upd: Вариант №2
|
код теста (кликните здесь для просмотра)
| Код: |
// Вариант №2. Поиск по двум атрибутам
var ships_m_ownLess = FindByTwoAttributesYield(root!, m => (string?)m.Attribute("owner") == "ownerless" &&
(string?)m.Attribute("class") == "ship_m");
Console.WriteLine($"Кораблей класса \"M\": {ships_m_ownLess.Count()}"); // 2
// Распечатать кусок XML с ничейными кораблями класса "М"
foreach (var node in ships_m_ownLess)
Console.WriteLine(node);
|
| Код: |
#region Var 2
static IEnumerable<XElement> FindByTwoAttributesYield(XElement root, Func<XElement, bool> predicate)
{
if (predicate(root))
yield return root;
foreach (var child in root.Elements())
{
foreach (var match in FindByTwoAttributesYield(child, predicate))
yield return match;
}
}
#endregion
|
|
Поиск по ничейным кораблям класса "М" выдал результат: 2 штуки.
|
распечатка XML-узлов с этими кораблями (кликните здесь для просмотра)
| Код: |
<component class="ship_m" macro="ship_arg_m_miner_solid_01_a_macro" connection="space" code="ZJC-958" owner="ownerless" spawntime="0" thruster="thruster_gen_m_allround_01_mk1_macro" id="[0x21b18dd]">
<listeners>
<listener listener="[0x21b978e]" event="killed" />
<listener listener="[0x21b97a3]" event="killed" />
<listener listener="[0x21b978d]" event="boostdisabled" />
</listeners>
<offset>
<rotation yaw="149.99995" pitch="-20" roll="10" />
</offset>
<render>
<parameter value="4279830786" name="letter_color" type="color" />
<parameter value="4280491810" name="number_color" type="color" />
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
<source class="script" />
<modification>
<paint ware="paintmod_0008" generated="1" />
</modification>
<gravidar />
<software wares="software_dockmk2 software_scannerlongrangemk2 software_trademk1" />
<control>
<post id="defence" component="[0x21b97a3]" />
<post id="tradecomputer" />
<post id="aipilot" />
<post id="playerpilot" />
<post id="engineer" component="[0x21b978e]" />
</control>
<ammunition>
<available>
<item macro="ship_gen_xs_lasertower_01_a_macro" amount="6" />
<item macro="env_deco_nav_beacon_t1_macro" amount="12" />
<item macro="countermeasure_flares_01_macro" amount="4" />
<item macro="eq_arg_resourceprobe_01_macro" amount="12" />
</available>
</ammunition>
<weapongroups>
<primary active="0">
<entry>
<weapon id="[0x21b978f]" />
</entry>
</primary>
<secondary active="0" />
</weapongroups>
<boost />
<stance unlocktime="0" />
<connections>
<connection connection="con_shipstorage_xs_01" macro="con_shipstorage_xs_01">
<component class="dockingbay" macro="shipstorage_gen_xs_01_macro" connection="object" id="[0x21b18b7]">
<offset default="1" />
</component>
</connection>
<connection connection="con_storage01" macro="con_storage01">
<component class="storage" macro="storage_arg_m_miner_solid_01_a_macro" connection="shipconnection" id="[0x21b97a4]">
<offset default="1" />
<render>
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
</component>
</connection>
<connection connection="con_shield_01">
<component class="shieldgenerator" macro="shield_arg_m_standard_01_mk2_macro" connection="con_shieldgen_01" id="[0x21b97a1]">
<offset>
<position x="0.03646" y="8.601" z="-10.467" />
</offset>
</component>
</connection>
<connection connection="con_cockpit" macro="con_cockpit">
<component class="cockpit" macro="cockpit_gen_virtual_01_macro" connection="ship" id="[0x21b97a2]">
<offset default="1" />
<connections>
<connection connection="entities">
<component class="computer" macro="character_defence_computer_01_macro" connection="parentconnection" code="DQQ-590" owner="ownerless" known="1" read="0" id="[0x21b97a3]">
<listeners>
<listener listener="[0x21b18dd]" event="killed" />
</listeners>
<traits flags="remotecommable">
<skills morale="6" />
</traits>
<entity type="officer" post="defence" />
</component>
</connection>
<connection connection="entities">
<component class="computer" macro="character_engineer_computer_01_macro" connection="parentconnection" code="QCK-141" owner="ownerless" known="1" read="0" id="[0x21b978e]">
<listeners>
<listener listener="[0x21b18dd]" event="killed" />
</listeners>
<traits flags="remotecommable">
<skills engineering="6" morale="6" />
</traits>
<entity type="officer" post="engineer" />
</component>
</connection>
</connections>
</component>
</connection>
<connection connection="con_primaryweapon_01">
<component class="weapon" macro="weapon_gen_m_mining_01_mk2_macro" connection="weaponcon_01" lastshottime="-4" id="[0x21b978f]">
<offset>
<position x="-19.891" y="-11.33" z="28.51" />
</offset>
<render>
<parameter flags="override" owner="[0x21b978f]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_engine_01">
<component class="engine" macro="engine_arg_m_combat_01_mk2_macro" connection="engineconnection01" id="[0x21b978d]">
<offset>
<position x="0.05738" y="0.1134" z="-50.977" />
</offset>
<render>
<parameter flags="override" owner="[0x21b978d]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_turret_02">
<component class="turret" macro="turret_arg_m_mining_01_mk1_macro" connection="con_mining_turret" lastshottime="-4" id="[0x21b9813]">
<offset>
<position x="12.704" y="0.7034" z="-10.373" />
<rotation roll="72.02296" />
</offset>
<render>
<parameter flags="override" owner="[0x21b9813]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_turret_01">
<component class="turret" macro="turret_arg_m_mining_01_mk1_macro" connection="con_mining_turret" lastshottime="-4" id="[0x21a454b]">
<offset>
<position x="-12.719" y="0.708" z="-10.373" />
<rotation roll="-72.02298" />
</offset>
<render>
<parameter flags="override" owner="[0x21a454b]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_dock_xs" macro="con_dock_xs">
<component class="dockingbay" macro="dock_gen_xs_ship_01_macro" connection="connection_component" id="[0x21b42a0]">
<offset default="1" />
<render>
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
</component>
</connection>
</connections>
</component>
<component class="ship_m" macro="ship_tel_m_frigate_01_a_macro" connection="space" code="WES-888" owner="ownerless" spawntime="0" thruster="thruster_gen_m_combat_01_mk1_macro" id="[0x2069da0]">
<listeners>
<listener listener="[0x2069da6]" event="killed" />
<listener listener="[0x2069da8]" event="killed" />
<listener listener="[0x21c607f]" event="boostdisabled" />
<listener listener="[0x21c6080]" event="boostdisabled" />
</listeners>
<offset>
<rotation yaw="15" pitch="-3" roll="-30" />
</offset>
<render>
<parameter value="4279632914" name="letter_color" type="color" />
<parameter value="4280427042" name="number_color" type="color" />
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
<source class="script" />
<modification>
<paint ware="paintmod_0008" generated="1" />
</modification>
<gravidar />
<software wares="software_scannerlongrangemk2 software_scannerobjectmk2 software_trademk1" />
<control>
<post id="defence" component="[0x2069da6]" />
<post id="tradecomputer" />
<post id="aipilot" />
<post id="playerpilot" />
<post id="engineer" component="[0x2069da8]" />
</control>
<ammunition>
<available>
<item macro="weapon_gen_mine_03_macro" amount="4" />
<item macro="ship_gen_s_lasertower_01_a_macro" amount="4" />
<item macro="ship_gen_xs_lasertower_01_a_macro" amount="4" />
<item macro="weapon_gen_mine_01_macro" amount="10" />
<item macro="weapon_gen_mine_02_macro" amount="4" />
<item macro="countermeasure_flares_01_macro" amount="5" />
</available>
</ammunition>
<weapongroups>
<primary active="0">
<entry>
<weapon id="[0x2069da3]" />
<weapon id="[0x2069da4]" />
</entry>
</primary>
<secondary active="0" />
</weapongroups>
<boost />
<stance unlocktime="0" />
<connections>
<connection connection="con_shipstorage_xs_01" macro="con_shipstorage_xs_01">
<component class="dockingbay" macro="shipstorage_gen_xs_01_macro" connection="object" id="[0x2069da2]">
<offset default="1" />
</component>
</connection>
<connection connection="con_storage01" macro="con_storage01">
<component class="storage" macro="storage_tel_m_frigate_01_a_macro" connection="shipconnection" id="[0x2069da5]">
<offset default="1" />
<render>
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
</component>
</connection>
<connection connection="con_cockpit" macro="con_cockpit">
<component class="cockpit" macro="cockpit_gen_virtual_01_macro" connection="ship" id="[0x2069daa]">
<offset default="1" />
<connections>
<connection connection="entities">
<component class="computer" macro="character_defence_computer_01_macro" connection="parentconnection" code="RMG-072" owner="ownerless" known="1" read="0" id="[0x2069da6]">
<listeners>
<listener listener="[0x2069da0]" event="killed" />
</listeners>
<traits flags="remotecommable">
<skills morale="6" />
</traits>
<entity type="officer" post="defence" />
</component>
</connection>
<connection connection="entities">
<component class="computer" macro="character_engineer_computer_01_macro" connection="parentconnection" code="KSZ-091" owner="ownerless" known="1" read="0" id="[0x2069da8]">
<listeners>
<listener listener="[0x2069da0]" event="killed" />
</listeners>
<traits flags="remotecommable">
<skills engineering="6" morale="6" />
</traits>
<entity type="officer" post="engineer" />
</component>
</connection>
</connections>
</component>
</connection>
<connection connection="con_primaryweapon_02">
<component class="weapon" macro="weapon_gen_m_plasma_01_mk2_macro" connection="weaponcon_01" lastshottime="0" id="[0x2069da3]">
<offset>
<position x="25.552" y="-17.967" z="43.667" />
</offset>
<render>
<parameter flags="override" owner="[0x2069da3]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_primaryweapon_01">
<component class="weapon" macro="weapon_gen_m_beam_01_mk2_macro" connection="weaponcon_01" lastshottime="-4" id="[0x2069da4]">
<offset>
<position x="-25.456" y="-17.967" z="43.656" />
</offset>
<render>
<parameter flags="override" owner="[0x2069da4]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_shield_back_r">
<component class="shieldgenerator" macro="shield_arg_m_standard_01_mk2_macro" connection="con_shieldgen_01" id="[0x2069da1]">
<offset>
<position x="34.691" y="5.383" z="1.042" />
<rotation roll="90.00001" />
</offset>
</component>
</connection>
<connection connection="con_shipstorage_s_01" macro="con_shipstorage_s_01">
<component class="dockingbay" macro="shipstorage_gen_s_frigate_01_macro" connection="object" id="[0x21bcad7]">
<offset default="1" />
</component>
</connection>
<connection connection="con_shield_l">
<component class="shieldgenerator" macro="shield_arg_m_standard_01_mk1_macro" connection="con_shieldgen_01" id="[0x21bcae3]">
<offset>
<position x="-34.691" y="5.383" z="1.042" />
<rotation yaw="-179.99989" roll="90.00001" />
</offset>
</component>
</connection>
<connection connection="con_shield_b">
<component class="shieldgenerator" macro="shield_arg_m_standard_01_mk2_macro" connection="con_shieldgen_01" id="[0x21c2c12]">
<offset>
<position y="-19.372" z="-0.5129" />
<rotation roll="-179.99989" />
</offset>
</component>
</connection>
<connection connection="con_engine_02">
<component class="engine" macro="engine_arg_m_combat_01_mk2_macro" connection="engineconnection01" id="[0x21c6080]">
<offset>
<position x="0.005395" y="-4.273" z="-58.463" />
</offset>
<render>
<parameter flags="override" owner="[0x21c6080]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_engine_01">
<component class="engine" macro="engine_arg_m_combat_01_mk2_macro" connection="engineconnection01" id="[0x21c607f]">
<offset>
<position x="0.005395" y="11.395" z="-58.463" />
</offset>
<render>
<parameter flags="override" owner="[0x21c607f]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_dockarea_arg_s_ship_01" macro="con_dockarea_arg_s_ship_01">
<component class="dockarea" macro="dockarea_arg_s_ship_01_macro" connection="connection01" id="[0x21c607e]">
<offset default="1" />
<render>
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
<connections>
<connection connection="connectionfor_dockingbay_arg_s_01_macro" macro="connectionfor_dockingbay_arg_s_01_macro">
<component class="dockingbay" macro="dockingbay_arg_s_01_macro" connection="position" id="[0x21c607d]">
<render>
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
</component>
</connection>
</connections>
</component>
</connection>
<connection connection="con_turret_tb">
<component class="turret" macro="turret_arg_m_gatling_01_mk1_macro" connection="con_gatling_turret" lastshottime="0" ammunition="15" id="[0x21c607c]">
<offset>
<position y="17.103" z="-18.618" />
<rotation yaw="179.99989" />
</offset>
<render>
<parameter flags="override" owner="[0x21c607c]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_turret_tf">
<component class="turret" macro="turret_arg_m_gatling_01_mk1_macro" connection="con_gatling_turret" lastshottime="0" ammunition="15" id="[0x21c607b]">
<offset>
<position y="16.582" z="48.115" />
</offset>
<render>
<parameter flags="override" owner="[0x21c607b]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_dock_xs" macro="con_dock_xs">
<component class="dockingbay" macro="dock_gen_xs_ship_01_macro" connection="connection_component" id="[0x21c607a]">
<offset default="1" />
<render>
<parameter value="assets\textures\ui\factions\faction_ownerless_diffhq" name="diffuse_map" type="texture" />
</render>
</component>
</connection>
<connection connection="con_turret_l">
<component class="turret" macro="turret_arg_m_gatling_01_mk1_macro" connection="con_gatling_turret" lastshottime="0" ammunition="15" id="[0x21c6079]">
<offset>
<position x="-35.649" y="5.584" z="35.486" />
<rotation yaw="-90.00001" pitch="-70.00002" />
</offset>
<render>
<parameter flags="override" owner="[0x21c6079]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
<connection connection="con_turret_r">
<component class="turret" macro="turret_arg_m_gatling_01_mk1_macro" connection="con_gatling_turret" lastshottime="0" ammunition="15" id="[0x21c6078]">
<offset>
<position x="35.85" y="5.161" z="35.486" />
<rotation yaw="-90.00001" pitch="70.00002" />
</offset>
<render>
<parameter flags="override" owner="[0x21c6078]" name="mat_dynamicglow" type="glow">
<persistent interval="0" />
</parameter>
</render>
</component>
</connection>
</connections>
</component>
|
|
В общем и в целом: файл сэйва загружается, конечно, сравнительно "долго" (секунд 10-15 на моем ПК), занимает памяти прилично, но работает поиск и вычитка интересующих итемов шустро.
Т.е. здесь имеем некий компромисс - между долгой загрузкой и памятью, но быстрым поиском нужного VS быстрое чтение, но сложный разбор результата.
Последний раз редактировалось: igorVL (01:21 05-06-2026), всего редактировалось 2 раз(а) |
|
|
|
alexalsp
541 EGP
      Рейтинг канала: 14(2323) Репутация: 56 Сообщения: 4817
Зарегистрирован: 12.08.2014
 |
|
X4AbandonedShip
Типа такое - просто черновик .
ептель 5 утра , засиделся.
|
Cкрытый текст (кликните здесь для просмотра)
|
| X4AbandonedShip.rar |
| Описание: |
|
| Имя файла: |
X4AbandonedShip.rar |
| Размер файла: |
3.81 MB |
| Скачано: |
12 раз(а) |
_________________ CMDR: Fallout(EG)
ED - если застряли: https://discord.gg/yZqwPbJaCq
https://t.me/+ApizhYp4JD9kMjU6
Пользуйте мои моды как хотите....
Последний раз редактировалось: alexalsp (04:10 05-06-2026), всего редактировалось 1 раз |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
| alexalsp : |
|
X4AbandonedShip
|
Работает!
Найденное соответствует моему консольному поисковику (корабли и их коды).
Я тогда не буду свой оконный вариант писать - твою подправлю, и считай поисковик ничейного готов!
|
|
|
|
alexalsp
541 EGP
      Рейтинг канала: 14(2323) Репутация: 56 Сообщения: 4817
Зарегистрирован: 12.08.2014
 |
|
Если так тогда
1) Надо сделать выбор языка текстов, на каком отображать данные.
2) можно вообще постоянные данные раскидать каждый по своим конфигам. что бы из них локально бралось. как у секторов. раз парсанул и больше не трогаешь пока какой та мод на корабли станции или сектора не добавился в игру.
3) Еще я думал доделать привязку к макросам кораблей текста из текстовика. Тоже распарсить все macro кораблей в джесон как у секторов. Ибо в савке не у всех есть идентификаторы текста, а если уж делать, то надо просто всем присвоить из текстовиков.
все кордабли лежат в папках
X4 Foundations\assets\units\
а там нужна папка macros и вытягивание с них идентификаторы текста
<identification name="{20101,11002}"
жто уже есть для секторов просто добавить тип
ship_***_macro
и думаю нам нужны не все корабли а только XL L и S(хотя и он под вопросом) толку от них ноль )) Ну или не борзеть и все искать, а там каждый себе решит , что с этим делать.
_________________ CMDR: Fallout(EG)
ED - если застряли: https://discord.gg/yZqwPbJaCq
https://t.me/+ApizhYp4JD9kMjU6
Пользуйте мои моды как хотите....
Последний раз редактировалось: alexalsp (12:10 05-06-2026), всего редактировалось 1 раз |
|
|
|
igorVL
64 EGP Рейтинг канала: 5(208) Репутация: 2 Сообщения: 220
Зарегистрирован: 04.08.2023
 |
|
1) можно добавить (загружать) языки X4, если каталог игры корректен.
2) Сектора вижу - загружаются и сохраняются в джсон. В остальное надо вникнуть, что там к чему и где берется..
3) Тоже пока не совсем понимаю..
|
Cкрытый текст (кликните здесь для просмотра)
|
|
Cкрытый текст (кликните здесь для просмотра)
|
Последний раз редактировалось: igorVL (12:30 05-06-2026), всего редактировалось 1 раз |
|
|
|
alexalsp
541 EGP
      Рейтинг канала: 14(2323) Репутация: 56 Сообщения: 4817
Зарегистрирован: 12.08.2014
 |
|
Что бы не играться с этими попытками чтения в катах, тем более я так и не смог понять как из 01 ката внуть данные, он 10 гигов, можно просто тупо консольный каталогтулз взять , распаковать во временную папку только нужные фалы, распарсить их, создать джесоны и использовать в именовании.
Файлы есть в 01 , но я так и не смог вынуть, толи там сжатие другое, толи просто размер большой , хз короче.
Как вариант можно попробовать родной каталог тулз.
_________________ CMDR: Fallout(EG)
ED - если застряли: https://discord.gg/yZqwPbJaCq
https://t.me/+ApizhYp4JD9kMjU6
Пользуйте мои моды как хотите....
Последний раз редактировалось: alexalsp (17:14 05-06-2026), всего редактировалось 1 раз |
|
|
|
|
|
|
|
|
Канал X4: Foundations: «[SOFT] X4:Полезный софт и модули для разработчиков» |
|
|
| К списку каналов | Наверх страницы |
Цитата не в тему: Мы же никого не заставляем рыбок мочить... Хотя чешуя красиво разлетается... (Garmahis)
|
| » [SOFT] X4:Полезный софт и модули для разработчиков | страница 1 |
|