Elite Games - Свобода среди звезд!
.
ВНИМАНИЕ!
Наша конференция посвящена космической тематике и компьютерным играм.
Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!

  » [SOFT] X4:Полезный софт и модули для разработчиков | страница 1
Конференция предназначена для общения пилотов. Для удобства она разделена на каналы, каждый из которых посвящен определенной игре. Пожалуйста, открывайте темы только в соответствующих каналах и после того, как убедитесь, что данный вопрос не обсуждался ранее.

Поиск | Правила конференции | Фотоальбом | Регистрация | Список пилотов | Профиль | Войти и проверить личные сообщения | Вход

   Страница 1 из 2
На страницу: 1, 2  След. | Все страницы
Поиск в этой теме:
Канал 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
 Скачано:  18 раз(а)


Последний раз редактировалось: igorVL (19:31 04-06-2026), всего редактировалось 4 раз(а)
    Добавлено: 20:00 30-05-2026   
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 раз
    Добавлено: 19:21 01-06-2026   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
+ Добавлены CAT/DAT DLC (extensions):
 Cкрытый текст   (кликните здесь для просмотра)


Последний раз редактировалось: igorVL (14:52 02-06-2026), всего редактировалось 1 раз
    Добавлено: 14:52 02-06-2026   
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
 Имя файла:  X4 Save Backup.7z
 Размер файла:  475.44 KB
 Скачано:  15 раз(а)
    Добавлено: 00:14 03-06-2026   
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

Пользуйте мои моды как хотите....
    Добавлено: 01:54 03-06-2026   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
Тогда 9 Хы...
    Добавлено: 10:13 03-06-2026   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
alexalsp :
я уже старый и слепой

Я тоже не молодой, но в очках еще вижу 8-й шрифт Улыбка
    Добавлено: 11:37 03-06-2026   
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

Пользуйте мои моды как хотите....
    Добавлено: 11:42 03-06-2026   
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 и тут же получать результат в виде нормального текста в текущей локали (выбранном языке). Без лишних телодвижений. Улыбка
    Добавлено: 01:34 04-06-2026   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
X4 ProfileViewer - Обновлено (версия 1.0.0.1)!

Добавлено:
- вычитка "человеческого" названия старта игры;
- вычитка текущей локации в текстовом виде;
- добавлена поддержка файлов ".gz" (сжатых);
- прочие мелкие исправления и добавления.
 Скрин   (кликните здесь для просмотра)


Последний раз редактировалось: igorVL (19:37 04-06-2026), всего редактировалось 2 раз(а)
    Добавлено: 19:35 04-06-2026   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
X4ResourceExplorer (Проводник ресурсов X4) - обновление.
Библиотеки CatReaderLib и DatReaderLib дополнены.

 Проводник теперь умеет в языки X4   (кликните здесь для просмотра)

 Можно разобрать ресурсы X4 до самого последнего узла   (кликните здесь для просмотра)

... и посмотреть содержимое каждого.

DescriptionReader теперь возвращает текст (GetText()) в "чистом" виде, т.е. без комментариев и содержимого в скобках (как это делает сама игра X4).
    Добавлено: 22:01 04-06-2026   
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 раз
    Добавлено: 22:05 04-06-2026   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
alexalsp :
типа, давай на перегонки

Да ну, какие тут гонки. Просто наверстываю упущенное... Улыбка
Пока есть свободное время, вот ковыряюсь. Заинтересовало как-то.
    Добавлено: 22:26 04-06-2026   
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

Пользуйте мои моды как хотите....
    Добавлено: 23:44 04-06-2026   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
alexalsp :

Поразбираюсь...
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 раз(а)
    Добавлено: Вчера в 1:21   
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 раз
    Добавлено: Вчера в 4:07   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
alexalsp :
X4AbandonedShip

Работает! Улыбка
Найденное соответствует моему консольному поисковику (корабли и их коды).
Я тогда не буду свой оконный вариант писать - твою подправлю, и считай поисковик ничейного готов!
    Добавлено: Вчера в 11:02   
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 раз
    Добавлено: Вчера в 12:02   
igorVL
 64 EGP

Рейтинг канала: 5(208)
Репутация: 2
Сообщения: 220

Зарегистрирован: 04.08.2023
1) можно добавить (загружать) языки X4, если каталог игры корректен.
2) Сектора вижу - загружаются и сохраняются в джсон. В остальное надо вникнуть, что там к чему и где берется..
3) Тоже пока не совсем понимаю..

 Cкрытый текст   (кликните здесь для просмотра)

 Cкрытый текст   (кликните здесь для просмотра)


Последний раз редактировалось: igorVL (12:30 05-06-2026), всего редактировалось 1 раз
    Добавлено: Вчера в 12:27   
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 раз
    Добавлено: Вчера в 17:13   
Канал X4: Foundations: «[SOFT] X4:Полезный софт и модули для разработчиков»
На страницу: 1, 2  След. | Все страницы
  
Показать: 
Предыдущая тема | Следующая тема |
К списку каналов | Наверх страницы
Цитата не в тему: Админов исправить нельзя, т.к. это критическое приложение. Можно только переставить, или заменить. (обьяснил Alone.)

  » [SOFT] X4:Полезный софт и модули для разработчиков | страница 1
Каналы: Новости | Elite | Elite: Dangerous | Freelancer | Star Citizen | X-Tension/X-BTF | X2: The Threat | X3: Reunion | X3: Terran Conflict | X Rebirth | X4: Foundations | EVE Online | Orbiter | Kerbal Space Program | Evochron | VoidExpanse | Космические Миры | Онлайновые игры | Другие игры | Цифровая дистрибуция | play.elite-games.ru | ЗВ 2: Гражданская война | Творчество | Железо | Игра Мечты | Сайт
   Дизайн Elite Games V5 beta.18