Mit dem Mai Patch am 08.05.120 YC wird die alte XML-API von EVE abgeschaltet. Ab da an kann nur noch über die ESI Schnittstelle Daten abgefragt werden. Die meisten 3rd-Party-Anwendungen haben bereits umgestellt, sodass es nicht weiter auffallen sollte.
Wer nur kleinere Infos benötigt, dem reicht der Zugriff via GoogleDocs. Dort ist die direkte Einbindung der EVE-XML-API recht einfach mit Hilfe der Formel ImportXML(). Da die XML demnächst deaktiviert wird ist dieser Zugriff nicht mehr gegeben.
GESI ist eine Scriptbibliothek, die nicht nur die lesenden Bereiche von ESI abrufen kann, sondern auch die benötigte Authentifizierung via SSO übernimmt.
Die Ersteinrichtung erscheint etwas aufwendig, ist aber notwendig für die SSO-Anmeldung.
Zuerst eine neue Tabelle anlegen und am besten gleich einen Namen vergeben.
Anschließend im Menü den Scripteditor öffnen: Tools -> Scripteditor…
Im Scripteditor nun drei Dateien erstellen und den Inhalt von github reinkopieren (GESI.gs, endpoints.gs und function.gs).
Als nächstes muss eine Anwendung für EVE’s Single Sign On (SSO) angelegt werden. Die Anmeldung nutzt OAuth2, welche wiederum eine Rückrufadresse benötigt. Bei Google Scripts sieht diese in etwa so aus: https://script.google.com/macros/d/{SCRIPT_ID}/usercallback
Wobei {SCRIPT_ID} ersetzt werden muss durch die ID des aktuellen Projektes. Dazu im Menü auf Datei -> Projekteigenschaften klicken.
“Manage Applications” und “Create New Application”
Name und Beschreibung (Description) sind frei wählbar.
“Connection Type” auf “Authentication & API Access” einstellen
Permissions: prinzipiell alles aktivieren, was beginnt mit “esi-”
(wenn man nicht alles freigeben will, dann muss bei Punkt 7. noch etwas am GESI-Code geändert werden)
Wieder zurück im Googlescript noch ein paar Parameter anpassen:
CLIENT_ID = ‘YOUR_CLIENT_ID’;
CLIENT_SECRET = ‘YOUR_CLIENT_SECRET’;
Ersetzen mit den Daten der soben erstellten Anwendung auf https://developers.eveonline.com/
Achtung: Es hat einen Grund warum es “Secret” (Geheim) heißt – jeder der ClientID und ClientSecret kennt, kann Aufrufe im Namen des eigenen Charakters ausführen.
MAIN_CHARACTER = ‘YOUR_MAIN_CHARACTER_NAME’;
Durch den eigenen Charnamen ersetzen.
Wenn im Punkt 6. nicht alle ESI-Schnittstellen ausgewählt wurden, dann bei SCOPES die nicht aktivierten auskommentieren indem // an den Anfang der jeweiligen Zeile gesetzt wird. Mit /* und */ können auch mehrere Zeilen auskommentiert werden.
Anschließend nicht vergessen alles zu speichern (kein roter Stern mehr neben dem Dateinamen sichtbar). Das Projekt zu der Tabelle kann auch umbenannt werden, damit es später einfacher zu erkennen ist.
Fast geschafft. Nun muss der Tabelle noch die Erlaubnis gegeben werden (Authorisation), dazu das Dokument (bzw. den Tab) einmal neu laden. Nach ein paar Sekunden erscheind im Menü ein neuer Eintrag namens “GESI” darunter befindet sich die Option “Authorize Sheet”
Doch vorher greift eine Sicherheitsoption von Google, dass keine unerlaubten Skripte ausgeführt werden dürfen. Hier muss man also erst mit seinem Googleaccount der Tabelle gestatten Skripte auszuführen.
“Authorize with EVE SSO” wird auf die EVE Seite verwiesen wo man sich mit seinen EVEaccount einloggen muss. Anschließend wird noch einmal angezeigt welche ESI-Funktionen abgefragt werden und für welchen Charakter. Mit einem abschließenden Klick auf “Authorize” ist alles erledigt.
Anwendungsbeispiel
Um einen Einblick zu bekommen, welche Informationen die ESI liefert ist https://esi.tech.ccp.is/ eine erste Anlaufstelle.
Um die Entsprechung in GESI zu finden den gewünschten Pfad in ‘endpoints.gs’ suchen.
Der Name des Objektes (hier gelb markiert) ist die Formel für die Googletabelle.
Das Ergebnis der Abfrage wird direkt in die Tabellenzellen ausgegeben.
Die meisten Rückgaben der ESI erfolgen als ID. Um diese IDs in den entsprechenden Namen zu übersetzen kann eine weitere ESI-Abfrage ausgeführt werden (universe_types_type). Bei den Googletabellen gibt es eine tägliche Begrenzung für Webabfragen, daher empfiehlt es sich für umfangreichere Projekte die eine oder andere Tabelle aus dem Static Data Export (SDE) direkt als weiteres Tabellenblatt in das Dokument einzubinden und dann per vlookup() die entsprechenden Informationen wie Namen auszulesen.
Von Haus aus kann GESI nur lesend auf die ESI-Schnittstelle zugreifen. Anwendungsfälle wie Route/Wegpunkt setzen oder Marktfenster öffnen ist somit nicht möglich.
Mit einfachen (Tabellen-)Formeln ist dies auch nicht so einfach umzusetzen, da diese nicht eine Abfrage ausführen und dann fertig sind, sondern regelmäßig neu berechnet (neu abgefragt) werden. Ein Wegpunkt würde so bei jeder Neuberechnung neu gesetzt werden.
Aber mit Makros, die nur einmal durchlaufen, ist dies recht schnell umgesetzt. Man kann sogar die bestehende Architektur von GESI verwenden ohne eine eigene Anmelderoutine schreiben zu müssen.
Eine gewisse Grundkenntnisse von Makroprogrammieren wie z.B. bei Excel sind dabei Hilfreich.
Die Eingabe von “=characters_character_location()” als Formel in eine Tabelle löst die folgende Makrofunktion aus der “function.gs” aus:
/**
*Information about the characters current location. Returns the current solar system id, and also the current station or structure ID if applicable.
*@param {string} name Name of the character used for auth. If none is given, defaults to AUTHING_CHARACTER.
*@param {boolean} opt_headers Default: True, Boolean if column headings should be listed or not.
*@return Get character location.
*@customfunction
*/
function characters_character_location(name, opt_headers) {
return parseData_(arguments.callee.name,{name:name,opt_headers:opt_headers});
}
Diese Funktion wiederum teilt sich in mehrere Unterfunktionen. Grundlegend holt sie sich aber die Abfrage- und Ergebnisinfos von “character_location” aus “endpoints.gs”, bastelt zusammen mit in der Formel angegebenen Parametern eine Abfrage für EVE-ESI zusammen und nach erfolgter Abfrage gibt die Funktion noch das Ergebnis in die Googletabelle aus.
Der nur lesende Zugriff auf die ESI ist in GESI fest einprogrammiert. Um das zu beheben müssen zwei Funktionen angepasst werden. Dazu ist es einfacher diese zu kopieren und umzubenennen.
Zum einen “getData_” (umbenannt zu “getDataPOST_”) für die Erstellung de Abfragestrings und Anmeldefunktionen. Dort in der vorletzten Zeile das ‘get’ umändern zu ‘post’ und den Funktionsaufruf ändern zu “doRequestPOST_”.
function getDataPOST_(endpoint_name, params) {
var endpoint = ENDPOINTS[endpoint_name]
var path = endpoint.path;
var name = params.name;
if (!name) name = MAIN_CHARACTER;
endpoint.parameters.forEach(function(param) {
if (param[‘in’] === ‘path’ && params[param.name]) {
path = path.replace(‘{’ + param.name + ‘}’, params[param.name])
} else if (param[‘in’] === ‘query’ && params[param.name]) {
path += path.indexOf(‘?’) !== -1 ? ‘&’ : ‘?’;
path += param.name + ‘=’ + (Array.isArray(params[param.name]) ? params[param.name].join(‘,’) : params[param.name]);
}
});
if (path.indexOf(‘{character_id}’) !== -1) path = path.replace(‘{character_id}’, getProperty_(name, ‘character_id’));
if (path.indexOf(‘{alliance_id}’) !== -1) path = path.replace(‘{alliance_id}’, getProperty_(name, ‘alliance_id’));
if (path.indexOf(‘{corporation_id}’) !== -1) path = path.replace(‘{corporation_id}’, getProperty_(name, ‘corporation_id’));
var token = CACHE.get(name + 'access_token’);
if (!token && endpoint.authed) token = refreshToken(name);
return doRequestPOST_(BASE_URL + path, ‘post’, token);
}
Die zweite verwendete Funktion ist “doRequest_” (umbenannt in “doRequestPOST_”) für die eigentliche Abfrage.
Die letzten beiden Zeilen sind für die Fehlerbehandlung und interpretation der zurückgegebenen Daten. Da wir aber keine Daten erwarten, müssen diese Zeilen auskommentiert werden (zwei // am Anfang der Zeile) ansonsten würde das Makro einen Fehler produzieren. Damit wird zwar die Fehlerbehandlung auch mit deaktiviert aber das ist erst einmal unwichtig.
Zusätzlich ist ‘endpoints.gs’ um die gewünschte ESI-Funktion zu ergänzen. Im folgenden Beispiel für die Funktionen Wegpunkt setzen und Marktdetails anzeigen. Als vorletzte Zeile folgenden Code einfügen.
}, // ← ursprünglich vorletzte Zeile; Komma nicht vergessen!
“ui_autopilot_waypoint”: {
“description”: “Set a solar system as autopilot waypoint”,
“summary”: “set waypoint”,
“request”: “post”,
“version”: 1,
“headers”: [ ],
“path”: “/v2/ui/autopilot/waypoint/”,
“authed”: true,
“response_type”: “object”,
“item_type”: “object”,
“parameters”: [
{
“name”: “add_to_beginning”,
“description”: “Whether this solar system should be added to the beginning of all waypoints”,
“required”: true,
“type”: “boolean”,
“in”: “query”
},
{
“name”: “clear_other_waypoints”,
“description”: “Whether clean other waypoints beforing adding this one”,
“required”: true,
“type”: “boolean”,
“in”: “query”
},
{
“name”: “destination_id”,
“description”: “The destination to travel to, can be solar system, station or structure’s id”,
“required”: true,
“type”: “long”,
“in”: “query”
}
]
}
}; // ← letzte Zeile bleibt unberührt