Версия для печати темы
CTPAX-X _ Программы _ CheMax
Автор: Кантемир Mar 18 2007, 18:00
Просто хочу оболочку и возможности сохранить, а база кодов с нула хочу написать
и добавить секреты.
Блин как редактировать база данных?
А может ктонибудь создать прогу на подобия это? Просто там в chemaxе нельзя ни редактировать ни с нула.
Автор: jTommy Mar 19 2007, 18:31
QUOTE(Кантемир @ Mar 18 2007, 09:00 PM)

Просто хочу оболочку и возможности сохранить, а база кодов с нула хочу написать
и добавить секреты.
Блин как редактировать база данных?
А может ктонибудь создать прогу на подобия это? Просто там в chemaxе нельзя ни редактировать ни с нула.
Никто не будет делать такой объем работы за тебя (это я про написание новой оболочки)...
К тому же идея сомнительная... зачем изобретать велосипед? Может лучше связаться с авторами и они добавят твои секреты.
Автор: -=CHE@TER=- Mar 21 2007, 18:07
Кантемир!
Простите, пожалуйста, но... у вас сообщения... как бы это сказать. Ошибок много, спецефических - так пишут дети (очень маленькие), либо люди слабо знакомые с русским языком. Мне сложно вникнуть в суть ваших сообщений. Может для вас родной язык английский? Если да - то пишите на нём - всем будет проще.
Базу кодов, действительно, можно набирать в текстовом файле.
Но тут сразу возникает две проблемы:
1) Как её разбирать, чтобы выводить на экран? (с текстовым файлом хлопот много)
2) Как проверять её целостность? (если вдруг кто-то внёс туда свои коды и при этом нарушил структуру базы)
Автор: -=CHE@TER=- Mar 22 2007, 10:16
QUOTE(Кантемир @ Mar 21 2007, 08:05 PM)

Нет, не это. (*улыбается*) Общий стиль ваших сообщений. Ладно, не берите в голову.
QUOTE(Кантемир @ Mar 21 2007, 08:05 PM)

Я знаком близе к русскому языку.

Это хорошо. Как вам будет удобно.
QUOTE(Кантемир @ Mar 21 2007, 08:05 PM)

Блин, а как у Chemax`а получаеться?

А может быть другим каким нибудь прогой создавать вместе этого блокнота, чтобы меньше было хлопот.
1) Файлы по отдельносты или как у файлы формата субтитров
2) Не знаю нужно, что нибудь придумать, скажем создадим прогу которое определаеть по базу кодов или вот допустим определает по оглавление базы кодов
Вот хотел бы создать конкурента Chemax`а.

Какой формат у CheMax - не знаю. Для вашей программы могу предложить такой:
а) коды для каждой игры хранятся каждый в своём текстовом файле (самом обыкновенном, без управляющих структур)
б) чтобы файлов этих не было очень много - они все помещены внутрь одного контейнера (т.е. файла без архивации); для этих целей очень, ИМХО, подойдёт формат типа PACK (.PAK) из Quake II - т.к. там очень удобно добавлять новые файлы (просто в конец, сместив заголовок). Хотя с редактированием старых, будет немного проблем.
Автор: -=CHE@TER=- Mar 26 2007, 17:21
QUOTE(Кантемир @ Mar 26 2007, 02:15 PM)

Не плохо придумана, а какой прогой можно создать PACK?
Есть специальные утилиты для этого... А вообще, мой ответ подразумевал, что ты сам напишешь программу для работы с такими псевдо-архивами. Потому что даже упаковав туда файлы, ты всё-равно не сможешь с ними работать, т.к. тебе в твоей программе нужно будет как-то их оттуда доставать.
QUOTE(Кантемир @ Mar 26 2007, 02:15 PM)

А еще не подскажеть каким прогой можно создать оболочки прогу?
Выучить какой-нибудь язык программирования. (*улыбается*) Например,
Delphi (весьма простой).
QUOTE(Кантемир @ Mar 26 2007, 02:15 PM)

