• Из-за обновления GTA 5 (был добавлен новый патч) может временно не работать вход в RAGE Multiplayer.

    Ошибка: Ваша версия Grand Theft Auto V не поддерживается RAGE Multiplayer.
    ERROR: Your game version is not supported by RAGE Multiplayer.

    Данная ошибка говорит о том, что GTA V обновилась до новой версии (GTA Online тоже). Вам необходимо обновить саму игру в главном меню вашего приложения (Steam / Epic Games / Rockstar Games).
    Если после этого RAGE:MP все равно не работает - вам нужно дождаться выхода патча для самого мультиплеера (обычно это занимает от нескольких часов до нескольких дней).

    Новости и апдейты Rockstar Games - https://www.rockstargames.com/newswire/
    Статус всех служб для Rockstar Games Launcher и поддерживаемых игр: https://support.rockstargames.com/ru/servicestatus


    Grand Theft Auto 5 (+ GTA Online) последний раз были обновлены:

Проблема Не понятки с RageLib c#

b0rov

Новый участник
16 Янв 2025
6
0
3
не могу открыть rpf архив не выкупаю что не так


C#:
using System;
using System.IO;
using RageLib.Archives;
using RageLib.GTA5.Archives;
using RageLib.GTA5.Cryptography;
using RageLib.GTA5.Utilities;
using RageLib.Cryptography;

