Перейти к содержимому
Zone of Games Forum

Рекомендованные сообщения

По переводу

Хитрые Япошки спрятали текст да ещё и зашифровали. Мне удалось найти лазейку, но игру всё равно нужно пройти всю. т.к. функция дёргает текст и сохраняет в файл  для его последующего перевода через нейронку, так что прохождение всей игры обязательно, иначе текст игры не весь будет... и вставка будет такой же хитрой. не будет текст друг на друга наползать, да и качество лучше будет . если есть желающие видеть сие творение в нормальном переводе и хотят помочь - нужно пройти игру на англ.яз. что бы вытянуть весь текст, то милости прошу в Лы Сы.
 
п.с. и да, в их мире это реально такая дыня а не арбуз)))
 
_7c7d08f1bc880701bf62db5228318707.jpg?md
Märchen Forest — это чарующая и обманчиво глубокая сказка, которая начинается как солнечная прогулка, а превращается в эпическое испытание духа. Это путешествие, где за милыми улыбками лесных обитателей скрываются древние тайны, а под корнями уютного леса дремлют мрачные лабиринты прошлого.
 
Легенда о юной алхимице
Вы берете на себя роль очаровательной Милн — внучки лесного мастера зелий. Ваша история начинается в идиллическом уголке мира, залитом мягким светом, где главной заботой кажется поиск редкого гриба или помощь говорящему пингвину. Но не позволяйте этой пасторальной идиллии усыпить вашу бдительность.
 
Игра контрастов: От света к тени
Märchen Forest уникальна своей структурой. Она подобна театральной пьесе в трех актах, где декорации меняются до неузнаваемости:
  • Акт I: Улыбки леса. Исследуйте живописные локации, собирайте ингредиенты и решайте забавные головоломки. Это время магии, дружбы и алхимии.
  • Акт II и III: Бездна руин. Атмосфера резко меняется. Солнечный свет сменяется факелами подземелий. Здесь игра превращается в суровый Dungeon Crawler. Вам предстоит столкнуться с тьмой, голодом и опасными монстрами, полагаясь лишь на свой клинок, вовремя поставленный блок и стратегическое мышление.
 
Искусство боя и магия
Боевая система требует от игрока не только силы, но и грации. Динамичные сражения завязаны на чувстве ритма: одно точное парирование может решить исход битвы. С каждым шагом вглубь подземелий ставки растут, а сюжет обрастает драматическими деталями, превращаясь из детской сказки в серьезное фэнтези.
 
Почему стоит погрузиться в этот мир?
  • Визуальный стиль: Очаровательная эстетика в духе классических аниме-сказок.
  • Непредсказуемость: Вы никогда не знаете, какой сюрприз преподнесет сюжет за следующим поворотом лабиринта.
  • Атмосфера: Потрясающий саундтрек, который подчеркивает переход от беззаботности к леденящему душу напряжению.
 
Märchen Forest — это напоминание о том, что даже у самых маленьких героев бывают великие и опасные судьбы. Готовы ли вы заглянуть за грань лесной опушки и узнать, что скрывает тишина подземелий?
 
Скачать - Гугл диск
 
Скрытый текст

_7c7d08f1bc880701bf62db5228318707.jpeg _a772b1bd48eba98976acb2fda4362b60.jpeg _073f6d6b1bebc683d00aa01b828e8f9d.jpeg _18a2ae51e8b3434087a358bc42f3878a.jpeg _1c28b58852fee8c366b2ca5fca04057c.jpeg _585c13141d5a641523fe2e1a3c458756.jpeg _ff8e592223fc089d8b16cd78f14c5d07.jpeg _d4df463e186e4e57e406527a1bdf5533.jpeg _9f37d360112576748bdc42f1d49f0403.jpeg _d4bb895ef132c6395e0e649c34cdefe0.jpeg _0e6fba4ced3f8699adafc6a5857b64d6.jpeg _07725b00c66877169c82c166835c3c2e.jpeg

 

Изменено пользователем KetsuNeko

Поделиться сообщением


Ссылка на сообщение
3 часа назад, KetsuNeko сказал:

... и главное - интерес к проекту...

... но как по мне - игра не стоит потраченного времени которого у меня и так нет….

Хм… 

Поделиться сообщением


Ссылка на сообщение
2 часа назад, parabelum сказал:

Хм… 

