Пошаговая инструкция интеграции в Kongregate

Kongregate — весьма популярный игровой портал, на котором тысячи всевозможных игр и миллионы пользователей. Публиковать игры на этом портале достаточно просто. Так почему бы не опубликовать там свою игру? Давайте подробно рассмотрим, как это можно сделать. Начнем с загрузки Kongregate API.

Загрузка API

Для того, чтобы загрузить/проинициализировать объект Kongregate API необходимо выполнить внешний вызов объекта Javascript, который будет автоматически создан для вас. Этот объект будет доступен прежде, чем запустится ваше Unity приложение, так что его можно использовать в любое время. Метод Application.ExternalEval используется для вызова объекта Javascript kongregateUnitySupport, если он существует. Когда API загрузится полностью — будет выполнен метод Unity SendMessage для вызова метода KONGREGATE_LOADER_METHOD объекта Unity с именем KONGREGATE_LOADER_GO. Также необходимо убедиться, что API не загрузится более одного раза, так как это может привести к разрыву соединения.

Ниже следует пример того, как использовать объект kongregateUnitySupport для загрузки Kongregate API и оповещения вашего приложения Unity, когда загрузка завершена.

private const string KONGREGATE_LOADER_GO = «KongregateLoader»;
private const string KONGREGATE_LOADER_METHOD = «OnKongregateAPILoaded»;
private KongregateLoader kongregateLoader = null;
public void Login(Action onComplete)
{
kongregateLoader = Object.FindObjectOfType();
if (kongregateLoader == null)
{
kongregateLoader = (new GameObject(KONGREGATE_LOADER_GO)).AddComponent<KongregateLoader>();
Object.DontDestroyOnLoad(kongregateLoader);
kongregateLoader.Logined += OnLogined;
onLoginComplete = onComplete;
Application.ExternalEval(
«if(typeof(kongregateUnitySupport) != ‘undefined’){» +
» kongregateUnitySupport.initAPI(‘» + KONGREGATE_LOADER_GO + «‘, ‘» + KONGREGATE_LOADER_METHOD +
«‘);» +
«};»
);
}
}

Метод OnKongregateAPILoaded выглядит следующим образом (JavaScript из этого метода будет использован для внутриигровых покупок):

private void OnKongregateAPILoaded(string userInfoString)
{
isKongregate = true; // We now know we’re on Kongregate

// Split the user info up into tokens

var result = userInfoString.Split(«|»[0]);
var data = new LoginData { UserId = result[0], Username = result[1], GameAccessToken = result[2] };
var handler = Logined;
if (handler != null)
handler(data);
Application.ExternalEval(@»

// Extern the JS Kongregate API

function purchaseItem(item)
{
kongregate.mtx.purchaseItems([item], onPurchaseResult);
SendUnityMessage(‘LogMessage’, ‘purchase sent….’);
}
function onPurchaseResult(result)
{
if (result.success)
{
SendUnityMessage(‘LogMessage’, ‘purchase complete…’);
SendUnityMessage(‘OnPurchaseSuccess’);
}
else
{
SendUnityMessage(‘LogMessage’, ‘purchase error…’);
SendUnityMessage(‘OnPurchaseError’);
}
}

// Utility function to send data back to Unity

function SendUnityMessage(functionName, message)
{
Log(‘Calling to: ‘ + functionName);
var unity = kongregateUnitySupport.getUnityObject();
unity.SendMessage(‘KongregateLoader’, functionName, message);
}
function Log(message)
{
var unity = kongregateUnitySupport.getUnityObject();
unity.SendMessage(‘KongregateLoader’, ‘LogMessage’, message);
}
«);
}

Для удобства поместим данные пользователя в структуру следующего вида:

public struct LoginData
{
public string UserId;
public string Username;
public string GameAccessToken;
}
После загрузки API получаем данные пользователя
private void OnLogined(KongregateLoader.LoginData data)
{
kongregateLoader.Logined -= OnLogined;
isLoggedIn = true;
userId = data.UserId;
username = data.Username;
accessToken = data.GameAccessToken;
var handler = onLoginComplete;
if (handler != null)
handler();
}

Таким образом мы выполнили загрузку API, получив при этом user id и username пользователя, а также game_auth_token.

Получение данных профиля