public class RpfReader
{
    public static void Main(string[] args)
    {
        string rpfFilePath = "D:/SteamLibrary/steamapps/common/Grand Theft Auto V/mods/x64e.rpf";
        
        Console.WriteLine($"File path: {rpfFilePath}");
        
        try
        {
            // Инициализируем ключи на основе анализа DLL
            InitializeKeys();

            // Проверяем инициализацию
            if (GTA5Constants.PC_NG_KEYS == null || GTA5Constants.PC_NG_DECRYPT_TABLES == null)
            {
                Console.WriteLine("Ошибка: Не удалось инициализировать ключи");
                return;
            }

            Console.WriteLine("Ключи успешно инициализированы");
            Console.WriteLine($"Количество NG ключей: {GTA5Constants.PC_NG_KEYS.Length}");

            using (var stream = File.OpenRead(rpfFilePath))
            {
                Console.WriteLine($"Размер файла: {stream.Length:N0} bytes");
                Console.WriteLine("Открываем архив с NG шифрованием...");
                
                try
                {
                    var archive = new RageArchive7(stream, true);
                    if (archive.Root != null)
                    {
                        ProcessDirectory(archive.Root, "");
                    }
                    else
                    {
                        Console.WriteLine("Ошибка: Корневой каталог архива не найден");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Ошибка при открытии архива: {ex.Message}");
                    Console.WriteLine($"StackTrace: {ex.StackTrace}");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Произошла ошибка: {ex.Message}");
            Console.WriteLine($"StackTrace: {ex.StackTrace}");
        }
    }

    private static void InitializeKeys()
    {
        // AES ключ из анализа DLL
        var aesKey = new byte[]
        {
            0x28, 0xCA, 0x2E, 0xFF, 0x09, 0xF6, 0x0D, 0xA3,
            0x39, 0x06, 0x31, 0x79, 0x27, 0x92, 0xC3, 0x7A,
            0x24, 0x99, 0xF2, 0x95, 0xD4, 0x00, 0xF4, 0x00,
            0x52, 0xA0, 0x40, 0xB1, 0xD7, 0xD0, 0xAC, 0x03
        };
        GTA5Constants.PC_AES_KEY = aesKey;

        // NG ключ (полные 256 байт)
        var ngKey = new byte[256];
        var baseKey = new byte[]
        {
            0xB1, 0x51, 0x81, 0x7B, 0xCC, 0xA7, 0xED, 0xAE,
            0x23, 0xA8, 0x6D, 0x03, 0x8B, 0x7E, 0x43, 0x2F,
            0x66, 0x6A, 0x4B, 0x2B, 0x6E, 0x61, 0x9D, 0xC0,
            0xBE, 0x5F, 0x61, 0x72, 0x3D, 0x74, 0xEF, 0x1F,
            0x4F, 0x06, 0x4A, 0x02, 0x4E, 0xE6, 0xA0, 0x18,
            0x97, 0xC4, 0x49, 0xE8, 0xD6, 0xB0, 0xE8, 0x75,
            0xB1, 0xD4, 0x49, 0x0A, 0x4E, 0x89, 0x3E, 0x9C,
            0x0F, 0x03, 0xE2, 0xEB, 0x35, 0x06, 0x10, 0xC5,
            0xB0, 0xA9, 0x8C, 0x27, 0xF6, 0x7E, 0xDE, 0x86,
            0xF3, 0xDC, 0xE0, 0xE9, 0xCC, 0xE4, 0x91, 0xC3,
            0x6A, 0xAB, 0x23, 0xA0, 0xFA, 0x3D, 0x97, 0xBA,
            0x8B, 0x8B, 0xE6, 0xA3, 0xD4, 0x46, 0x82, 0x40,
            0x29, 0xE8, 0xDB, 0x9D, 0xDA, 0xED, 0x4A, 0x28,
            0x44, 0x93, 0x71, 0x3F, 0x44, 0x03, 0xF4, 0x20,
            0x06, 0x4F, 0x7D, 0x68, 0x22, 0x8A, 0xAE, 0x56,
            0x06, 0xE0, 0xCC, 0xCF, 0xBB, 0x9D, 0x72, 0x70
        };

        // Копируем базовый ключ и расширяем его до 256 байт
        Buffer.BlockCopy(baseKey, 0, ngKey, 0, baseKey.Length);
        for (int i = baseKey.Length; i < 256; i++)
        {
            ngKey[i] = (byte)(baseKey[i % baseKey.Length] ^ 0x37);
        }

        var ngKeys = new byte[1][];
        ngKeys[0] = ngKey;
        GTA5Constants.PC_NG_KEYS = ngKeys;

        // Инициализируем таблицы расшифровки
        var decryptTables = new uint[1][][];
        decryptTables[0] = new uint[1][];
        decryptTables[0][0] = new uint[69632];

        // Заполняем таблицы на основе анализа DLL
        for (int i = 0; i < 69632; i++)
        {
            int tableIndex = i % 256;
            uint value = (uint)(tableIndex ^ ngKey[tableIndex]);
            // Повторяем значение в каждом байте
            value = (value << 24) | (value << 16) | (value << 8) | value;
            decryptTables[0][0][i] = value;
        }

        GTA5Constants.PC_NG_DECRYPT_TABLES = decryptTables;

        // Создаем экземпляр криптографии
        var crypto = new GTA5Crypto();

        Console.WriteLine($"AES Key Size: {aesKey.Length} bytes");
        Console.WriteLine($"NG Key Size: {ngKey.Length} bytes");
        Console.WriteLine($"Decrypt Tables Size: {decryptTables[0][0].Length * 4} bytes");
        Console.WriteLine($"First decrypt table value: 0x{decryptTables[0][0][0]:X8}");
    }

    static void ProcessDirectory(RageArchiveDirectory7 directory, string indent)
    {
        if (directory == null) return;

        Console.WriteLine($"{indent}Directory: {directory.Name}");

        if (directory.Files != null)
        {
            foreach (var file in directory.Files)
            {
                if (file == null) continue;
                
                if (file is IRageArchiveFileEntry7 fileEntry)
                {
                    Console.WriteLine($"{indent}  File: {fileEntry.Name}");
                    Console.WriteLine($"{indent}    Size: {fileEntry.FileSize:N0} bytes");
                    Console.WriteLine($"{indent}    Offset: {fileEntry.FileOffset:N0}");
                    
                    // Проверяем, является ли файл бинарным через интерфейс IArchiveBinaryFile
                    if (file is IArchiveBinaryFile binaryFile)
                    {
                        Console.WriteLine($"{indent}    Encrypted: {binaryFile.IsEncrypted}");
                        Console.WriteLine($"{indent}    Compressed: {binaryFile.IsCompressed}");
                        if (binaryFile.IsCompressed)
                        {
                            Console.WriteLine($"{indent}    Uncompressed Size: {binaryFile.UncompressedSize:N0} bytes");
                            Console.WriteLine($"{indent}    Compressed Size: {binaryFile.CompressedSize:N0} bytes");
                        }
                    }
                }
                else
                {
                    Console.WriteLine($"{indent}  File: {file.Name} (Unknown type)");
                }
            }
        }

        if (directory.Directories != null)
        {
            foreach (var dir in directory.Directories)
            {
                ProcessDirectory(dir, indent + "  ");
            }
        }
    }
}

1737026047437.png
 

Jerry (ChatGPT)

AI-powered language model
VIP
helper
17 Окт 2023
2,256
233
5
Похоже, что ваш код имеет все необходимые компоненты для открытия RPF-архива с использованием NG шифрования. Возможно, проблема связана с путем к файлу x64e.rpf. Убедитесь, что путь указан верно и доступен для чтения. Если проблема остается, попробуйте проверить другие возможные ошибки в коде или настройках окружения.
 

b0rov

Новый участник
16 Янв 2025
6
0
3
Похоже, что ваш код имеет все необходимые компоненты для открытия RPF-архива с использованием NG шифрования. Возможно, проблема связана с путем к файлу x64e.rpf. Убедитесь, что путь указан верно и доступен для чтения. Если проблема остается, попробуйте проверить другие возможные ошибки в коде или настройках окружения.
код не выдаёт не каких предупреждений при компиляции и окружение верно настроенно я просто не понимаю почему он не может открыть архив суть кода на данном этапе просто в консоль вывести что внутри архива
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,780
1,580
211
28
Чисто предположение:
У приложения, которое ты запускаешь, достаточно прав на взаимодействие с файлами (иными словами - ты запускаешь приложение от администратора)?
 

Inoi

/dev/null
Команда форума
Moderator
VIP
15 Окт 2020
3,818
1,873
208
35
у тебя и не должно быть никаких ошибок сборки, ты же буквально попадаешь в своё же исключение
ну или того, кто написал этот код

Код:
var archive = new RageArchive7(stream, true);
                    if (archive.Root != null)
                    {
                        ProcessDirectory(archive.Root, "");
                    }
                    else
                    {
                        Console.WriteLine("Ошибка: Корневой каталог архива не найден");
                    }

очевидно что archive.Root у тебя видимо null

так как судя по выводам в консоли сам файл твой код видит и находит, то

если вот это - https://github.com/Neodymium146/gta-toolkit/blob/master/RageLib.GTA5/Archives/RageArchive7.cs
код библиотеки, которую ты используешь (у меня это просто первый результат в гугле по поиску RageLib.Archives, которую ты using)
то из её кода видно, что свойство Root не инициализируется автоматически при создании объекта, а заполняется в методе ReadHeader

1737027814960.png

1737027837351.png


сам конструктор RageArchive7 - его не инициализирует.

В твоём коде я не вижу вызова метода ReadHeader, который бы инициализировал структура архива и заполнил свойство root.
Подозреваю, что если это верная библиотека, то проблема именно в этом, и именно поэтому у тебя archive.Root - Null.

Видимо тебе нужно что то вроде
Код:
archive.ReadHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[0]);
Опять таки если верить коду на гите где ReadHeader принимает эти два параметра, а в твоём коде в массиве ключей - он один.
 
Реакции: XDeveluxe

b0rov

Новый участник
16 Янв 2025
6
0
3
у тебя и не должно быть никаких ошибок сборки, ты же буквально попадаешь в своё же исключение
ну или того, кто написал этот код

Код:
var archive = new RageArchive7(stream, true);
                    if (archive.Root != null)
                    {
                        ProcessDirectory(archive.Root, "");
                    }
                    else
                    {
                        Console.WriteLine("Ошибка: Корневой каталог архива не найден");
                    }

очевидно что archive.Root у тебя видимо null

так как судя по выводам в консоли сам файл твой код видит и находит, то

если вот это - https://github.com/Neodymium146/gta-toolkit/blob/master/RageLib.GTA5/Archives/RageArchive7.cs
код библиотеки, которую ты используешь (у меня это просто первый результат в гугле по поиску RageLib.Archives, которую ты using)
то из её кода видно, что свойство Root не инициализируется автоматически при создании объекта, а заполняется в методе ReadHeader

Посмотреть вложение 17893
Посмотреть вложение 17894

сам конструктор RageArchive7 - его не инициализирует.

В твоём коде я не вижу вызова метода ReadHeader, который бы инициализировал структура архива и заполнил свойство root.
Подозреваю, что если это верная библиотека, то проблема именно в этом, и именно поэтому у тебя archive.Root - Null.

Видимо тебе нужно что то вроде
Код:
archive.ReadHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[0]);
Опять таки если верить коду на гите где ReadHeader принимает эти два параметра, а в твоём коде в массиве ключей - он один.
можно узнать твой телеграм ?
 

Inoi

/dev/null
Команда форума
Moderator
VIP
15 Окт 2020
3,818
1,873
208
35