слова из контекста вырывать не нужно. ты же понял о чём я. если нет то поясню — нет времени искать ключи к зашифрованному тексту, так как это очень сложно и долго.  

Поделиться сообщением


Ссылка на сообщение
2 часа назад, KetsuNeko сказал:

слова из контекста вырывать не нужно. ты же понял о чём я. если нет то поясню — нет времени искать ключи к зашифрованному тексту, так как это очень сложно и долго.  

Дружище, я больше на это обратил внимание “игра не стоит потраченного времени”.

Просто если мне проект не нравиться, я за него не берусь.

Поделиться сообщением


Ссылка на сообщение

Да что там искать то.
Алгоритм: Rijndael (AES) с BlockSize=256
Режим: CBC
1. Base64 decode
2. AES decrypt

Ключи:
 

// PROJECT_KEY (32 байта):
{ 219, 213, 3, 55, 151, 160, 65, 59, 242, 96,
  31, 17, 243, 131, 158, 221, 122, 115, 147, 122,
  205, 191, 88, 227, 80, 100, 140, 248, 78, 102,
  60, 234 }

// PROJECT_IV (32 байта):
{ 81, 195, 46, 43, 97, 91, 5, 227, 111, 244,
  215, 186, 50, 37, 107, 101, 5, 187, 155, 119,
  95, 250, 46, 209, 20, 35, 193, 244, 114, 104,
  6, 95 }

 

// SAVE_KEY

{    27, 117, 138, 231, 251, 254, 7, 22, 50, 123,
    121, 215, 107, 234, 218, 206, 77, 83, 236, 75,
    219, 54, 229, 6, 7, 199, 128, 40, 77, 148,
    57, 55
])

// SAVE_IV

{    206, 175, 60, 42, 180, 134, 58, 221, 48, 202,
    108, 66, 58, 244, 162, 215, 25, 216, 205, 207,
    94, 228, 62, 10, 246, 178, 148, 101, 106, 226,
    146, 157
])

Я конечно не знаю в каких файлах тексты, может в других шифрованиях если есть. Но xmldata этим декодируется.

uu5hC3o.png

Набрасал вейбкодинг:

Скрытый текст

#!/usr/bin/env python3
"""
ORK Framework XML Data Decryptor
Decrypts encrypted xmlData from ORK Framework games (like Marchen Forest)

Algorithm: Rijndael (AES variant) with 256-bit block size, CBC mode
"""

import base64
import argparse
import sys
from pathlib import Path

# Скрипт не требует внешних зависимостей - используется встроенная реализация Rijndael256

# Ключи для данных проекта (xmlData)
PROJECT_KEY = bytes([
    219, 213, 3, 55, 151, 160, 65, 59, 242, 96,
    31, 17, 243, 131, 158, 221, 122, 115, 147, 122,
    205, 191, 88, 227, 80, 100, 140, 248, 78, 102,
    60, 234
])

PROJECT_IV = bytes([
    81, 195, 46, 43, 97, 91, 5, 227, 111, 244,
    215, 186, 50, 37, 107, 101, 5, 187, 155, 119,
    95, 250, 46, 209, 20, 35, 193, 244, 114, 104,
    6, 95
])

# Ключи для сохранений игры (savegame)
SAVE_KEY = bytes([
    27, 117, 138, 231, 251, 254, 7, 22, 50, 123,
    121, 215, 107, 234, 218, 206, 77, 83, 236, 75,
    219, 54, 229, 6, 7, 199, 128, 40, 77, 148,
    57, 55
])

SAVE_IV = bytes([
    206, 175, 60, 42, 180, 134, 58, 221, 48, 202,
    108, 66, 58, 244, 162, 215, 25, 216, 205, 207,
    94, 228, 62, 10, 246, 178, 148, 101, 106, 226,
    146, 157
])


def decrypt_rijndael_256(encrypted_base64: str, key: bytes, iv: bytes) -> str:
    """
    Расшифровывает данные, зашифрованные Rijndael с BlockSize=256.
    Используется встроенная реализация Rijndael256.
    """
    # Декодируем Base64
    encrypted_data = base64.b64decode(encrypted_base64)
    
    # Используем встроенную реализацию Rijndael-256
    decrypted = rijndael_cbc_decrypt(encrypted_data, key, iv)
    
    # Убираем padding (PaddingMode.Zeros)
    decrypted = decrypted.rstrip(b'\x00')
    
    # Декодируем в строку
    text = decrypted.decode('utf-8', errors='replace')
    
    # Извлекаем содержимое между { и }
    return get_enclosed(text, '{', '}')