Важно отметить, что при отправке запросов на Kongregate во избежание ошибок лучше использовать api вместо www.

Для получения данных профиля необходимо отправить запрос следующего вида

GET url: http://api.kongregate.com/api/user_info.json

необходимые параметры:

username или user_id: username/user_id пользователя, информацию о котором вы запрашиваете

либо

usernames или user_ids: запрашивает информацию о нескольких пользователях(не более 50), их username/user_id разделяются запятой

дополнительные параметры:

page_num: страница данных запроса (по умолчанию 1)

friends: true, если вы хотите получить список друзей пользователя (для множественного запроса список друзей вернется пустым)

Результатом данного запроса является JSON строка со следующими полями:

success: true/false в зависимости от того, был ли запрос успешным

error: код ошибки типа integer в случае ее возникновения

error_description: описание кода ошибки типа string, в случае ее возникновения

В случае успеха в данном JSON объекте также получаем следующие поля:

page_num: номер текущей страницы

num_pages: общее количество страниц

user_id: Kongregate id пользователя

username: username пользователя

private: true если профиль закрыт для общего доступа

friends: массив usernames друзей пользователя (если запрашивался)

friend_ids: массив userids друзей пользователя (если запрашивался)

user_vars: JSON объект, содержащий уточняющую информацию о пользователе

level: текущий уровень пользователя (integer)

avatar_url: URL полноразмерной аватары пользователя

chat_avatar_url: URL маленькой аватары пользователя, которая используется в чате

game_title: название игры, в которую играет пользователь

game_url: URL игры, в которую играет пользователь

developer: true, если пользователь является разработчиком

moderator: true, если пользователь является модератором

admin: true, если пользователь является администратором

Для получения информации из JSON я использовал Boomlagoon JSON от Boomlagoon Ltd.

В моей игре мне нужны были только поля user_id, username, friend_ids и avatar_url.

Я получил их следующим образом:

{
var userData = JSONObject.Parse(loaderData.Text);
if (userData.GetBoolean(«success»))
var profile = new KongregateProfile(userData);
}

,где JSONObject.Parse — метод класса Boomlagoon.JSON.JSONObject, который преобразует строку в JSON объект, а loaderData.Text — строка, полученная в результате запроса http://api.kongregate.com/api/user_info.json?user_id={0}&friends=true, где {0} — Kongregate id пользователя.

Теперь рассмотрим конструктор KongregateProfile, который получает данные из JSON объекта:

public KongregateProfile(JSONObject userInfo)
{
userId = ((int) userInfo.GetNumber(«user_id»)).ToString();
username = userInfo.GetString(«username»);
if (userInfo.GetBoolean(«success»))
{
var userVars = JSONObject.Parse(userInfo.GetObject(«user_vars»).ToString());
avatarUrl = userVars.GetString(«chat_avatar_url»);
avatarUrl = avatarUrl.Replace(«16×16», «50×50»);
}
else
Debug.LogWarning(«Can not load avatar!»);
}

При использовании userVars.GetString(«avatar_url») возвращался аватар размером 1х1, поэтому пришлось использовать конструкцию

avatarUrl = userVars.GetString(«chat_avatar_url»);
avatarUrl = avatarUrl.Replace(«16×16», «50×50»);

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

{
var profiles = new List<IKongregateProfile>();
var playerInfo = JSONObject.Parse(loaderData.Text); // loaderData.Text — GET url: http://api.kongregate.com/api/user_info.json?user_id={0}&friends=true
var friendsString = playerInfo.GetValue(«friend_ids»).ToString();
friendsString = friendsString.Remove(0, 1); //removing «[» in the beginning
friendsString = friendsString.Remove(friendsString.Length — 1); //removing «]» in the end
var friends = JSONObject.Parse(data.Text); // data.Text — GET url: http://api.kongregate.com/api/user_info.json?user_ids= + friendsString
if (friends.GetBoolean(«success»))
{
foreach (var friend in friends.GetArray(«users»))
{
var friendData = JSONObject.Parse(friend.ToString());
var profile = new KongregateProfile(friendData);
profiles.Add(profile);
}
}
}

In-app purchases

