Если однажды ты пpидя домой не сможешь войти в системy
с админскими пpавами - значит дети yже выpосли..

+--------------------------------------------------------------------------------------------------------------------------------[release: 03.08.04]----+
|
|
|
|
|
|
|
  _|_|    _|_|_|    _|_|    _|_|_|    _|_|    _|  _|    _|  _|_|    _|_|_|      _|  _|    _|  _|
_|      _|  _|  _|  _|  _|  _|        _|  _|      _|_|_|_|  _|  _|  _|        _|_|_|_|_|  _|  _|
_|      _|_|_|_|_|  _|  _|  _|_|      _|_|    _|  _| |  _|  _|_|    _|_|_|      _|  _|      _|_|
_|      _|  _|  _|  _|  _|  _|        _|      _|  _|    _|  _|          _|    _|_|_|_|_|      _|
  _|_|    _|_|_|    _|_|    _|_|_|    _|      _|  _|    _|  _|      _|_|_|      _|  _|        _|
|
|
|
|
|
|
|
+-------------------------------------------------------------------------------------------------------------------------------------------------------------+
+--------------------------------------------------------------[0x05: Games в раzрезе]-------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

Сегодня мы поговорим об игрушках. Да-да, именно о них, родимых. Бывает так, что купил игрушку, вставил диск в CD-ROM, установил ее, а затем очнулся на утро следующего (или не следующего) дня. Честно говоря, рассказывать о магии игр можно долго. Но наша задача заключается в препарировании криво написанных игр. Можно отложить в сторону твой любимый ArtMoney, SoftIce, Advanced HEX Editor и приняться потрошить игрушку непосредственно.

Помнится, играл я как-то раз в очень простую, но очень интересную игру. Ее название я, естественно, не помню. Игра была про войну. Ты находишься на каком-то острове в какой-то башне с круговым обзором, у тебя есть несколько видов оружия и боеприпасы к ним. А над тобою пролетают самолеты, мимо тебя проплывают корабли, на твой остров высаживается десант... На определенном этапе я никак не мог сбить 5 юнкерсов, выходило максимум 4. Пришлось поковырять саму игрушку. Оказалось, что описания всех миссий лежат в ini-файлах открытым текстом. Я подредактировал количество самолетов, которое необходимо сбить для прохождения миссии. А потом понеслось... Пулемет стал бить на гораздо большие расстояния и наносить урон в десятки раз больший, самолеты летели один за одним, а нужно было сбить 5-6 и т.д. Я изощрялся довольно долго, до тех пор пока... не прошел игру. Вот такая история... Ну а сейчас мы приступим к препарированию другой, более популярной игры. Итак, игрушка жанра квест, изданная далеко не вчера, "ГЭГ-2".

Честно говоря, в первый "ГЭГ" я не играл, поэтому не могу сравнить продукты двух разных команд, выпущенных под одним лейблом. Главное, что препарируемая игра сделана настолько плохо (или хорошо, если посмотреть с другой стороны), что из нее можно сотворить что угодно: от пародии на нее саму до нового квеста.

Начинаем разбирать игрушку.
Посмотрим, какие файлы мы можем редактировать непосредственно с помощью "блокнота" (хотя я предпочитаю "бред"):
?map.vco - описание сцен, комнат, размещения предметов (? заменяет число от 1 до 12, остальные значения не тестировал)
sequences.dat - описание действий
sound.dat - распределение звуков и фоновых шумов по локациям
В папках graph и sound лежат картинки (форматы BMP и JPG) и звуки (формат WAV) соответственно.
Нам пока этого достаточно, т.к. материала для изучения довольно много.

Начнем с самого интересного - описания действий. Здесь был использован скриптовый язык, напоминающий c/c++.
Всякое действие начинается с ключевого слова begin и заканчивается ключевым словом end. Далее идет описание типа действия: просмотр, клик, комбинирование предметов, использование правильного или неправильного предмета. А затем описывается результат самого действия. Т.е. мы имеем схему:
begin
<описание типа действия>
<результат действия>
end
В тексте скрипта могут использоваться комментарии (/* */).

Просмотр описывается следующим образом:
view <номер сцены (sn)> <3 числа (ln1,ln2,ln3) - номер локации>
Стоит заметить, что изображение данной локации будет лежать по адресу graph\sn\ln1_ln2_ln3.jpg

Клик:
click <номер предмета (in)>

Комбинирование предметов:
comb <номер первого предмета (1in)> <номер второго предмета (2in)>

Использование правильного предмета:
item <номер действующего предмета (sin)> zone <номер принимающего предмета (din)>

Использование неправильного предмета:
Иногда требуется выполнить действие после неправильного применения предмета, например, предупредить об опасности неверного выбора (надеюсь, никто не станет засовывать ножницы в розетку).
wrong_item zone <номер принимающего предмета (din)>

Где прописаны все эти номера, я еще не знаю (надеюсь, к концу статьи я смогу это выяснить). Скажу одно: никакой защиты от внесения изменений не предусмотрено, поэтому можно творить практически что угодно.

Все скрипты построены на использовании условных операторов if и if_not, аргументами которых являются булевозначные флаги. Общий вид такого оператора:
if[<флаг>] {
 <действие 1>
 } else[] {
 <действие 2>
 }
Имя флага должно состоять из латинских букв и цифр, причем первым символом должна быть буква (хотя это не проверялось, но идентификаторы в большинстве компиляторов и интерпретаторов строятся именно по такому принципу).