def get_enclosed(text: str, begin: str, end: str) -> str:
    """Извлекает содержимое между begin и end маркерами."""
    start_idx = text.find(begin)
    if start_idx == -1:
        return text
    
    start_idx += len(begin)
    end_idx = text.rfind(end)
    
    if end_idx == -1 or end_idx <= start_idx:
        return text
    
    return text[start_idx:end_idx]


# ============ Rijndael-256 Implementation ============

def rijndael_cbc_decrypt(data: bytes, key: bytes, iv: bytes, block_size: int = 32) -> bytes:
    """
    Расшифровывает данные с использованием Rijndael CBC с BlockSize=256 бит (32 байта).
    """
    cipher = Rijndael256(key)
    
    result = bytearray()
    prev_block = iv
    
    for i in range(0, len(data), block_size):
        block = data[i:i + block_size]
        decrypted_block = cipher.decrypt_block(block)
        
        # XOR с предыдущим блоком (CBC)
        xored = bytes(a ^ b for a, b in zip(decrypted_block, prev_block))
        result.extend(xored)
        prev_block = block
    
    return bytes(result)


class Rijndael256:
    """
    Минимальная реализация Rijndael с BlockSize=256 бит.
    """
    
    # S-box для Rijndael
    SBOX = [
        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
        0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
        0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
        0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
        0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
        0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
        0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
        0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
        0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
        0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
        0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
        0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
        0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
    ]
    
    # Inverse S-box
    SBOX_INV = [
        0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
        0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
        0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
        0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
        0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
        0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
        0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
        0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
        0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
        0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
        0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
        0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
        0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
        0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
        0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
        0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
    ]
    
    # Round constants
    RCON = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a]
    
    def __init__(self, key: bytes):
        self.Nb = 8  # BlockSize / 32 = 256 / 32 = 8
        self.Nk = len(key) // 4  # KeySize / 32
        self.Nr = max(self.Nb, self.Nk) + 6  # Number of rounds
        self.round_keys = self._key_expansion(key)
    
    def _xtime(self, a):
        return ((a << 1) ^ 0x11b) & 0xff if a & 0x80 else a << 1
    
    def _multiply(self, a, b):
        result = 0
        for i in range(8):
            if b & 1:
                result ^= a
            a = self._xtime(a)
            b >>= 1
        return result
    
    def _key_expansion(self, key: bytes) -> list:
        """Расширение ключа для Rijndael-256."""
        w = []
        
        # Копируем начальный ключ
        for i in range(self.Nk):
            w.append(list(key[4*i:4*i+4]))
        
        # Расширяем ключ
        for i in range(self.Nk, self.Nb * (self.Nr + 1)):
            temp = w[i - 1][:]
            
            if i % self.Nk == 0:
                # RotWord + SubWord + Rcon
                temp = temp[1:] + temp[:1]
                temp = [self.SBOX[b] for b in temp]
                temp[0] ^= self.RCON[i // self.Nk - 1]
            elif self.Nk > 6 and i % self.Nk == 4:
                temp = [self.SBOX[b] for b in temp]
            
            w.append([w[i - self.Nk][j] ^ temp[j] for j in range(4)])
        
        return w
    
    def _add_round_key(self, state: list, round_num: int):
        for c in range(self.Nb):
            for r in range(4):
                state[r][c] ^= self.round_keys[round_num * self.Nb + c][r]
    
    def _inv_sub_bytes(self, state: list):
        for r in range(4):
            for c in range(self.Nb):
                state[r][c] = self.SBOX_INV[state[r][c]]
    
    def _inv_shift_rows(self, state: list):
        # Для Nb=8, сдвиги: [0, 1, 3, 4]
        shifts = [0, 1, 3, 4]
        for r in range(1, 4):
            state[r] = state[r][-shifts[r]:] + state[r][:-shifts[r]]
    
    def _inv_mix_columns(self, state: list):
        for c in range(self.Nb):
            s0 = state[0][c]
            s1 = state[1][c]
            s2 = state[2][c]
            s3 = state[3][c]
            
            state[0][c] = self._multiply(0x0e, s0) ^ self._multiply(0x0b, s1) ^ self._multiply(0x0d, s2) ^ self._multiply(0x09, s3)
            state[1][c] = self._multiply(0x09, s0) ^ self._multiply(0x0e, s1) ^ self._multiply(0x0b, s2) ^ self._multiply(0x0d, s3)
            state[2][c] = self._multiply(0x0d, s0) ^ self._multiply(0x09, s1) ^ self._multiply(0x0e, s2) ^ self._multiply(0x0b, s3)
            state[3][c] = self._multiply(0x0b, s0) ^ self._multiply(0x0d, s1) ^ self._multiply(0x09, s2) ^ self._multiply(0x0e, s3)
    
    def decrypt_block(self, block: bytes) -> bytes:
        """Расшифровывает один блок (32 байта)."""
        # Создаём state matrix (4 rows x Nb columns)
        state = [[0] * self.Nb for _ in range(4)]
        for c in range(self.Nb):
            for r in range(4):
                state[r][c] = block[c * 4 + r]
        
        # Initial round
        self._add_round_key(state, self.Nr)
        
        # Main rounds
        for round_num in range(self.Nr - 1, 0, -1):
            self._inv_shift_rows(state)
            self._inv_sub_bytes(state)
            self._add_round_key(state, round_num)
            self._inv_mix_columns(state)
        
        # Final round
        self._inv_shift_rows(state)
        self._inv_sub_bytes(state)
        self._add_round_key(state, 0)
        
        # Convert state to bytes
        result = bytearray(self.Nb * 4)
        for c in range(self.Nb):
            for r in range(4):
                result[c * 4 + r] = state[r][c]
        
        return bytes(result)


def decrypt_project_data(encrypted_base64: str) -> str:
    """Расшифровывает xmlData проекта."""
    return decrypt_rijndael_256(encrypted_base64, PROJECT_KEY, PROJECT_IV)


def decrypt_save_data(encrypted_base64: str) -> str:
    """Расшифровывает данные сохранения."""
    # Проверяем, не является ли это незашифрованным сохранением
    if encrypted_base64.startswith('<savegame'):
        return encrypted_base64
    return decrypt_rijndael_256(encrypted_base64, SAVE_KEY, SAVE_IV)


def encrypt_rijndael_256(plaintext: str, key: bytes, iv: bytes) -> str:
    """Зашифровывает данные с использованием Rijndael с BlockSize=256."""
    cipher = Rijndael256(key)
    
    # Оборачиваем текст в { }
    text = '{' + plaintext + '}'
    data = text.encode('utf-8')
    
    # Добавляем padding до кратности 32
    block_size = 32
    padding_len = block_size - (len(data) % block_size)
    if padding_len != block_size:
        data += b'\x00' * padding_len
    
    # CBC encryption
    result = bytearray()
    prev_block = iv
    
    for i in range(0, len(data), block_size):
        block = data[i:i + block_size]
        # XOR с предыдущим блоком
        xored = bytes(a ^ b for a, b in zip(block, prev_block))
        encrypted_block = cipher.encrypt_block(xored)
        result.extend(encrypted_block)
        prev_block = encrypted_block
    
    return base64.b64encode(bytes(result)).decode('ascii')


# Добавляем метод шифрования в класс Rijndael256
def _encrypt_block(self, block: bytes) -> bytes:
    """Шифрует один блок (32 байта)."""
    state = [[0] * self.Nb for _ in range(4)]
    for c in range(self.Nb):
        for r in range(4):
            state[r][c] = block[c * 4 + r]
    
    self._add_round_key(state, 0)
    
    for round_num in range(1, self.Nr):
        self._sub_bytes(state)
        self._shift_rows(state)
        self._mix_columns(state)
        self._add_round_key(state, round_num)
    
    self._sub_bytes(state)
    self._shift_rows(state)
    self._add_round_key(state, self.Nr)
    
    result = bytearray(self.Nb * 4)
    for c in range(self.Nb):
        for r in range(4):
            result[c * 4 + r] = state[r][c]
    
    return bytes(result)

def _sub_bytes(self, state: list):
    for r in range(4):
        for c in range(self.Nb):
            state[r][c] = self.SBOX[state[r][c]]

def _shift_rows(self, state: list):
    shifts = [0, 1, 3, 4]
    for r in range(1, 4):
        state[r] = state[r][shifts[r]:] + state[r][:shifts[r]]

def _mix_columns(self, state: list):
    for c in range(self.Nb):
        s0 = state[0][c]
        s1 = state[1][c]
        s2 = state[2][c]
        s3 = state[3][c]
        
        state[0][c] = self._multiply(0x02, s0) ^ self._multiply(0x03, s1) ^ s2 ^ s3
        state[1][c] = s0 ^ self._multiply(0x02, s1) ^ self._multiply(0x03, s2) ^ s3
        state[2][c] = s0 ^ s1 ^ self._multiply(0x02, s2) ^ self._multiply(0x03, s3)
        state[3][c] = self._multiply(0x03, s0) ^ s1 ^ s2 ^ self._multiply(0x02, s3)

# Добавляем методы в класс
Rijndael256.encrypt_block = _encrypt_block
Rijndael256._sub_bytes = _sub_bytes
Rijndael256._shift_rows = _shift_rows
Rijndael256._mix_columns = _mix_columns


def encrypt_project_data(plaintext: str) -> str:
    """Зашифровывает xmlData проекта."""
    return encrypt_rijndael_256(plaintext, PROJECT_KEY, PROJECT_IV)


def encrypt_save_data(plaintext: str) -> str:
    """Зашифровывает данные сохранения."""
    return encrypt_rijndael_256(plaintext, SAVE_KEY, SAVE_IV)


def main():
    parser = argparse.ArgumentParser(
        description='ORK Framework XML Data Decryptor/Encryptor',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog='''
Examples:
  Decrypt project xmlData from file:
    python ork_decrypt.py -d input.txt -o output.xml
    
  Decrypt from stdin:
    echo "BASE64_DATA" | python ork_decrypt.py -d -
    
  Decrypt savegame:
    python ork_decrypt.py -d save.txt -o save.xml —save
    
  Encrypt XML back:
    python ork_decrypt.py -e input.xml -o output.txt
        '''
    )
    
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('-d', '--decrypt', metavar='FILE', 
                       help='Decrypt file (use - for stdin)')
    group.add_argument('-e', '--encrypt', metavar='FILE',
                       help='Encrypt file (use - for stdin)')
    
    parser.add_argument('-o', '--output', metavar='FILE',
                        help='Output file (default: stdout)')
    parser.add_argument('--save', action='store_true',
                        help='Use savegame keys instead of project keys')
    
    args = parser.parse_args()
    
    # Read input
    if args.decrypt:
        if args.decrypt == '-':
            data = sys.stdin.read().strip()
        else:
            data = Path(args.decrypt).read_text(encoding='utf-8').strip()
        
        # Decrypt
        if args.save:
            result = decrypt_save_data(data)
        else:
            result = decrypt_project_data(data)
            
    elif args.encrypt:
        if args.encrypt == '-':
            data = sys.stdin.read()
        else:
            data = Path(args.encrypt).read_text(encoding='utf-8')
        
        # Encrypt
        if args.save:
            result = encrypt_save_data(data)
        else:
            result = encrypt_project_data(data)
    
    # Write output
    if args.output:
        Path(args.output).write_text(result, encoding='utf-8')
        print(f"Output written to: {args.output}")
    else:
        print(result)


if __name__ == '__main__':
    main()

 

 

  • Лайк (+1) 1

Поделиться сообщением


Ссылка на сообщение

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас популярно

  • Продвигаемые темы

  • Последние сообщения

    • Случаем не крутил колёсиком мышки при зажатом ctr на рабочем столе (предварительно тыкнув куда-нибудь в пустую часть рабочего стола левой мышой)? По идее это должно выравнять размеры к общему, делая обновление их размера при изменении этого размера (осторожно, может перепутать порядок иконок, сделай заранее скриншот, чтобы потом расставить всё как было).
    • @mytraz о чём думать, поезд ушёл  Что-то могло ещё произойти в декабре, если бы я не стал в позу и сказал НЕТ) Но нет я ни секунды не жалею о том, что передумал. Тогда я может кого-то перетянул к себе, а сейчас то что, ко мне заходят на бусти случайные зеваки, которые пришли с гугла) Но просто подумай логически, зачем мне это. На этом денег не заработаешь, но это может стать второй работой. Особенно по части техподдержки, тут хоть целую службу нанимай для разбора случаев “а почему меня не работает”. Времени всё это занимает уйму. Догу стоит уже в лаунчер встроить хелпдеск с чатом И у него в мечтах всё это автоматизировать, но не думаю, что китайцы позволят ему “сесть и ничего не делать” В прочем, поживём увидим, мне больше нравится позиция наблюдателя))  
    • Увы но никого из списка выше не выберут, как это обычно бывает, у них свой или штат или аутсорс переводчиков которые пилят лицензированный перевод. Это не как с озвучкой. Другой уровень. Но ты подумай)) у тебя уже собирается небольшая армия почитателей
    • @piton4 на 10 винде ровные.кеш возможно сбился )
    • Уже довольно давно обратил внимание, что ярлыки для игр стали разного размера. Как можно заметить, некоторые картинки начинаются от стрелочки, но норм размер, это когда стрелка внутри основного квадрата..  Никто не в курсе, как это исправить? Смотрится довольно хреново и раньше такого не было.
    • Ох, файтинг песочница. Необычное сочетание.
    • https://store.steampowered.com/app/3380520/ToHeart/ — страница игры Жанр: Визуальная новелла (3D) Разработчик: AQUAPLUS Издатель: DMM GAMES, Shiravune Платформы: Windows Дата выхода: 25 Июня 2025 На перевод
    • @Tost3R полностью согласен, и соревноваться в этом деле интересно только поначалу, а когда уже видно кого комьюнити выбрало — это как об стенку горох.  Через некоторое время после старта выхода игры в стиме уже было 6 (ШЕСТЬ) русификаторов. Сейчас в итоге осталось три из поддерживающихся. Всё равно много Зато есть выбор) И да, то, что труды периодически делятся если не на ноль, то на 2(привет обновам), это как-то грустновато) Победит тот, кого выберут Китайцы в качестве ОФ локализатора Так, что умнее всех тот, кто сейчас договаривается с ними)) Самая тёмная лошадка конечно вот этот русик. https://boosty.to/dlightru/posts/03c12dc4-27b2-4cc4-a489-6cc07d4d9196?share=post_link
    • Полагаю тут ещё вопрос останется ли свой след в истории (не обесценится ли потраченное время)? Перевод для Once Human вышел через кажется 7 месяцев после релиза, хотя кол-во текста разное. И в один прекрасный момент труды канут в лету. Чего не случится с сингл играми, которые не патчатся с год и более, да и вряд ли будут патчиться. Давно не касался темы бесплатных переводов и конечно диву даюсь совмещать работу/учебу, общение с юзерами тут/в вк/стиме/на бусти и создание самих переводов и всё это собственно бесплатно (добровольно). Это я к: Так что @DOG729 ни в коем случае не хотел обесценить твой труд.
  • Изменения статусов

    • TerryBogard  »  Siberian GRemlin

      C&C: RA: Retaliation (ПК) не работает.
      · 0 ответов
    • Алекс Лев  »  SerGEAnt

      Привет, Сержант. Прошу разрулить ситуэйшн и урезонить некоторых людей, оскорбивших мою личность. Пожалуйста, для этого прочтите нашу переписку с Ленивым. Примите меры, будьте добры, мною составлена бумага, ждущая вашей электронной подписи, для подачи её в суд. Если не желаете судебных разборок (а я пойду дальше, если меры не будут приняты), оскорбившие меня люди должны понести необходимое по вашему же Договору наказание. Спасибо.
      · 1 ответ
    • Antony1203  »  SerGEAnt

      Добрый вечер! С Новым Годом. Нашел на просторах сети русскую озвучку Halo Infinite, которая отсутствует на моем любимом сайте  Протестил. Все работает. Подскажите, как можно передать? Спасибо.
      · 2 ответа
    • Albeoris

      Демка вышла. Работаем.
      · 0 ответов
    • maddante665  »  parabelum

      https://disk.yandex.ru/d/A7W9aHwW7wLTjg
      ссылка на торрент , в нем архив с игрой.
      единстенное в геймпасее папка TotalChaos_Data так, а в стиме Total Chaos_Data, но если пробел убрать в архиве с ркссификатором все равно не работает, ломаются надписи , просто прозрачные. я пробовал только текст .
      · 1 ответ
  • Лучшие авторы


Zone of Games © 2003–2026 | Реклама на сайте.

×