ВНИМАНИЕ! Наша конференция посвящена космической тематике и компьютерным играм. Политические вопросы и происходящие в мире события в данный момент на нашем сайте не обсуждаются!
|
» Структура данных X-Tension | страница 8 |
|
|
|
Канал X-Tension/X-BTF: «Структура данных X-Tension» |
|
|
Perseus
888 EGP
       Рейтинг канала: 4(87) Репутация: 158 Сообщения: 2122 Откуда: Челябинск Зарегистрирован: 13.02.2002
 |
|
Молодца!
|
|
|
Рыб
1242 EGP
     Рейтинг канала: 3(36) Репутация: 340 Сообщения: 7461
Зарегистрирован: 05.06.2001
 |
|
To Blueboar: слушай, надеюсь ты ковыряешься в оригинальном экзешнике верси 2.1 (2.1а), а не в более ранней или какой-нить хитро-локализованной, а то ведь в них адреса могут отличаться как в EXE, так и в OBJ.
Да, чуть не забыл - .
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
OBJ-файл у меня от Shaddie, он вроде говорил,
что от версии 2.1
EXE - тоже вроде от нее же, скачивал на каком-то
сайте, посвященном X-TENSION.
Для уверенности можете выслать мне эти файлы
той версии, которой пользуется большинство народу
на почту.
|
|
|
Рыб
1242 EGP
     Рейтинг канала: 3(36) Репутация: 340 Сообщения: 7461
Зарегистрирован: 05.06.2001
 |
|
Blueboar : |
Для уверенности можете выслать мне эти файлы той версии, которой пользуется большинство народу на почту.
|
Сегодня вечером дома поставлю оригинальную eng-версию, пропатчу до 2.1а и завтра с утра вышлю.
Кста, насколько реально вытянуть и расшифровать скрипт, который отвечает за отсылку компового транспортника за ресурсами?
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Проблема в том, что пока абсолютно неизвестно,
какой скрипт вызывается при каком событии.
Если это узнать, то, я думаю, расшифровка всех
скриптов заняла бы от силы неделю - две.
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Сделано еще одно открытие. Я узнал, зачем нужен файл PCH (например 001.PCH). Правда, не совсем понятно, почему тогда нет 002.PCH, но разберемся.
Ответ: 001.PCH указывает количество стека после выполнения каждой команды в 001.OBJ. Вопрос «Зачем, можно ведь и так узнать» не принимается – я не знаю! Но факт есть факт.
Итак, откроем 001.PCH. В начале, как и принято, имя секции ‘STCK’. Потом, тоже в соответствии со стандартом 4 байта длины секции (которая кстати единственная в файле). Так вот, длины в PCH и OBJ файле одинаковы. Это означает, что сколько в OBJ команд, столько же записей и в PCH.
Ну что ж, выпишем первые данные из того и другого файла:
OBJ: 0000-0055-20EC-0009-0001-0828-0002-013B-B1B9-000B-002F-0002
PCH: FFFF-0000-FFFF-0000-0001-FFFF-0002-FFFF-FFFF-0003-0004-0002
Проверяем. В OBJ – файле первая команда 0000 не используется (да такой и нет). Если посмотрите в секцию SYMB, то увидите, что первая подпрограмма с адреса 0001, а не 0000, то есть эти два байта пропускаются. В PCH – FFFF, да, я думаю, могло быть все что угодно, все равно это никогда не выполнится.
Далее 0055-20EC. Выделить 20EC ячеек локального стека. В PCH – 0000-FFFF. FFFF, как вы помните, означает, что данная ячейка никогда не выполнится. И действительно, данные сами по себе не выполняются, а существуют лишь как часть команды. Под 0055 написано 0000. Это означает 0 ячеек стека. Это само собой разумеется, так как подпрограмма только начала выполняться, и, естественно, стека пока нет.
Следующая команда 0009 – сохранить «0» на стеке. Под ней тоже 0. Потому что команда 0055 стек-то выделила, но он еще ничем не заполнен. Обратите внимание, что команда 0009 записывает одно значение в стек, потому под следующей командой 0001-0828 уже написано «0001», что означает, что в стеке уже есть одно значение- ноль.
Под 0828 – FFFF, то есть это данные. И вообще, про данные я больше говорить не буду, под ними всегда FFFF. В следующей команде 0002-013B-B1B9 записано 0002. Правильно, так как предыдущая команда 0001 записала еще одно значение.
В команде 000B уже 3 значения стека, так как команда 0002 записала еще одно. И, наконец, в команде 002F – 4 значения, так как еще записала команда 000B. А вот после команды 002F значения стека уже 2. Почему? А прочитайте описание команды 002F! Последнее значение в стеке (000B = PUSH 00000002) – количество параметров. Она их куда-то записывает, и из стека, соответственно, удаляет, стека остается 4-3=1 (как вы понимаете, количество параметров тоже удаляется). Но один параметр записывается – идентификатор, позволяющий адресовать эти данные. Так что стека становится не 1, а 2 ячейки. Поэтому в следующей команде и записано 0002.
Интересно, а зачем в EGOSOFT все это нагородили? На первый взгляд от данного файла никакой пользы, ну, кроме, может быть, проверки правильности выполнения скрипта. Ну, можно еще узнать, сколько стека нужно передать каждой ассемблерной подпрограмме сравнив стек до и после ее вызова.
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Если кто-нибудь из вас программировал на
C++, то вы знаете, что там есть функция
printf, которой можно форматировать строку,
причем все форматирование включается после
символа %. В X-TENSION тоже есть такие
символы, например %d, %f, %x. Описания по С
у меня нет, может кто-нибудь напомнить, как
все это работает?
|
|
|
Рыб
1242 EGP
     Рейтинг канала: 3(36) Репутация: 340 Сообщения: 7461