Я пробивал что нибудь сделать в Chemax`е у неге защита стоит ASPack 2.12 -> Alexey Solodovnikov
Проверял с помощью Peid. А Дальше eXeScope и Restorator 2007
Ну вот там нашел украшения оболочки.
Ну-да, программа защищена хорошо. Их БД с кодами, кстати, зашифрована (недавно посмотрел).
QUOTE(Кантемир @ Mar 26 2007, 02:15 PM)

Ну, вообще-то мы авторы не только этой программы. (*улыбается*)
Автор: Siberian GRemlin Mar 27 2007, 13:07
А не проще на M$ Access взять документацию и на нём БД сделать?!
Автор: jTommy Mar 28 2007, 18:38
QUOTE(Siberian GRemlin @ Mar 27 2007, 05:07 PM)

А не проще на M$ Access взять документацию и на нём БД сделать?!
Совсем не проще. Это-ж придется Access ставить. Например, я ее редко пользую и поэтому не ставлю... Хотя догадываюсь, что большинство народу Office ставит вместе со всем барахлом, которое предлагается по умолчанию.
В данном случае легче всего забить на эту идею, но если очень хочется, то сначала придется изучить Дельфи. Узнать что такое форма, интерфейс программы и как его лучше спроектировать, как работать с типизированными файлами и т.д. и пр.
P.S.: ИМХО, читы - плехо! Даже если они применяются, когда игра уже пройдена.
Автор: -=CHE@TER=- Apr 1 2007, 16:57
QUOTE(Кантемир @ Apr 1 2007, 04:10 PM)

-=CHE@TER=-!
А не проще без архива?
Проще. Можно вообще файлы в отдельный каталог валить. Но неудобно - когда ты добавишь более пары тысяч таких текстовых файлов, то станет неудобно в такой каталог заходить, т.к. будет долго список с файлами создаваться.
QUOTE(Кантемир @ Apr 1 2007, 04:10 PM)

Спасибо большое! Тебя тоже.
Автор: 9k1d Dec 14 2007, 09:04
QUOTE(Кантемир @ Apr 1 2007, 07:10 PM)

jTommy!
это получаешься две разние игры
Я эту прогу хотел создать прошлом году летом, а время летить.
P.S. Всех поздравляю с 1 апреля.

ну как там результат есть? или это шутка была?
Автор: -=CHE@TER=- Aug 13 2009, 21:07
Я вижу, что в этой теме часто зависают гости.
Если кого-то интересует как вытащить из БД Chemax всё содержимое наружу, то прочитайте статью http://www.xakep.ru/post/27145/default.asp.
Как отправная точка для начала работы - самое то.
Автор: -=CHE@TER=- Jul 21 2013, 12:43
Вот уже 10 лет код шифрования БД у Chemax не меняется (проверил на только что скачанной версии):
CODE
#define KEY_LEN 10
static const char key[KEY_LEN] = "a@g5eDu(*5";
void cm_decrypt(unsigned char *p, unsigned int size) {
unsigned int i, k;
for (i = 0; i < size; i++) {
k = i % KEY_LEN;
if (p[i] > key[k]) {
p[i] = p[i] - key[k];
} else {
p[i] = p[i] - key[k] + 255;
}
}
}
Читаем в память весь "cheats.dat", скармливаем этой функции и получаем на выходе расшифрованный буфер.
Но БД представляет из себя один сплошной текстовый файл.
Список игр завален на форму программы, а смещения до начала каждой игры внутри БД лежат как массив DWORD в исполняемом файле. Т.е. чтобы разбить БД по играм, нужно распаковывать (ASPack) исполняемый файл Chemax, искать там таблицу смещений и через неё выдёргивать игры.
В Chemax v2.7 (2004 год) таблица смещений начиналась в 000DA604h у распакованного файла, с какого-то DWORD (то ли размер таблицы, то ли количество игр - фиг знает).
Первое смещение, пожоже, всегда 1.
В общем, организация этой БД - это долбанный стыд.
К слову сказать, к тем играм, которые я знаю, некоторые коды написаны неверно или, вообще, дублируются в одном месте не полные и в другом также (у игры два названия) - короче, в поисках кодов к игре, я бы на эту базу полагаться не стал.
Автор: -=CHE@TER=- Feb 12 2018, 20:33
Не прошло и 15 лет, как ключик таки поменяли - меня сегодня по e-mail спрашивали почему мой алгоритм выше не работает. Я, кстати, его переписал, чтобы он был более понятным. Для версий 19.0 и 20.0, что сейчас лежат на официальном сайте (возможно и с более ранними версиями вплоть до 2013 года работать будет):
CODE
static const char key[KEY_LEN] = "qZ8&5N3eS0";
Как я понимаю, ключ поменяли именно потому, что он засветился здесь - в публичной теме. А, главное, было бы что прятать - БД у них фиговая, я ещё ранее писал что они, походу, вообще не проверяют ту ахинею, которую туда пихают. Было бы, кстати, толково, если бы они создали Wiki на основе своей базы, чтоб все желающие могли выправить весь тот ужас, который эта БД из себя представляет.
Автор: -=CHE@TER=- Feb 12 2024, 18:07
В 2022 году домен CheMax.ru был разделегирован, так что история данной программы на этом закончилась, поэтому можно подвести уже окончательный итог.
Для начала отвечу на самое первое сообщение этой темы (понимаю, что уже не актуально, ну да ладно):
QUOTE(Кантемир @ Mar 18 2007, 18:00)

Просто хочу оболочку и возможности сохранить, а база кодов с нула хочу написать
и добавить секреты.
Блин как редактировать база данных?
А может ктонибудь создать прогу на подобия это? Просто там в chemaxе нельзя ни редактировать ни с нула.
Нет, это невозможно. Дело в том, что описания кодов хранятся зашифрованные в текстовом файле "Cheats.dat", в то время как соответствующие этим текстам имена игр и смещения до них в этом файле, намертво прошиты в "Chemax.exe", который ещё и ASPack'ом упакован (защищён от изменений). Поэтому, максимум, что можно сделать, это изменить коды к существующим играм так, чтобы они не выходили за отведённое им место (меньше текста можно - лишнее пробелами заменить, больше - нельзя).
Сама программа и некоторые её старые и новые версии, помимо веб-архива, доступны ещё здесь: http://old-dos.ru/files/file_101547.html.
И тут, поковыряв старые и новые версии этой программы, я выяснил интересную штуку про ключи шифрования. Оказывается, ключ "a@g5eDu(*5" использовался только для русской версии. В английской версии ещё с 2004 года использовался ключ "qZ8&5N3eS0" на который перевели и русскую между 2013 и 2018 годом - видимо, автору надоело пересобирать исполняемый файл с разными ключами при выпуске новых версий. Так что, признаю, моё предположение о том что ключ поменяли, потому что я его в этой теме публично засветил, было неверное.
Попробую при следующем обновлении сайта добавить программу для расшифровки любой базы данных (с автоматическим определением ключа расшифровки), а также два текстовых файла со смещениями и именами игр в последних версиях "Cheats.dat" (RUS 21.4 и ENG 20.8) для тех, кто захочет распотрошить базу данных (распаковал и распарсил исполняемые файлы "CheMax.exe"). Увы, это, конечно, не вернёт потерянных трейнеров и других полезных утилит, которые накрылись вместе с сайтом программы.
Функция для расшифровки любой базы данных выглядит так (возвращает не нулевое значение, если буфер удалось расшифровать):
CODE
uint32_t CheMaxDecrypt(uint8_t *p, uint32_t size) {
uint8_t key[10];
uint32_t i, k;
i = 0;
/* sanity check */
if (p && size && ((*p == 0x81) || (*p == 0x91))) {
/* detect key */
if (*p == 0x81) {
memcpy(key, "a@g5eDu(*5", sizeof(key));
} else {
memcpy(key, "qZ8&5N3eS0", sizeof(key));
}
/* decrypt database with key */
for (i = 0; i < size; i++) {
k = i % sizeof(key);
p[i] += ((p[i] > key[k]) ? 0 : 255) - key[k];
}
i = 1;
}
return(i);
}
На этом, вероятно, уже точно всё - тему можно считать закрытой.
Автор: -=CHE@TER=- Feb 22 2024, 14:21
http://www.ctpax-x.org/?goto=files&show=170
Автор: useretail Apr 20 2025, 02:17
Причесал для линукса: https://www.upload.ee/files/17982691/dechemax.zip.html
Благоданости: -=CHE@TER=-
CODE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <inttypes.h>
#define OUTPUT_NAME_MAX 260
static const uint8_t valid_char_mask[32] = {
0x00, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
0x04, 0x80, 0x7B, 0x40, 0xEF, 0xB9, 0x38, 0xF1,
0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF
};
static const uint8_t decryption_keys[3][10] = {
"qs3g#erty0",
"a@g5eDu(*5",
"qZ8&5N3eS0"
};
const char *get_basename(const char *path) {
const char *base = strrchr(path, '/');
return base ? base + 1 : path;
}
void replace_file_ext(char *out, size_t size, const char *filename, const char *new_ext) {
const char *base = get_basename(filename);
const char *dot = strrchr(base, '.');
size_t len = dot ? (size_t)(dot - base) : strlen(base);
if (*new_ext != '.')
snprintf(out, size, "%.*s.%s", (int)len, base, new_ext);
else
snprintf(out, size, "%.*s%s", (int)len, base, new_ext);
}
int decrypt_buffer(uint8_t *buffer, size_t buffer_size, uint32_t key_type) {
if (!buffer || buffer_size == 0 || key_type >= 3) return 0;
const uint8_t *key = decryption_keys[key_type];
size_t i = 0, k = 0;
if (key_type == 0) {
k = buffer_size - 1;
while (k && !buffer[k]) k--;
while (k && (buffer[k] == ';' || (buffer[k] >= '0' && buffer[k] <= '9'))) k--;
if (k && !buffer[k]) {
buffer[k] = ' ';
k++;
i = 0;
while (k < buffer_size && (buffer[k] >= '0' && buffer[k] <= '9')) {
i = i * 10 + (buffer[k++] - '0');
}
for (; k < buffer_size; k++) {
if (!buffer[k]) buffer[k] = ' ';
}
buffer_size = i;
}
}
for (i = 0; i < buffer_size; i++) {
k = i % 10;
if (key_type == 0) {
buffer[i] -= key[k];
} else {
buffer[i] += ((buffer[i] > key[k]) ? 0 : 255) - key[k];
}
}
return 1;
}
uint32_t detect_key_type(const uint8_t *data, size_t size) {
if (!data || size < 128) return 100;
uint8_t temp[128];
for (uint32_t key_index = 0; key_index < 3; key_index++) {
memcpy(temp, data, sizeof(temp));
decrypt_buffer(temp, sizeof(temp), key_index);
int is_valid = 1;
for (size_t j = 0; j < sizeof(temp); j++) {
if (!(valid_char_mask[temp[j] / 8] & (0x80 >> (temp[j] % 8)))) {
is_valid = 0;
break;
}
}
if (is_valid) return key_index;
}
return 100;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <cheats.dat>\n", get_basename(argv[0]));
return 1;
}
const char *input_filename = argv[1];
int input_fd = open(input_filename, O_RDONLY);
if (input_fd < 0) {
fprintf(stderr, "Error: could not open input file '%s': %s\n", input_filename, strerror(errno));
return 2;
}
struct stat file_stat;
if (fstat(input_fd, &file_stat) != 0) {
fprintf(stderr, "Error: could not get file info for '%s': %s\n", input_filename, strerror(errno));
close(input_fd);
return 3;
}
size_t file_size = (size_t)file_stat.st_size;
uint8_t *file_buffer = malloc(file_size);
if (!file_buffer) {
fprintf(stderr, "Error: failed to allocate memory (%zu bytes): %s\n", file_size, strerror(errno));
close(input_fd);
return 4;
}
ssize_t bytes_read = read(input_fd, file_buffer, file_size);
if (bytes_read != file_size) {
fprintf(stderr, "Error: failed to read from '%s' (expected %" PRIuPTR " bytes, got %" PRIuPTR " bytes): %s\n",
input_filename, (uintptr_t)file_size, (uintptr_t)bytes_read, strerror(errno));
free(file_buffer);
close(input_fd);
return 5;
}
close(input_fd);
uint32_t key_type = detect_key_type(file_buffer, file_size);
if (!decrypt_buffer(file_buffer, file_size, key_type)) {
fprintf(stderr, "Error: input file is not a valid or supported format\n");
free(file_buffer);
return 6;
}
char output_filename[OUTPUT_NAME_MAX];
replace_file_ext(output_filename, sizeof(output_filename), input_filename, ".txt");
int output_fd = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (output_fd < 0) {
fprintf(stderr, "Error: could not create output file '%s': %s\n", output_filename, strerror(errno));
free(file_buffer);
return 7;
}
ssize_t bytes_written = write(output_fd, file_buffer, file_size);
if (bytes_written != file_size) {
fprintf(stderr, "Error: failed to write to '%s' (expected %" PRIuPTR " bytes, got %" PRIuPTR " bytes): %s\n",
output_filename, (uintptr_t)file_size, (uintptr_t)bytes_written, strerror(errno));
close(output_fd);
free(file_buffer);
return 8;
}
close(output_fd);
free(file_buffer);
printf("Success: '%s' decrypted and saved as '%s'\n", input_filename, output_filename);
return 0;
}
Автор: useretail Apr 26 2025, 00:31
todo: выковырять списки смещений и имена игр для FC
Автор: -=CHE@TER=- Apr 26 2025, 00:50
Так они там не зашифрованы - просто в конце находятся. Сначала список игр, потом, через запятую, смещения (байтовые) в десятичном виде. Я как раз в программе это обрабатывал, чтобы расшифровывалось всё, кроме этого списка в хвосте.
Автор: Shadeov Jul 8 2025, 17:14
Привет всем!
Подскажите, пожалуйста, как достать ключи смещений в CheMax? Нужна пошаговая инструкция для "новичка".
Хочу сохранить это наследие, адаптировать под современные системы и при этом обеспечить обратную совместимость с базой данных.
Всё никак не дадим спокойно помереть ЧеМаксу
Автор: -=CHE@TER=- Jul 8 2025, 17:32
QUOTE(Shadeov @ Jul 8 2025, 17:14)

Привет всем!
Добро пожаловать на форум!
QUOTE(Shadeov @ Jul 8 2025, 17:14)

Подскажите, пожалуйста, как достать ключи смещений в CheMax? Нужна пошаговая инструкция для "новичка".
Хочу сохранить это наследие, адаптировать под современные системы и при этом обеспечить обратную совместимость с базой данных.
Всё никак не дадим спокойно помереть ЧеМаксу 
Готовые смещения есть в архиве к программе database decrypter (ссылку ранее в этой теме давал) к последним версиям CheMax: 20.8 для английской версии (файл "eng_20_8.txt") и 21.4 для русской (файл "rus_21_4.txt"). Вроде бы, это должны быть последнии версии программы.
Если нужны для каких-то старых версий, то тут придётся попотеть. Я так делал:
1. Смещения для описаний находятся внутри CheMax.exe, но файл защищён ASPack.
2. Я снимал ASPack программой Dr.WEB.FLY-CODE.Unpacker.0.1.
3. Далее нужно вытащить строки (названия игр) и смещения - они отдельно находятся.
4. Чтобы вытащить имена игр, засовываем распакованный файл "STEP1_ASPACK.exe" в программу по работе с ресурсами (я для этого Resource Hacker использовал) и сохраняем куда-нибудь .DFM файл с главной формой программы. Затем в Delphi (у меня он стоит) создаём пустой проект, затем сохраняем и закрываем его. Заменяем файл формы сохранённой формой от CheMax. После этого открываем проект снова в Delphi, на форме выбираем список с именами игр, выбираем редактировать, затем сохраняем в буфер обмена Ctrl+C всё содержимое и вставляем Ctrl+V в какой-нибудь пустой текстовый файл.
5. Теперь нужно достать смещения. Здесь сложнее, потому что они в бинарном виде и как их найти я не могу написать - я тупо вручную отсматривал файл в HEX-редаторе. У меня осталась вот такая черновая рабочая программа, которой я смещения доставал - надеюсь пригодится как отправная точка для работы. Обращаю внимание, что смещений, вроде бы, на 1 больше, чем названий игр (последнее смещение равно размеру файла с описаниями) - это для того, чтобы размер описания к игре можно было получить как разницу между следующим и текущим смещением.
6. Ну и потом нужно просто объединить смещения и названия игр - можно написать для этого программу или скрипт, например, на том же PHP или на чём удобнее.
Программу ниже нужно скомпилировать и перенаправить вывод в файл при запуске:
offsdump.exe > offs.txt
Исходный код "offsdump.c":
CODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/* eng 19.2 */
/*
static uint32_t offslist[] = {
0xD7C14,
0xDBA94,
0xDE974
};
*/
/* eng 20.8 */
static uint32_t offslist[] = {
0xD8614,
0xDC494,
0xDF374
};
/* rus 21.4 */
/*static uint32_t offslist[] = {
0xDBA14,
0xDF894,
0xE2774,
0xE5654,
0xE8534,
0xEB414,
0xEE2F4
};*/
static uint32_t offs[4000];
int main(int argc, char *argv[]) {
uint32_t i, j;
FILE *fl;
fl = fopen("STEP1_ASPACK.exe", "rb");
if (!fl) { return(1); }
for (i = 0; i < (sizeof(offslist) / sizeof(offslist[0])); i++) {
fseek(fl, offslist[i], SEEK_SET);
fread(offs, sizeof(offs), 1, fl);
for (j = 0; j < 4000; j++) {
if (!offs[j]) { break; }
printf("%08X\n", offs[j]);
}
}
fclose(fl);
return(0);
}
Автор: Shadeov Jul 9 2025, 00:58
QUOTE
Добро пожаловать на форум!
Спасибо!
QUOTE
Если нужны для каких-то старых версий, то тут придётся попотеть.
Правильно ли я понимаю, что ни у "Dr.WEB.FLY-CODE.Unpacker", ни у "STEP1_ASPACK.exe" нет ни исходников, ни даже внятного описания принципа работы?
Мне нужно будет воспроизвести их логику на клиентском JavaScript, а позже — и на других платформах. Использование готовых exe-файлов убивает кроссплатформенность.
Автор: -=CHE@TER=- Jul 9 2025, 06:28
QUOTE(Shadeov @ Jul 9 2025, 00:58)

Правильно ли я понимаю, что ни у "Dr.WEB.FLY-CODE.Unpacker", ни у "STEP1_ASPACK.exe" нет ни исходников, ни даже внятного описания принципа работы?
"Dr.WEB.FLY-CODE.Unpacker" точно исходных кодов нет, а "STEP1_ASPACK.exe" - это имя, под которым первая программа сохраняет распакованный "CheMax.exe" файл (со снятой защитой). К CheMax тоже никто исходных кодов не выкладывал.
QUOTE(Shadeov @ Jul 9 2025, 00:58)

Мне нужно будет воспроизвести их логику на клиентском JavaScript, а позже — и на других платформах. Использование готовых exe-файлов убивает кроссплатформенность.
А какая
конечная цель проекта? Что сделать нужно в итоге?
Возможно есть какое-то более простое решение, чем писать распаковщик для ASPack и что-то откуда-то выковыривать.
Я почему спрашиваю именно про
конечную цель, потому что промежуточные задачи могут быть сильно не о том. Не помню, вроде бы, где-то уже рассказывал, но меня как-то попросили написать распаковщик ресурсов к игре, потом переделать чтобы он сохранённые игры распаковывал (там формат схожий), но в итоге выяснилось, что человек просто хотел найти где у него в игре деньги хранятся и дать их себе побольше. Однако это легко делалось программой ArtMoney (о которой человек просто не знал) и распаковывать ничего не нужно было. К слову сказать, человек потом извинился, что ввёл в заблуждение и сразу не рассказал что именно он в итоге получить хотел, и даже на копилку сам закинул.
Поэтому я про итоговую цель и спрашиваю - возможно, есть решение гораздо проще того, что мы сейчас обсуждаем.
Если там какой-то секрет большой, то можно мне личное сообщение написать на e-mail.
А если нет, то давайте здесь обсуждать - возможно, техническое решение будут ещё кому-то интересно для похожего или другого проекта. Или кто-то ещё из прочитавших идей подбросит.
Автор: Shadeov Jul 9 2025, 08:56
QUOTE
А какая конечная цель проекта?
Цель — альтернативный клиент для CheMax с обратной совместимостью. Планирую сайт + кроссплатформенные клиенты (Mac, Windows, iOS, Android и т.д.).
Идея в том, чтобы просто загружать CheMax.exe и cheats.dat, после чего база открывается в современном интерфейсе — прямо в браузере, без установки.
Если безболезненной распаковки не получится, то, скорее всего, просто вытащу смещения вручную и буду сопоставлять по хешу .dat‑файлов.
В крайнем случае — использовать только уже готовые ваши смещения от последних версий.
Пока набросал небольшой сайт на основе вашей DeCheMax — https://dechemax.vercel.app/
Открывает последние версии CheMax и CheMax FC. Old пока не проверял. Всё на клиенте: база сохраняется в кэше браузера и там же распаковывается.
Как доделаю — обязательно выложу исходники.
Автор: -=CHE@TER=- Jul 9 2025, 10:04
Во! Спасибо за развёрнутый ответ.
Теперь по пунктам.
QUOTE(Shadeov @ Jul 9 2025, 08:56)

Цель — альтернативный клиент для CheMax с обратной совместимостью. Планирую сайт + кроссплатформенные клиенты (Mac, Windows, iOS, Android и т.д.).
Идея в том, чтобы просто загружать CheMax.exe и cheats.dat, после чего база открывается в современном интерфейсе — прямо в браузере, без установки.
Идея классная, только вот с точки зрения конечного пользователя сложновата в использовании. Проще будет, наверное, БД последней версии CheMax конвертировать в одностраничный HTML файл и выложить в Интернет. Кому надо скачают к себе на диск для просмотра в offline, кому не надо - смогут через Интернет обозреватель с любого устройства смотреть. Если из БД выкинуть все игры, где написано только "для этой игры есть трейнер на сайте CheMax" (сайт закрылся и трейнеры вместе с ним пропали) и больше ничего (как это ни странно, таких игр много, причём этот текст тупо дублируется), то итоговая HTML страничка ещё и занимать мало будет. Ещё можно сделать список с играми как плавающий блок слева или справа, чтобы всегда на экране был и якорями-ссылками для быстрого перехода к нужной игре.
Можно, как уже писал ранее, сделать сайт-вики с кодами для CheMax, где люди смогут их обновлять, исправлять, добавлять.
Я не вижу смысла именно заморачиваться поддержкой всех версий (разве что, кроме как хобби) в силу следующих причин:
1. Неудобно использовать. Пользователю чтобы посмотреть какие-то коды, которые он когда-то в этой программе видел, нужно где-то найти дистрибутив программы, установить или как-то его распаковать, затем достать оттуда нужные файлы, затем залить их на сайт - я ставлю на то, что такое количество телодвижений очень многих людей отпугнёт, а кому-то просто всё желание заморачиваться отобьёт. Да, можно добавить поддержку InnoSetup установщика и .ZIP архива, чтобы можно было дистрибутив программы заливать на сайт без установки, но дистрибутив всё равно нужно будет где-то найти.
2. Сайт CheMax закрылся, похоже, автор не планирует продолжать проект. Сами по себе коды к играм не могут быть защищены авторским правом (если, вдруг, беспокоит этот вопрос). К тому же, скорее всего, коды для БД просто собирались из всяких сборников и сайтов в Интернете. Программа была полезна для экономии трафика в 2000-ых годах, когда Интернет дорого стоил и не был безлимитным, то иметь под рукой энциклопедию было удобно. А сейчас с общедоступным Интернетом такая программа не особо актуальна в виде отдельного приложения.
QUOTE(Shadeov @ Jul 9 2025, 08:56)

Если безболезненной распаковки не получится, то, скорее всего, просто вытащу смещения вручную и буду сопоставлять по хешу .dat‑файлов.
В крайнем случае — использовать только уже готовые ваши смещения от последних версий.
Да, кстати, именно такое решение и хотел предложить - заготовить смещения + имена игр от всех существующих версий и по размеру/хешу от .dat файла использовать нужные. Процесс, правда, будет долгий и трудоёмкий - непонятно сколько там версий было, что-то можно из WebArchive достать, что-то с того же Old-Dos, но все ли там версии - неизвестно.
QUOTE(Shadeov @ Jul 9 2025, 08:56)

Пока набросал небольшой сайт на основе вашей DeCheMax — https://dechemax.vercel.app/
Открывает последние версии CheMax и CheMax FC. Old пока не проверял. Всё на клиенте: база сохраняется в кэше браузера и там же распаковывается.
Как доделаю — обязательно выложу исходники.
Глянул - круто!
Я в любом случае отговаривать не буду - если есть желание, силы и время - то почему бы и нет?
Хобби проекты тем интересны и приятны, что люди делают просто то что им хочется и нравится.
А ещё иногда такие штуки делаются просто чтобы освоить какие-то новые технологии и на чём-то потренироваться - просто так писать что-то абстрактное неинтересно, а вот работать над конкретной задачей уже гораздо увлекательнее.
В общем, я за любой кипишь, кроме голодовки. (*улыбается*)
Автор: -=CHE@TER=- Jul 12 2025, 17:41
QUOTE(Shadeov @ Jul 9 2025, 08:56)

Пока набросал небольшой сайт на основе вашей DeCheMax — https://dechemax.vercel.app/
Погонял немного, очень круто! Несколько пожеланий:
1. Заголовок страницы "Create Next App". Заменить на что-нибудь типа "CheMax Decoder", а то сразу вкладку не нашёл, когда переключился на другую.
2. Хотелось бы, чтобы поле "Поиск игр..." не исчезало, когда крутишь список с играми вниз.
3. Когда листал коды к какой-то игре, где много текста, а затем через список слева переключился на коды к другой игре, где тоже много текста, то сохраняется позиция. На небольшом разрешении экрана (у меня 1024x768) не сразу понимаешь, что у тебя сверху коды и нужно прокручивать вверх страницу с описанием кодов, чтобы на начало выйти. Хотелось бы, чтобы позиция сбрасывалась на ноль (вверх) при переключении на другую игру из списка или перезагрузки всей страницы.
4. Почему-то после перезагрузки страницы, если список игр слева пролистать в самый низ, то никак не удаётся выбрать последнюю игру - страница очень долго сопротивляется и почему-то откатывается на одну позицию вверх. Если долго крутить колесо мышки вниз, то в какой-то момент страница таки сдаётся и позволяет выбрать последнюю игру в списке.
5. Три полоски рядом с названием игры в правой части, лучше заменить на стрелку влево, как в GitHub сделано, когда код открываешь, там также можно панель слева скрыть. Просто три подряд горизонтальные черты ассоциируются с меню, а здесь на привычную иконку другой функционал установлен.
6. Было бы очень здорово поиск как-то разделить. Например, сделать снизу или сверху над полем для ввода текста опции-радиокнопки:
(o) по имени | ( ) по тексту | ( ) везде
Или как-то так. А то ищешь по названию игры, а тебе в список выводятся все игры, где в описании, например, слово "doom" встречается. Поиск по тексту и везде рекомендую оставить, потому что иногда помнишь код, но не можешь вспомнить как игра точно пишется, чтобы правильно её в поиске набрать и найти.
Из отдельных вещей, которые не могу не отметить:
1. Очень понравился дизайн - ничего лишнего, очень удобно, все элементы расположены именно там, где их и ожидаешь увидеть. Также как и цветовая схема: важное более насыщенным цветом, второстепенные элементы чуть более блеклым.
2. Понравилось, что статистика есть: если загрузить несколько БД, то в списке указан размер как самой базы, так и количество игр в ней. А когда выбираешь игру, то указано сколько символов в описании (вертикальная точка в качестве разделителя хорошо смотрится - надо будет взять на заметку). Хотя вся эта статистика и мелочь (возможно, вообще, какая-то вещь оставшаяся от отладочного кода), но ужасно приятно и информативно.
3. Особый плюс, что работает даже на относительно старых Интернет обозревателях, а то я боялся, что без установки какой-нибудь супер-последней версии Google Chrome, которой для работы ещё и Windows 11 нужен, ничего работать не будет. В консоли (F12), кстати, тоже ошибок нет, что говорит о том, что код чисто написан. Очень круто! Эх, все бы так сайты делали. А то коммерческие сайты, за которые сумасшедшие деньги платят, так написаны, что кровь из глаз хлещет, а хобби-проекты люди за просто так делают, но получается настолько лучше, что даже сравнивать неудобно.
Автор: Shadeov Sep 13 2025, 14:22
QUOTE(-=CHE@TER=- @ Jul 13 2025, 00:41)

Несколько пожеланий
Спасибо, ценный фидбек!
По пунктам:- Заголовок сменил на **CheMax Decoder**.
- Поле поиска теперь не пропадает навсегда — при наведении место поиска раскрывается.
- При переключении игры контент прокручивается в начало (сброс позиции).
- Исправил зависание при выборе последней игры (баг с инерцией/виртуальным списком).
- Три полоски заменил на стрелку для скрытия панели и наоборот.
- Добавил кнопку с опциями поиска.
Что ещё сделал (технически коротко)
:- Поддержка мобильных версий — мобильная верстка и UX переработаны.
- Форма ввода пароля, если ни один из ключей не выдал валидный результат.
- PWA + офлайн (работает как обычный PWA — есть ограничения).
- Поддержка загрузки нескольких баз сразу.
- Интерфейс: выбор языка EN / RU.
- Улучшил клиентский движок, всё также — база хранится в IndexedDB и распаковывается прямо в браузере. Только со старой версией несовместимо, и оно не нужно было на самом деле.
- Сопоставляет хеши некоторый баз, чтобы сопоставить хеш и название платформы. Например, определит для какой консоли БД, хоть и не используется в UI сейчас. Также определяет тип, версию и язык базы.
- Добавил работу с браузерной навигацией (раньше не работали кнопки Вперед/Назад при переходе между играми или БД).
- Задизайнил красивую иконку.
Сайт: https://decoder.rechemax.ru/?ref=ctpax-x.org (скоро — интересное на https://rechemax.ru/?ref=ctpax-x.org).
Docker-образы и исходники выложу буквально на днях — дам здесь же ссылку сразу после релиза.
Автор: -=CHE@TER=- Sep 13 2025, 19:26
Ух! Огонь, получилось!
Из нового отдельно хочу вот эти пункты отметить - прям очень круто (по первому пункту - полезная штука, я что-то до неё не догадался, а вторая просто очень удобная вещь):
QUOTE(Shadeov @ Sep 13 2025, 14:22)

- Форма ввода пароля, если ни один из ключей не выдал валидный результат.
- Добавил работу с браузерной навигацией (раньше не работали кнопки Вперед/Назад при переходе между играми или БД).
Ещё несколько пожеланий, если можно:
1. Я смотрю сайт с Windows 7 x64 и обозревателя Eclipse R3dfox 135.0.1 x64 (современные возможности FireFox, но работает на Windows 7). Поле для поиска почему-то не постоянно, а исчезает, если крутить вниз. Чтобы снова появилось нужно прокрутить список вверх. Причём, что самое неприятное, поле для поиска ещё и кнопку интерфейса прокрутки вверх закрывает, так что на мышке где нет колеса, или оно сломано, список вверх прокрутить не получится.
2. Теперь очень странно идёт переключение игр: несколько раз меняется заголовок окна, содержимое тоже. Такое ощущение, что теперь переключение игр идёт с какой-то задержкой. В результате если ты промахнулся и не ту игру выбрал, а затем достаточно быстро выбрал какую надо, то окно будет с некоторым запозданием несколько раз менять содержимое и сверху заголовок окна тоже будет туда-сюда меняться, что сильно дезориентирует и ты некоторое время пытаешься понять ту ли игру тебе в конечном итоге показали. Может быть как-то сделать список неактивным, пока текущая выбранная игра не загрузится? Или, когда готово будет, обновлять всё сразу одним махом (и заголовок и содержимое)?
3. Залил 4 БД и потом, решив удалить лишние (старые), не нашёл как это сделать. В прошлый раз на сайте в списке БД на главной, вроде бы, была кнопка "X", которой можно было лишние БД подчистить.
4. Залил русскую БД 2.4 и английскую 3.6 (обе за 2004 год) - похоже, для них не было таблиц, потому что описания там выводятся обрезанные в начале и конце на полуслове, да ещё и не для тех игр. Ну, как бы, это, наверное, и не особо важно - всё же это старые версии. Может быть, просто как-то предупреждать, что БД расшифрована, но смещений нет? И выводить, не знаю, просто одним сплошным текстом, например? К сожалению, тут хороших вариантов в голову не приходит как лучше сделать, кроме как ограничить работу только с последними версиями БД.
5. Хотелось бы, чтобы при смене языка страница восстанавливалась как была: введённое в поиске слово, тип поиска, позиция в списке, открытая игра и позиция текста в ней. Сейчас всё сбрасывается. Не знаю насколько это технически сложно сделать.
6. Поиск по всем БД на главной я заметил только в последний момент. В интерфейсе просмотра уже выбранной БД его, походу, приткнуть негде. Как и с пунктом 4 не подскажу, увы, как тут лучше сделать. Функция полезная, которая будет сразу по всем БД искать, но вот куда её лучше поставить или оставить так - увы, не подскажу.
7. А ещё на главной странице, почему-то, если снизу щёлкнуть по иконке смены цвета или языка, то, такое ощущение, что справа появляется какой-то невидимый блок, потому что содержимое страницы сдвигается влево на пару пикселей. И, соответственно, возвращается назад, когда меню закрываешь, хотя ни одно их них на моём разрешении экрана (1024x768) за правый край не уходит.
8. А ещё какая-то странная штука произошла (увы, не смог воспроизвести и повторить): я набрал в поиске "Duke Nukem" (без кавычек) и начал по порядку тыкаться на игры в списке, когда дошёл до самой нижней, последней, у меня, почему-то, внезапно перегрузилась вся страница. Не понял что случилось, а повторить, увы, сколько не пытался, но так и не удалось.
А теперь к другим новостям.
Я обновил декодировщик на сайте до версии 1.3, что нового: поддержка расшифровки украинской версии программы (последняя была v3.2), а также файл со смещениями и именами игр для неё "ukr_3_2.txt". Обращаю внимание, что массив tmsk[] изменился - в разрешённые символы добавлены украинские буквы, чтобы проверка расшифровки формата файла проходила успешно.
Обновлённую версию декодировщика можно взять на сайте.
Украинскую версию можно найти на WebArchive: https://web.archive.org/web/20110916002823/http://www.chemax.ru/download/chemaxukr32.exe.
Автор: -=CHE@TER=- Sep 15 2025, 00:52
Так, обновил архив с утилитами на сайте ещё раз. Да, теперь там две утилиты. Новая называется "idxbuild.exe" и позволяет автоматически вытащить и построить таблицу индексов к БД. Для этого нужно сделать следующее:
1. Выкачать все интересующие версии программы отсюда: https://web.archive.org/web/*/https://chemax.ru/download/* (сразу предупреждаю, что там далеко не все версии сохранились).
2. Распаковать RAR-архив (если в WebArchive файл .RAR не сохранился, а только .EXE, то пропускаем этот шаг).
3. Вручную распаковать .EXE установщик при помощи утилиты innonp (https://innounp.sourceforge.net/). Устанавливать через оригинальный установщик настоятельно не рекомендую, потому что в некоторых версиях прячется Яндекс.Бар и прочее безобразие.
4. В распакованном установщике находим файлы "CheMax.exe" и "Cheats.dat" и кидаем туда же файл "idxbuild.exe", после чего запускаем его, жмём "ОК" на диалоговом окне и ждём пока он сам не откроет и не закроет программу.
5. Как только программа закрылась, то в том же каталоге должен будет появиться файл: "###_XX_Y.TXT", где
### - язык (ENG, RUS, UKR)
XX_Y - версия (например 20.8).
Индексные файлы будут отличаться от тех, что я выложил на сайте, потому что я из названий игр двойные пробелы убирал - считаю, что это опечатки. В программе мне их убирать лень было, поэтому так и осталось - сохраняется в том виде, в каком есть.
Сразу предупреждаю, что на всех версиях не тестировал - только на самой ранней что нашёл и самой поздней, поэтому возможны нежданчики. Так что проверяйте, чтобы в индексном файле последнее смещение было равно размеру файла "Cheats.dat" - это 100% гарантия того, что всё было извлечено верно.