Как стать автором
Обновить

Работ с EVE API на Delphi

Введение в API


EVE API – это платформа, созданная для использования сторонними утилитами (программы, сайты и др.) для доступа к данным персонажа или корпорации, повышения опыта игроков EVE. Команда CCP решила раскрыть некоторые игровые данные с этой целью. Все данные защищены API ключами уникальными для каждого игрового аккаунта. (Читайте подробнее API keys.)
EVE API предоставляет большое количество различной информации сторонним приложениям. Более подробную информацию можно прочитать на английском языке по адресу: http://wiki.eve-id.net/API
Данные требующие проверки аутентификации можно получить, только передав HTTP запрос, содержащий значения userID и apiKey, выполнив POST или GET запрос к серверу. Значения userID и apiKey можно получить посетив соответствующий раздел на сайте EVE по адресу: http://myeve.eve-online.com/api/default.asp. В случае отказа аутентификации сервер вернёт сообщение об ошибке. Так же хочу добавить, что существует два типа API ключей — Limited Access и Full Access API key. По-умолчанию используются ограниченные ключи, которые предоставляют ограниченный доступ к данным аккаунта. Как правило, ограниченных ключей вполне достаточно для получения основных сведений о персонаже.



Используемые инструменты и библиотеки



При разработке тестовой программы я буду использовать IDE Delphi 7, компонент IdHTTP1 из состава стандартных Indy компонентов распространяемых вместе со средой разработки, компонент XMLDocument1 для парсинга полученного XML ответа от сервера, а также различные компоненты из состава Alpha Controls (http://www.alphaskins.com/) для создания красивого графического интерфейса программы.

Сразу отвечу, почему я выбрал для разработки IDE Delphi 7, а не какую-нибудь другую «более актуальную» среду разработки. У меня нет предрассудков и комплексов по-поводу разговоров в Интернете о несостоятельности Delphi как полезного инструмента для разработчиков. ИМХО Delphi (даже 7-й версии) вполне пригоден для разработки приложений любой сложности. Как говорится всё зависит от прямоты рук программиста.

Практика



Итак, приступаем непосредственно к созданию программы. Для начала необходимо нарисовать интерфейс приложения примерно как на картинке снизу. На форму необходимо добавить компонент Memo1 для вывода лог-сообщений программы, несколько кнопок для тестирования работы разных сервисов EVE API, компонент Image1 в котором будем отображать портрет персонажа полученного с сервера, так же я ещё добавил несколько контролов и формочку для настройки работы приложения через http-прокси. В-принципе работа через прокси для тестового приложения не обязательна. Мне пришлось добавить поддержку прокси в связи с тем, что мой друг сисадмин, которого я просил протестировать программу, выходит в Интернет через прокси и без этого программа у него не работала.

Итак, в результате у Вас должно получиться что-то вроде этого:

image

Теперь приступим к разбору непосредственно самого кода, отвечающего за работу с EVE API.

Первая кнопочка «Testing…» проверяет статус сервера и количество пилотов on-line:

procedure TMainForm.Button1Click(Sender: TObject);
var
mem: TMemoryStream;
begin
// Читаем из реестра настройки прокси (если она используется)
if ReadFromRegistry('\\HKEY_CURRENT_USER','Software\Trojan4ick\EVETools','UseProxy','0') = '1'
then
begin
idHTTP1.ProxyParams.ProxyServer := ReadFromRegistry('\\HKEY_CURRENT_USER','Software\Trojan4ick\EVETools','Proxy','');
idHTTP1.ProxyParams.ProxyPort := StrToInt(ReadFromRegistry('\\HKEY_CURRENT_USER','Software\Trojan4ick\EVETools','ProxyPort','3128'));
// Авторизация прокси
if (ReadFromRegistry('\\HKEY_CURRENT_USER','Software\Trojan4ick\EVETools','UseProxyAuth','0') = '1')
then
begin
idHTTP1.ProxyParams.BasicAuthentication := True;
idHTTP1.ProxyParams.ProxyUsername := ReadFromRegistry('\\HKEY_CURRENT_USER','Software\Trojan4ick\EVETools','ProxyUser','');
idHTTP1.ProxyParams.ProxyPassword := ReadFromRegistry('\\HKEY_CURRENT_USER','Software\Trojan4ick\EVETools','ProxyPass','');
end;
end;

mem := TMemoryStream.Create;
try
// Запрашиваем статус серевера EVE
idhttp1.Get('http://api.eve-online.com/server/ServerStatus.xml.aspx', mem);
//mem.SaveToFile(tmpdir+'\control.inf');
//ShowMessage(IntToStr(IdHTTP1.Response.ResponseCode));

// Парсим полученный ответ сервер и выводим информацию в более
// благоприятном виде.
EVEXML.Active := True;
EVEXML.Encoding := 'UTF-8';
// Загужаем из потока памяти полученный xml ответ сервера
EVEXML.LoadFromStream(mem);

if EVEXML.DocumentElement.Attributes['version'] = '2' then
begin
EVEMemo.Lines.Add('EVE API version: '+EVEXML.DocumentElement.Attributes['version']);
EVEMemo.Lines.Add('Текущее время по eve: '+EVEXML.DocumentElement.ChildNodes['currentTime'].NodeValue);
if EVEXML.DocumentElement.ChildNodes['result'].ChildNodes['serverOpen'].NodeValue then
EVEMemo.Lines.Add(Format('Сервер он-лайн. Пилотов(%s)',[EVEXML.DocumentElement.ChildNodes['result'].ChildNodes['onlinePlayers'].NodeValue]))
else EVEMemo.Lines.Add('Сервер офф-лайн.');
end else EVEMemo.Lines.Add(Format('Версия EVE API [%s] не поддерживается.',[EVEXML.DocumentElement.Attributes['version']]));
EVEXML.Active := False;
except
on E: Exception do
begin
EVEMemo.Lines.Add('Response: '+IntToStr(IdHTTP1.Response.ResponseCode));
EVEMemo.Lines.Add(Format('[%s] %s',[E.ClassName, E.Message]));
end;
end;
EVEMemo.Lines.Add('');
idhttp1.Disconnect;
mem.Free;
end;


Основные моменты в коде прокомментированы, наибольший интерес представляет строка:
idhttp1.Get('http://api.eve-online.com/server/ServerStatus.xml.aspx', mem);
Метод Get компонента IdHTTP1 посылает GET запрос к серверу по адресу, который передаётся первым параметром (http://api.eve-online.com/server/ServerStatus.xml.aspx'). В случае удачи ответ будет сохранён в переменную потока памяти (тип TMemoryStream) mem, которая передаётся вторым параметром. Ответ представляет из себя XML документ в кодировке UTF-8:

<?xml version='1.0' encoding='UTF-8'?>
2007-12-12 11:48:50
<row name="Mary" characterID="150267069"
corporationName="Starbase Anchoring Corp" corporationID="150279367" />
<row name="Marcus" characterID="150302299"
corporationName="Marcus Corp" corporationID="150333466" />
<row name="Dieinafire" characterID="150340823"
corporationName="Center for Advanced Studies" corporationID="1000169" />


2007-12-12 12:48:50


Чтобы получить информацию о статусе сервера, необходимо передать полученный XML документ для обработки компоненту XMLDocument1. Для этого соответствующим методом компонента загружаем xml документ из потока памяти (объект mem): EVEXML.LoadFromStream(mem); *

* XMLDocument1 в моём варианте программы называется как EVEXML.

В конечном результате после нажатия кнопки Testing… в логе должен быть выведен статус сервера, количество пилотов on-line и текущее EVE Time время. Для получения статуса сервера EVE не нужно использование API-ключей.

image

Следующая по списку кнопка «char». Этой кнопкой я получал список персонажей зарегистрированных на моём аккаунте. Для получения этих данных необходимо использовать API-ключи, которые можно посмотреть по приводимой ранее ссылке.
Код обработчика событий этой кнопки значительно короче по причине того, что здесь не используются настройки прокси и не производится парсинг xml ответа сервера. Основной целью было передать API-ключи серверу и успешное прохождение аутентификации.

procedure TMainForm.sButton3Click(Sender: TObject);
var
LoginInfo: TStringList;
Response: TStringStream;
begin
try
LoginInfo := TStringList.Create;
Response := TStringStream.Create('');
LoginInfo.Add('apiKey=Здесь вы указываете свой API-ключ');
LoginInfo.Add('apiKey=Здесь вы указываете свой API-ключ');
IdHTTP1.Post('http://api.eve-online.com/account/Characters.xml.aspx',LoginInfo,Response);
Showmessage(Response.DataString);
finally
begin
Response.Free;
LoginInfo.Free;
end;
end;
end;


Секрет колдунства заключается в одной строчке, в которой передаётся POST запрос к серверу:

IdHTTP1.Post('http://api.eve-online.com/account/Characters.xml.aspx',LoginInfo,Response);

Она отличается от метода Get объекта IdHTTP1 только количеством передаваемых параметров и их типом. Параметры заголовков POST передаются как список строк типа TStringList – объект LoginInfo. В формате POST заголовков это будет выглядеть как список строк:

apiKey=Здесь вы указываете свой API-ключ
apiKey=Здесь вы указываете свой API-ключ

Ответ сервера я не стал обрабатывать и просто вывел сообщение содержащее xml текст:

Showmessage(Response.DataString);

Кнопка «pics» работает точно также как и кнопка «Testing…», за тем исключением что методу Get необходимо передать ник персонажа, портрет которого Вы желаете получить:

idhttp1.Get('http://api.eve-nline.com/eve/CharacterID.xml.aspx?names='+sEditCharName.Text, mem);

Полученный портрет сохраняется в папке с программой и отображается компонентом Image1.

image

В принципе никаких сложностей в работе с EVE API нет, всё в конечном результате сводится к парсингу xml документа. Если у Вас возникли какие-либо вопросы в процессе прочтения статьи (а я думаю они возникли) смело задавайте их мне на почту: badboy.coder2010(собачка)gmail.com Кому нужны полные, исходные тексты программы так же прошу обращаться ко мне на e-mail. Спасибо за внимание, надеюсь статья оказалась полезной.

P.S.
Программа писалась в целях удовлетворения своих интересов и не является полноценным, рабочим вариантом, так что прошу не пинать.

На всякий случай приношу свои извинения за характер изложения статьи, этой мой первый раз.

Так же хотелось бы поблагодарить своего друга-сисадмина Сергея за помощь в небольшом тестировании программы.
Если кого-то заинтересовала моя статья, буду благодарен за инвайтик на мой любимый хабр.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.