Зарегистрирован: 05.06.2001
 |
|
ссылка
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Итак, продолжаем раскапывать команды скриптов. На этот раз у нас одна новая команды, кроме того, две команды (0029&002B) получили новые значения.
0004 Прочитать переменную номер XX (данные) из секции VARS
0029 Записать переменную номер XX (данные) из секции VARS. В обоих случаях значение берется & помещается в стек. Если данные записываются, из стека они не пропадают
0006 Прочитать слово неизвестно откуда под номером XX (данные). То есть это как бы поле для временного сохранения разных данных.
002B Записать слово неизвестно куда под номером XX (данные). Потом его можно прочитать командой 0006.
Зачем нужно два метода записи значений неизвестно. Может быть в секцию VARS записываются переменные с именем (как вы помните, в сегменте VARS каждая переменная имеет имя), а остальные – командами 0006&002B?
Спасибо за информацию про C++. И вообще, кто-нибудь следит
за тем, что я делаю? А то впечатление, что народ просто
ждет, пока я накопаю чего-нибудь, что можно будет использовать,
а пока - пусть себе пишет, чего знает...
|
|
|
Рыб
1242 EGP
     Рейтинг канала: 3(36) Репутация: 340 Сообщения: 7461
Зарегистрирован: 05.06.2001
 |
|
Blueboar : |
Зачем нужно два метода записи значений неизвестно. Может быть в секцию VARS записываются переменные с именем (как вы помните, в сегменте VARS каждая переменная имеет имя), а остальные – командами 0006&002B?
|
Не знаю, могу предположить что одна пара команд работает со значением, а вторая - с указателем на значение.
Blueboar : |
И вообще, кто-нибудь следит за тем, что я делаю? А то впечатление, что народ просто ждет ...
|
Я слежу , только времени не хватает самому поковыряться .
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Я продолжал разбирать самые простые подпрограммы, теперь уже в 001.OBJ. Выяснил, что почти все они совпадают (в смысле в 001.OBJ есть почти все подпрограммы из 002.OBJ), причем не просто по алгоритмам работы, а по коду! Если в 002.OBJ было написано «прочитай число из ячейки 4», то в 001.OBJ читают из этой же ячейки, хотя, в принципе, могли выделить любую
Даже области STRG у них частично совпадают (некоторые одинаковые названия подпрограмм располагаются на одинаковом же смещении в обоих файлах).
Ну так вот. Я набрел на подпрограмму, которая берет число из стека (в норме, судя по подпрограмме, там должно быть число от 5 до 16 (10H), что соответствует командам 000E-0019), и в зависимости от числа возвращает другое число, по схеме:
000B, 000C 00010000
000D, 000F 00015000
000E 00030900
0008, 000A, 0010 000704D0
0005, 0006, 0007 00103B21
Кто-нибудь может сказать, может он видел где-то в игре эти числа, или просто догадается, что они означают? Подпрограмма называется «GetFixedValueFactor»
|
|
|
DF
300 EGP
   Рейтинг канала: 5(118) Репутация: 47 Сообщения: 478