На Kongregate внутриигровые покупки осуществляются следующим образом: пользователь совершает покупку, и предмет заносится в инвентарь на Kongregate. Для того, чтобы использовать предмет, нужно знать его идентификатор, который он получил при занесении в инвентарь. Для использования внутриигровых покупок нам снова понадобится наш объект KongregateLoader.

Для того, чтобы пользователь купил предмет, необходимо сначала создать его на Kongregate. Это делается следующим образом: переходим к настройкам игры http://www.kongregate.com/games/MyUser/GAME_NAME/items, где GAME_NAME – название вашей игры. Создаем покупку нажав на New Item и указываем все нужные данные. Идентификатор должен быть уникальным.

Часть кода из KongregateLoader, которая будет использована для внутрииигровых покупок

private Action onPurchaseSuccess = delegate { };
private Action<string> onPurchaseError = delegate { };
public void PurchaseItem(string item, Action onSuccess, Action<string> onError)
{
onPurchaseSuccess = onSuccess;
onPurchaseError = onError;
CallJSFunction(string.Format(«purchaseItem(‘{0}’)», item), null);
}
private void OnPurchaseSuccess()
{
var handler = onPurchaseSuccess;
if (handler != null)
handler();
}
private void OnPurchaseError()
{
var handler = onPurchaseError;
if (handler != null)
handler(«KongregateLoader: failed purchase»);
}
public void LogMessage(string message)
{
Debug.Log(message);
}
public void CallJSFunction(string functionCall, string callback)
{
if (isKongregate)
{
if (string.IsNullOrEmpty(callback))
{
Application.ExternalEval(functionCall);
}
else
{
Application.ExternalEval(string.Format(@»
var value = {0};
SendUnityMessage(‘{1}’, String(value));
«, functionCall, callback));
}
}
}

Также нам понадобится JavaScript из метода OnKongregateAPILoaded, код которого приведен выше в разделе «Загрузка API».

Для совершения покупки выполним следующий метод:

public void BuyItem(string itemId, Action onSuccess, Action<string> onError)
{
if (isLoggedIn) //checking if user is logged in
kongregateLoader.PurchaseItem(itemId, onSuccess, onError);
}

, где itemId — уникальный идентификатор, который вы ввели при создании нового предмета.

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

public void GetItems(Action<Dictionary<string, string>> onGetItems)
{
if (isLoggedIn)
{
var itemsJSON = JSONObject.Parse(data.Text); //data.Text — GET url: http://api.kongregate.com/api/user_items.json?api_key={0}&user_id={1}, {0} — api key (http://www.kongregate.com/games/MyUser/GAME_NAME/api), {1} — Kongregate ID
Dictionary<string, string> items = new Dictionary<string, string>();
foreach (var item in itemsJSON.GetArray(«items»))
{
var i = JSONObject.Parse(item.ToString());
items.Add(((int)i.GetNumber(«id»)).ToString(), i.GetString(«identifier»));
}
var handler = onGetItems;
if (handler != null)
handler(items);
}
}

Теперь рассмотрим HTTP запрос, который позволяет использовать предмет с ограниченным количеством использований, принадлежащий пользователю. Чтобы его использовать, вы должны ввести id экземпляра этого предмета. Этот id мы получили из инвентаря пользователя с помощью метода GetItems. Отправка этого запроса для предмета с неограниченным количеством использований приведет к ошибке.

Для использования предмета необходимо отправить запрос: POST url: http://api.kongregate.com/api/use_item.json

необходимые параметры:

api_key: api key вашей игры (http://www.kongregate.com/games/MyUser/GAME_NAME/api)

game_auth_token: game_auth_token пользователя (был получен при логине)

user_id: Kongregate ID

id: id (из инвентаря пользователя) экземпляра предмета

результат:

success: true/false в зависимости от того, был ли запрос успешным

error: код ошибки типа integer в случае ее возникновения

error_description: описание кода ошибки типа string, в случае ее возникновения

в случае успеха:

remaining_uses: обновленное количество оставшихся использований

usage_record_id: уникальный id использования

Если remaining_uses = 0, то экземпляр предмета удаляется из инвентаря пользователя.

Вот, в принципе, все что нужно для того, чтобы опубликовать свою игру на Kongregate и настроить внутриигровые покупки.

0 ответы

Ответить

Want to join the discussion?
Feel free to contribute!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *