Руководство по созданию плагинов для игры Компьютерная эволюция 4
  1. Введение
  2. Формат плагинов
  3. Настройка Delphi
  4. Настройка Visual C++ .NET
  5. Описание функций
  6. Принципы работы со значениями в главной программе
  7. Значения элементов массивов
  8. Пример плагина на Delphi
  9. Пример плагина на Visual C++i
  10. Установка плагина
  11. Обратная связь

Введение

Начиная с версии 3.3 Beta 1 в игре появилась использовать плагины. Плагины - набор расширений к игре. Они добавляют новые возможности в игру, могут изменять ее ход и т.д.

Примечание 1: здесь и далее будут рассматриваться примеры плагинов для текущей версии (на данный момент текущей версией является 4.0.3). Это связано с тем, что в более ранних версиях могли быть найдены ошибки или недоступны некоторые параметры.
Примечание 2: Рассматриваемый здесь материал рассчитан на человека знакомого с языком программирования Object Pascal или С++, в частности с системой проектирования прикладных программ Delphi или Visual Studio. Также очень желательны навыки работы с указателями и функциями.
Примечание 3: Написанные плагины несовместимы с версиями игры ниже 4.0.3.
Примечание 4: Поскольку в программе для строк используется тип данных shortstring - запись в строковые параметры для Visual C++ невозможна. А чтение строк должно начинаться не с нулевого символа, а с первого. Однако если вы используете Borland C++ Builder, то вместо создания типа char*, можно создать тип shortstring*, тогда запись в строковые параметры будет возможна..



Формат плагинов

Все плагины должны быть сделаны в виде динамических библиотек. То есть иметь расширение dll. Другие форматы плагинов будут проигнорированы.



Настройка Delphi

Создание плагина в Delphi начинается с создания DLL. Создайте DLL и сохраните проект в папку Plugins, которая находится там, где вы установили игру. Можете нажать Ctrl+F9, чтобы убедиться, что был создан файл имя_вашего_проекта.dll. Поскольку в момент загрузки плагина ему передается управление, то неплохо было бы автоматически запускать игру и во время передачи управления плагину отслеживать возникающие события. Это даст возможность ставить точки прерывания и выполнять плагин по шагам. Активизируем данную возможность. Для этого в Delphi выбираем пункт Run -> Parameters.... В появившемся окне устанавливаем следующие параметры: Host Application - путь_к_исполняемому_файлу_игры; Working Directory - папка_где_у_вас_установлена_игра. На рисунке справа показано данное окно.











Настройка Visual C++ .NET

Создайте DLL с использованием библиотек MFC и сохраните проект в папку Plugins. Теперь откройте окно свойств проекта (Project -> Имя_проекта_Properties). На рисунке слева показано окно настройки проекта. В разделе Debugging, параметр Command, укажите путь к exe файлу игры. А параметру Working Directory присвойте путь к каталогу игры. В разделе Linker -> General установить параметр Output File равным имя_проекта.dll.



















Описание функций

В плагине обяхательно должны присутствовать две функции. Одна из функций - данные об авторе. Другая - управляющая функция. Описание первой функции выглядит следующим образом:

function PluginAuthor:Pchar;
begin
   PluginAuthor:='||';
end;

Для Visual C++ это будет выглядеть так:

extern "C" __declspec(dllexport) char* PluginAuthor(void)
{ return "||"; }
Здесь функция имеет пустой список формальных параметров и возвращает только один единственный параметр - данные об авторе. Этот параметр состоит из 3-х секций, каждая из которых разделяется знаком '|'. Первая секция - Имя автора плагина. Вторая секция - E-mail автора плагина. Третья секция - краткое описание плагина.
Вторая функция выглядит так:
function PluginExec(I,R,S,B:pointer;ISize,RSize,SSize,BSize:integer):boolean; stdcall;
begin
   PluginExec:=true;
end;
И соответственно функция на Visual C++:
extern "C" __declspec(dllexport) __stdcall PluginExec(void *I, void *R, void *S, void *B)
{ return true; }
В отличие от предыдущей функции данная функция имеет несколько формальных параметров и возвращаемый параметр типа boolean (bool для Visual C++). Первые четыре формальных параметра в функции имеют тип Pointer (указатель без типа - void *). Это указатели на массив указателей: I - указатель на массив указателей на тип integer (int); R - тип real (double); S - тип shortstring (char*); B - тип boolean (bool). Параметры типа integer это длины соответствующих им массивов: ISize - длина массива указателей на тип integer; RSize - тип real; SSize - тип shortstring; BSize - тип boolean (для Visual C++ данные параметры необязательны). Данная функция возвращает в главную функцию значение true или false. True свидетельствует о том, что плагин выполнился нормально. Если вы используете в исходном коде блоки try и except, то в зависимости от ситуации передавайте значение true или false.



Принципы работы со значениями в главной программе

Понятно, что создание плагинов было бы бессмысленным, если бы они не меняли какие-то значения в главной программе. Для доступа к значениям хранящимся в главной программе необходимо объявить имена типов указателей на массивы и произвести операцию разыменования. Рассмотрим, как это делается:

type
   IntMas=array of ^integer;
Данная запись создает тип IntMas, который является массивом указателей на тип integer. Аналогичные записи можно сделать и для других типов массивов:
RealMas=array of ^real;
StrMas=array of ^shortstring;
BoolMas=array of ^boolean;
Далее в теле функции PluginExec осуществляем следующие операции:
var
   Integers:IntMas;
begin
   setlength(Integers,ISize);
   Integers:=I;
Здесь мы объявляем переменную Integers типа IntMas. Задаем длину массива Integers(поскольку тип IntMas как раз и является массивом указателей), используя формальный параметр ISize. Аналогичную операцию проводим для остальных массивов:
var
   Reals:RealMas;
   Strings:StrMas;
   Booleans:BoolMas;
begin
   setlength(Reals,RSize);
   setlength(Strings,SSize);
   setlength(Bolleans,BSize);
   Reals:=R;
   Strings:=S;
   Booleans:=B;
Теперь можно работать со значениями, хранящимися в главной программе, используя операцию разыменования:
   Reals[0]^
Используя данную запись мы получаем значение (операция разыменование), которое хранится в массиве указателей на вещественные числа под номером 0 (нумерация всех массивов в плагинах должна начинаться с 0). Под номером 0 хранится рейтинг игрока. Таким образом, если мы к примеру напишем такую запись:
   ShowMessage(IntToStr(Reals[0]^));
...на экран выведется сообщение с текущим рейтингом игрока. Если же мы хотим изменить рейтинг игрока к примеру на 10 очков, то запись должна быть такой:
   Reals[0]^:=Reals[0]^+10;
В конце плагина, в разделе exports необходимо обязательно указывать имена функций PluginExec и PluginAuthor.
exports PluginExec, PluginAuthor;
Теперь вкратце рассмотрим реализацию на Visual C++:
typedef int* intp;
typedef double* realp;
typedef char* charp;
typedef bool* boolp;

IntMas=static_cast(I);
CharMas=static_cast(S);
RealMas=static_cast(R);
BoolMas=static_cast(B);

if (*IntMas[13]>90)
   MessageBox(NULL,"Отношение властей нормальное.","Сообщение из плагина",MB_OK|MB_ICONINFORMATION);
Кроме этого следует в .def файле проекта, в разделе EXPORTS прописать следующие строки:
PluginAuthor @1
PluginExec @2



Значения элементов массивов

Далее приводится таблица значений элементов массивов, которые можно использовать в плагинах.

   Целые числа
Номер элементаЗначение
0Текущий месяц
1Текущий год
2Текущий день
3Возраст игрока
4Сумма вклада в банке
5Процент вклада в банке
6Нумерация текущего статуса игрока:
   0 - человек
   1 - чайник
   2 - юзер
   3 - продвинутый
   4 - хакерок
7Количество записанных дисков CD-ROM
8Количество знаний по Assembler (аналогично C , Pascal и Basic):
   0 - ничего не знаете
   1 - вступили на курсы
   2 - прошли 1-й этап обучения
   3 - прошли 2-й этап обучения
   4 - Закончили обучение
9Количество знаний по Pascal
10Количество знаний по C
11Количество чистых дисков CD-ROM
12Количество написанных программ
13Отношение властей
14Скорость работы сканера
15Скорость печати принтера
16Безопасность монитора
17Скорость работы с интернетом
18Надежность ИБП
19Производительность процессора
20Производительность добавляемая при разгоне процессора
21Тактовая частота шины FSB
22Процент разгоняемости процессора
23Множитель на процессоре
24Температура процессора
25Частота вращения кулера
26Частота вращения шпинделя жесткого диска
27Объем жесткого диска
28Ежемесячная зарплата игрока
29Тактовая частота ядра на видеокарте
30Тактовая частота памяти на видеокарте
31Процент разгоняемости видеокарты
32Объем установленной на видеокарте памяти
33Производительность добавляемая при разгоне видеокарты
34Производительность видеокарты
35Производительность добавляемая при включении технологии Hyper Threading
36Скидка на винчестеры (если в магазине проходит акция)
37Скидка на видеокарты (если в магазине проходит акция)
38Скидка на процессоры (если в магазине проходит акция)
39Объем установленной оперативной памяти
40Тип установленной оперативной памяти (PC 2100, 2700, и т.д.)
41Скорость чтения дисков CD-ROM
42Скорость записи дисков CD-R
43Скорость записи дисков CD-RW
44Скорость записи дисков DVD-R
45Скорость записи дисков DVD-RW
46Скорость течения времени (часов в секунду)
47Количество взломанных Unix-машин
48Количество взломанных Windows-машин
49Количество арестов
50Степень неприятия к последней запущенной игре
51Количество испорченных при записи болванок
52Текущий час
53Время с момента последнего обновления антивирусных баз
54Производительность добавляемая после дефрагментации диска
55Сумма кредита игрока
56Процент кредита
57Количество дней до конца срока кредита
58Время в днях со времени последней дефрагментации
59Количество знаний по Basic
60Степень прозрачности главного окна
61Количество значий по программированию (общий рейтинг)
62Диагональ используемого монитора
63Количество предоплаченного трафика за интернет
64Температура видеокарты
65Ежемесячная стоимость размещения сайта на платном хостинге (0 - бесплатный хостинг)
66Ежемесячная квартплата
67Престиж купленного автомобиля
68Комфорт купленного жилья
69Размер активного раздела
70Свободное место на активном разделе
71Количество дней оставшихся до завершения обучения игрока программированию
72Язык изучаемый игроком на курсах программирования (56 - Basic; 57 - Pascal; 58 - Assembler; 59 - C++)

   Вещественные числа
Номер элементаЗначение
0Рейтинг игрока
1Деньги игрока
2Настроение игрока
3Напряжение на процессоре
4Сумма пени снимаемого с игрока при просрочке кредита

   Строковые параметры
Номер элементаЗначение
0Рабочая папка программы
1Имя игрока
2Чипсет материнской платы
3Чип видеокарты
4Тип разъема на материнской плате куда может быть установлена видеокарта
5Тип операционной системы(установленной на активном разделе)
6Тип разъема видеокарты для подключения к материнской плате
7Тип среды разработки(установленной на активном разделе)
8Дата последнего обновления антивирусных баз
9Имя последней запущенной пользователем игры
10Тип установленной оперативной памяти (DDR, DDR2 и т.д.)
11Адрес сервера обновления антивирусных баз
12Комментарий к сохраненной игре
13Метка активного раздела
14Файловая система активного раздела
15Операционная система установленная на активном разделе
16Установленная среда разработки(здесь и далее идут программы установленные в систему находящуюся на активном разделе, при том что сами программы могут быть расположены как на логических разделах, так и на активном основном)
17Установленный антивирус
18Установленный противоспамный фильтр
19Установленный брандмауер
20Установленная программа дефрагментации
21Установленная программа для работы с разделами жесткого диска
22Установленный браузер
23Установленный файловый менеджер
24Установленная программа для тестирования компьютера
25Установленная программа для копирования дисков
26Установленный аудио конвертер
27Установленный видео конвертор
28Установленная программа для разгона видеокарты

   Флаговые параметры
Номер элементаЗначение
0Имеет ли игрок самую престижную работу (начальник)
1Возможность записи DVD дисков
2Будет ли игроку предоставлено 100 Мб преоплаченного трафика за интернет при покупке модема (если в магазине проходит соответствующая акция)
3Делал ли игрок экстримальный разгон видеокарты
4Проходит ли игрок обучение на курсах программирования



Пример плагина на Delphi

library Test;

uses
   Dialogs, SysUtils;

{$R *.res}

type IntMas=array of ^integer;

function PluginAuthor:Pchar;
begin
   PluginAuthor:='Ревенков Павел|RPsoft@mail.ru|Тестовый плагин';
end;

function PluginExec(I,R,S,B:pointer;ISize,RSize,SSize,BSize:integer):boolean;
var
   MyMas:IntMas;
begin
   setlength(MyMas,ISize); MyMas:=I;
   ShowMessage('Тестовый пример плагина. Текущий месяц - '+IntToStr(MyMas[0]^));
   PluginExec:=true;
end;

exports PluginExec, PluginAuthor;

end.



Пример плагина на Visual C++

typedef int* intp;
typedef double* realp;
typedef char* charp;
typedef bool* boolp;

extern "C" __declspec(dllexport) char* PluginAuthor(void)
{ return "Ревенков Павел|RPsoft@mail.ru|Тестовый плагин"; }

extern "C" __declspec(dllexport) __stdcall PluginExec(void *I, void *R, void *S, void *B)
{
   intp *IntMas;
   charp *CharMas;
   realp *RealMas;
   boolp *BoolMas;

   IntMas=static_cast(I);
   CharMas=static_cast(S);
   RealMas=static_cast(R);
   BoolMas=static_cast(B);

   if (*IntMas[13]>90)
      MessageBox(NULL,"Отношение властей нормальное.","Сообщение из плагина",MB_OK|MB_ICONINFORMATION);

   return true;
}


Установка плагина

После того, как вы создали окончательный dll файл, сохраните его вместе с файлами необходимыми для работы плагина (картинки, музыка и т.д.) в папку Plugins, которая находится там, где у вас установлена игра.

Обратная связь

Если вам что-то непонятно в этом руководстве или вы хотите задать мне какие-то вопросы, пишите мне на e-mail: RPsoft@mail.ru