Установка флага производится оператором set_flag[<флаг>], а его сброс - kill_flag[<флаг>].

del_item[<(in)>] - удаление предмета из инвентаря.

add_item[<(in)> <путь>] - добавление предмета в инвентарь. После добавления окно инвентаря не закрывается. Путь - путь к графическому файлу с изображением предмета из папки graph.

add_item[<(in)> <путь> break] - добавление предмета в инвентарь. После добавления окно инвентаря закрывается. Путь - путь к графическому файлу с изображением предмета из папки graph.

ch_view[<(sn_1)> <(ln1_1)> <(ln2_1)> <(ln3_1)> <(sn_2)> <(ln1_2)> <(ln2_2)> <(ln3_2)>] - замена одного вида локации на другой. Например, при построении пирамиды из 3х кубиков, на применение 1го кубика можно поменять пустой фон на фон с одним кубиком, аналогично и для других кубиков.

ch_anim[<(sn)> <(ln1)> <(ln2)> <(ln3)> <путь_1> <путь_2>] - замена анимации. Статической картинкой считается анимация, состоящая из одного фрейма. Например, после применения скорпиона на тиски, их вид дополняется торчащим жалом скорпиона. Путь_1 - путь к меняемой картинке из папки graph, путь_2 - путь к меняющей картинке из папки graph, (x,y) - координаты места, куда следует поместить картинку.

ch_zone[<(din_1)> <(din_2)>] - замена предмета первого предмета на второй (например, закрытой двери на открытую).

jump[<(sn)> <(ln1)> <(ln2)> <(ln3)>] - переместиться в выбранную локацию.

wav[<имя_звукового_файла> $] - проигрывание звукового файла, следующее действие задерживается до конца выполнения этого.

wav[<имя_звукового_файла>] - проигрывание звукового файла с параллельным исполнением следующего действия.

avi[<имя_видеофайла>] - проигрывание видеоролика. Все видеофайлы запакованы в video\video.dv.

pop[<имя_звукового_файла>] - реплика попугая. При этом с плеча свешивается попугай. Кстати, вся анимация предметов, а также и попугая, выполнена в спрайтах, в формате BMP. Можно исользовать знак $ с результатом, аналогичным его использованию в функции wav.

anim[ <путь_к_первому_фрейму> <количество_фреймов> wait] - проигрывание анимации. Может использоваться и без wait, назначение этого ключевого слова мной не было определено.

kill_point_sound[<(sn)> <(ln1)> <(ln2)> <имя_звукового_файла>] - удаление заданного фонового звука в локации.

add_point_sound[<(sn)> <(ln1)> <(ln2)> <имя_звукового_файла> <относительная_громкость>] - добавление заданного фонового звука в локации. Относительная громкость - отрицательное число, обычно кратное 100.

close_inv[] - закрыть окно инвентаря.

Теперь обладая знанием этого скриптового языка можно открыть "упрямую" дверь, получить любой предмет, заставить глюки появляться постоянно (особенно относится к доске почета завода 8))).

Формат файла sound.dat еще проще, чем лом в разрезе:
<(sn)> <(ln1)> <(ln2)> <относительная_громкость> <имя_звукового_файла>

Т.е. таким образом мы можем положить любые фоновые звуки на любую локацию.

Остается загадочным формат записи информации о предметах, находящихся в конкретной локации. За это отвечают файлы ?map.vco. Например, неизвестно, есть ли альтернативы ключевому словосочетанию original cursor, что означают числа в area 1 140 124 484 (возможно, второе и третье числа - координаты левого верхнего угла предмета по x и y), что обозначает ключевое слово bong, почему используется только размер size - 100 100.

А теперь поговорим о некоторых ляпах программистов из SGsoft:
begin /*попытаться сунуть арканоида в комп директора*/
 item 15 zone 8
	if_not[noCD]
		{
		 set_flag[noCD]
	 	 pop[p_nocd.wav]
		} else[]
		       {
			if_not[noCD2]
				{
				 set_flag[noCD2]			
				}
		       } else[]
			      {
			       kill_flag[noCD]
			       kill_flag[noCD2]	
			      }
end
Как мы видим, тут мы на каждый третий раз напоминаем, что в компьютере директора нет CD-ROM'а. Тут представлен несколько запутанный текст подпрограммы. Можно было бы сделать текст более читаемым и снизить нагрузку на интерпретатор, только сообщение будет возникать каждый второй раз (но это некритично):
begin /*попытаться сунуть арканоида в комп директора*/
 item 15 zone 8
	if_not[noCD]
		{
		 set_flag[noCD]
		 set_flag[noCD2]
		 pop[p_nocd.wav]
		} 
	if_not[noCD2]
		{
		 kill_flag[noCD]
		}
	kill_flag[noCD2]
end
А вот файлик video/video.dv имеет формат streamed data library v0.3. С этим мы разберемся немного позже. Я предлагаю каждому читателю самостоятельно поэкспериментировать над игрушкой. Первостепенных задач несколько: выяснить, где и как хранятся номера предметов, где и как хранятся переходы с одной локации на другую, найти способ распаковки файла с видеороликами, выяснить назначения файла 0B340A19.fil (или аналогичного ему) на диске (хотя есть подозрения, что он относится к системе защиты Gefest). Результаты можно присылать на почтовый ящик журнала, мы их обязательно опубликуем.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+-----[content]-----------------------------------------------------------------------------------------------------------------------------[mail us]-----+