Зарегистрирован: 06.09.2003
 |
|
Цитата: |
И вообще, кто-нибудь следит за тем, что я делаю?
|
Я слежу, но к сожалению слишком занят чтобы заниматься этими исследованиями. К сожалению ты опоздал с этим исследованием как минимум на год, в этом канале уже почти не осталось народа, все в X2 сбежали.
Вот что могу еще добавить:
Файл 002.obj не изменялся с версии 1.1 до 2.1, менялся только 001.obj, более того я думаю что интерпретатор скриптов пришел в неизменном виде еще из XBTF, т.к. я пробовал прицепить к XT 001.obj от XBTF, конечно ничего вразумительного не получилось, после старта игры был черный экран но игра не сбросилась и была слышна реакция на клавиши. К XT можно прицепить 001.pch от XBTF, игра нормально работает.
002.obj производит начальную инициализацию, менюшку в начале игры и т.п., короче не интересно. 001.obj загружается только при начале новой игры или загрузке сейва и непосредственно управляет игровым процессом.
*.obj явно писались на каком-то языке высокого уровня и затем были откомпилированы. На таких командах которые мы тут рассматриваем никто ничего не писал.
Вообще у эгософта встречаются такие решения, что думаешь: "да откуда они взяли этого программиста? Из числа мазохистов, отчисленных с первого курса? " Я уже перестал удивляться ихним причудам. Так что встретив какую-то непонятную хрень которая вроде как и вообще не нужна особо не пугайся.
После нового года я может займусь написанием компилятора/декомпилятора .obj. Так что просьба действия всех команд описывать условными обозначениями, т.к. словами не всегда бывает понятно и подробно описывать какие параметры как используются, что берется/записывается в стек, как он изменяется после выполнения команды. Также желательно придумать командам мнемоники на манер ассемблера.
_________________ По моему так. |
|
|
ASKirilL
1220 EGP
       Репутация: 302 Сообщения: 8209 Откуда: Москва Зарегистрирован: 21.03.2003
 |
|
Цитата: |
И вообще, кто-нибудь следит
за тем, что я делаю? А то впечатление, что народ просто
ждет, пока я накопаю чего-нибудь, что можно будет использовать,
а пока - пусть себе пишет, чего знает...
|
Постоянно читаю и вникаю.
НО времени хватает только на прочитать и подумать.
_________________ Павлов - собака. |
|
|
Shaddie
556 EGP
      Рейтинг канала: 6(438) Репутация: 118 Сообщения: 261 Откуда: Томск Зарегистрирован: 09.09.2004
 |
|
Blueboar : |
Кто-нибудь может сказать, может он видел где-то в игре эти числа, или просто догадается, что они означают? Подпрограмма называется «GetFixedValueFactor»
|
Очень похоже на подпрограмму определения начального значения внутреннего идентификатора объектов.
При выполнении команды 002F, последнее значение в стеке это количество параметров, следующие значение в стеке (оно же первый параметр) это идентификатор типа объекта. Идентификатор типа объекта принимает значения (в стеке) от 1 до 17 (подробнее здесь).
Получается:
0005, 0006, 0007 00103B21 - станция тип 1, станция тип 2, корабль;
0008, 000A, 0010 000704D0 - товар групп 8 (Weapons), 10 (Missiles), 16 (то, что можно установить на корабль);
000B, 000C 00010000 - товар групп 11 (Energy Cells), 12 (Ship??? – не используется);
000D, 000F 00015000 - товар групп 13 (Delexian Wheat, Argnu Beef, Plankton, BoGas и т.п.), 15 (Ore, Silicon Wafers)
000E 00030900 - товар группы 14 (Cloth Rimes, Meatsteak Cahoonas, Space Fuel, Stott Spices, BoFu и т.п.).
То есть в зависимости от типа объекта формируется внутренний идентификатор: начальный внутренний идентификатор + текущее количество объектов этого типа. После выполнения команды 002F в стек записывается значение внутреннего идентификатора.
Правда из этой схемы выпадает товар группы 9 (Shield), для него, я думаю, FixedValueFactor должен быть 000704D0.
Немного статистики.
В оригинальном XT следующие количество объектов (без учета 2 секторов добавляемых после выполнения миссии «Пересей»):
Секторов – 90
Планет – 112
Солнц – 132
Астероидов – 816
Станций – 1099
Товаров – 5212
Кораблей – 10656
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
To Shaddie: Возможно. Кстати, значение 0012 (тип 0009) не то, что не встречается, оно есть, но оно НЕ ВЫПОЛНЯЕТСЯ. То есть в программе оно присутствует, но программа доходит до его начала, потом GOTO в конец и выполняется дальше. Если бы оно выполнялось, то ты прав, было бы 000704D0.
To DF: А если эту конференцию сейчас EGOSOFT читает? Они ж в суд на тебя подадут…
To Рыб: Я могу дать все названия подпрограмм & переменных, если там найдете подходящее название для отправки кораблей на станции, будем разбирать конкретно ее.
Так, разбирал я подпрограммы дальше, и оказалось, что моя первая такая не одна, вот еще подпрограммы, преобразующие одно в другое: Первая (даны коды команд, значения получите, отняв 9):
000B, 000D, 000F 00000001
000E 00000002
0010 00000004
Остальное 00000047
Коды есть еще для 11,12,13,E,F,10,15 но не используются. Для A и C кодов нет вообще (или плохо искал). Название: подпрограммы «GetValueFactor»
Еще одна такая же с названием «GetNumSubTypes»
10 7 00000047
E 5 0000000F
F 6 000000B3
16 D 0000000B
14 B 00000002
17 E 0000000B
18 F 00000002
15 C 00000001
19 10 0000002A
9 0 0000000B
12 9 00000004
11 8 00000009
13 A 00000007
D 4 0000000D
1A 11 00000003
1B 12 00000005
1D 14 00000014
Есть еще 3 такие подпрограммы, но разберемся сначала с этими. Но названия дать могу: «GetDialogFactoryRace» - судя по всему берет номер диалога при посадке на станции разных рас, «GetDialogRaceID», «GetDialogFactoryTypeID»
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Итак, я сочинил прогу на Паскале, которая выковыривает весь
STRG из OBJ файла и его расшифровывает, записывая в файл.
Напустил ее на 001.OBJ что прислал мне Shaddie, и получил
результат, который сохранил в WWW.Ссылки на narod.ru запрещены! Используйте пожалуйста другие, более нормальные хостинги.\
\XT.RAR.
Подпрограмм много, около 50 страниц, но мне больше всего
понравилось что-то типа 'CreateGetsuFuneSector'
Выбираем подпрограмму для исследования...
|
|
|
Shaddie
556 EGP
      Рейтинг канала: 6(438) Репутация: 118 Сообщения: 261 Откуда: Томск Зарегистрирован: 09.09.2004
 |
|
Blueboar : |
Подпрограмм много, около 50 страниц, но мне больше всего понравилось что-то типа 'CreateGetsuFuneSector'
Выбираем подпрограмму для исследования...
|
Круто!
BuildTradingStationInGetsuFune - я даже знаю где она находится .
|
|
|
Рыб
1242 EGP
     Рейтинг канала: 3(36) Репутация: 340 Сообщения: 7461
Зарегистрирован: 05.06.2001
 |
|
О как! Закачал, после обеда почитаю .
|
|
|
Blueboar
125 EGP
  Рейтинг канала: 2(12) Репутация: 20 Сообщения: 47 Откуда: Курган Зарегистрирован: 01.12.2004
 |
|
Кто заказывал BuildTradingStationInGetsuFune?
Получайте все, что накопал.
-----------------------------------------------------
Sub BuildTradingStationInGetsuFune
AE970 0055-0004 MAKE 4 STACK
AE974 0005-0004 PUSH SP[4]
AE978 000F PUSH 00000006
AE97A 000B PUSH 00000002
AE97C 003C UNKNOWN
AE97E 0057-0000-974E CALL 'ADD_125MW_FACTORY'
AE984 002C POP
AE986 0009 PUSH 00000000
AE988 0035 RET
-----------------------------------------------------
Как видите, в подпрограмме BuildTradingStationInGetsuFune
нет ничего сложного. Всего лишь вызывается подпрограмма
ADD_125MW_FACTORY, которая, видимо, добавляет фабрику в
данный сектор. Вопрос доставляет лишь команда 003C, еще
не опознанная. Потому будем считать, что со стеком она
не делает ничего (хотя скорее всего делает, но мы все
равно не знаем чего)
Вот подпрограмма ADD_125MW_FACTORY. Сначала она читает
оба параметра из стека, затем к последнему добавляет 1,
потом сохраняет еще 2 значения - число, сохраненное под
номером [0026] - думаю его сохранили, когда создавали
сектор GetsuFune, и там хранится его идентификатор, и
константу 00000001. Потом вызывается подпрограмма
GetDockPoint - нестандартным образом, командой 0058. Про
нее я уже в форумах говорил.
Потом командой 002D записывается новое значение
для идентификатора в стеке (вы помните, там значение
из переменной [0026], так как константа 1 будет убрана
оттуда подпрограмой GetDockPoint), по смещению второго
параметра (был 0006 и еще добавили 1 стало 0007). Это
значение равно третьему параметру - 0002. Неизвестно, как
это влияет на космос, но видимо при добавлении этих
данных появляется новая станция - тут уже дело за Shaddie,
знатоком идентификаторов всего чего только можно идентифицировать.
-------------------------------------------------------------------
Sub ADD_125MW_FACTORY
F14B0 0055-0004 MAKE 4 STACK
F14B4 0005-0005 PUSH SP[5] ;FIRST PARAM (0002)
F14B8 0005-0005 PUSH SP[5] ;SECOND PARAM (0006)
F14BC 000A PUSH 00000001
F14BE 003E ADD ;SECOND PARAM+1 = 0007
F14C0 0006-0026 READ [0026] ;NUM OF OBJECT?
F14C4 000A PUSH 00000001
F14C6 0058-0001-738B-0000-A05D ?CALL 'GetDockPoint'
F14D0 002D CHANGE_WRITE_OBJECT
F14D2 002C POP
F14D4 0009 PUSH 00000000
F14D6 0035 RET
--------------------------------------------------------------------
Вот подпрограмма GetDockObject. Написана судя 6по всему идиотом.
(если идиот не я). Судите сами. Сначала сохраняется второе значение
в стеке - помните, первое было константой 00000001, а второе -
прочитанное из переменной [0026]. Потом третье значение в стеке
становится равным первому (которое мы только что сохранили, и в
котором значение переменной). Потом два значения из стека выбрасываются,
а первым становится то, которое было третьим (которое мы предыдущей
командой туда записали - значение переменной [0026]).
Вопрос: Зачем городить огород, если можно было просто не
сохранять константу в предыдущей подпрограмме, и не вызывать эту?
----------------------------------------------------------------
Sub GetDockObject
2FD1E 0031-0001-7F35 GOTO 2FE72
----------------------------------------------------------------
2FE72 0005-0002 PUSH SP[2]
2FE76 002A-0003 SP[3] = [SP]
2FE7A 002E-0002 POP 2 TIMES
2FE7E 0035 RET
----------------------------------------------------------------
|
|
|
Рыб
1242 EGP
     Рейтинг канала: 3(36) Репутация: 340 Сообщения: 7461
Зарегистрирован: 05.06.2001
 |
|
Думаю, что квесты - одна из важнейших задач наравне с редактированием карты, так что может стоит в этом направлении покопать.
Просмотрел список процедур, только по названиям сложно что либо сказать:
TestQuest - непонятно, возможно проверяет текущий приоритет квеста и шанс его дачи.
CheckQuest - по названию, аналогичен предыдущему.
FindQuest - возможно, ищет квест по набору параметров (в станции, в космосе, время и т.п.)
EnableQuest - опять же, предположительно, включает/выключает определённые квесты при смене окружения.
RegisterQuest - ???
SetCurrentQuestToMinPriority - почти на 100% - вызвается по факту предложения квеста.
SetQuestStartTime - тут тоже вполне понятно.
Помню была инфа, что при запуске экзешника ему можно ключом подцепить дополнительный файл с квестами, соответственно если бы удалось найти то место где лежат квесты и разобрать его структуру, то можно было бы делать отдельные файлы с квестами.
|
|
|
|
|
|
Канал X-Tension/X-BTF: «Структура данных X-Tension» |
|
К списку каналов | Наверх страницы |
Цитата не в тему: Один дуэлянт не успел появиться, а зачинщик уже с секундантами передрался. (СПА)
|
» Структура данных X-Tension | страница 8 |
|