This document is about: QUANTUM 2
SWITCH TO

Backend Integration


Available in the Gaming Circle and Industries Circle
Circle

自訂資產伺服器整合

可以從一個自訂資產伺服器來載入物品/貨幣,並且使用它們作為錦標賽獎項或入場費。
同時,可以透過一個自訂伺服器,來路由任何註冊,該伺服器可以扣除這些物品或是拒絕錦標賽註冊(比如,使用者沒有足夠的貨幣)。

從伺服器載入商店物品

為了從自訂伺服器載入物品及貨幣,必須建立HTTP端點,其以一個特定的JSON格式來傳回物品。
您必須要做這個,以確保伺服器為了內部使用而載入物品,並且標記這些物品/貨幣為從外部資源「已載入」。

JSON格式:

JSON

{
   items:[
       {
           id:"itemId1",
           name:"itemName1",
           image:"imageUrl (optional)"
       },
       {
           id:"itemId2",
           name:"itemName2",
           image:"imageUrl (optional)"
       }],   
   currencies:[
       {
           id:"currencyId1",
           name:"currencyName1"
       },
       {
           id:"currencyId2",
           name:"currencyName2"
       }]
}

端點也必須以 狀態程式碼200 回應。
總是傳回所有您希望匯入的物品。
已存在的物品/貨幣將被更新。

External store image

當有一個傳回所需格式的端點之後,請導航到Game Settings/Store Integration並且啟用「外部儲存連結」。
選擇Custom URL提供者。
插入一個有效的HTTP路徑,並且針對您的伺服器要求的授權,來新增任何必要的標題/參數。

按一下Sync data now按鈕,其將匯入您的物品/貨幣。
當您在編輯您的錦標賽範本獎項及入場費的時候,您現在應該能夠存取已匯入的物品。

如果您的資產有任何更新,請按一下Sync data now按鈕,以再次匯入它們。

透過自訂伺服器來註冊

為了透過一個自訂伺服器來路由錦標賽註冊,必須建立一個HTTP端點,其接受一個特定的JSON格式。
在每個使用者註冊時,都將調用一個自訂伺服器,其中有一個含有關於錦標賽、使用者、入場費等等資訊的裝載。

HTTP調用是POST,其中有一個參數名為 使用者票證,其含有JSON裝載。

JSON格式:

JSON

{
   isSignup:true,
   isSignout:false,
   userId:"64bit number as string",
   userExternalId:"string",
   ticketId:"64bit number as string",
   tournamentId:"64bit number as string",
   customRequirements:[{
    name:"string",
    value:"string"
   }],
   fees:{
    items:[{
       id:"64bit number as string",
       externalId:"string",
       amount:1
    }],
    currencies:[{
       id:"64bit number as string",
       externalId:"string",
       amount:1
    }]
   }
}

然後等待一個成功的回應,其中有HTTP 狀態程式碼200(或在拒絕的情況下的另一個程式碼)。

External signup image

當有一個接受所需的JSON格式的端點的時候,請導航到:Game Settings/Tournament settings Integration並且啟用「外部註冊」。
插入一個有效的HTTP路徑,並且針對您的伺服器所需的授權來新增任何必要的標題/參數。

在這個設定之後,來自客戶端的任何註冊,應該在其被接受及確認之前,經由自訂伺服器來被路由。

錦標賽結果回報給自訂伺服器

為了透過一個自訂伺服器來收到錦標賽結果,必須建立一個HTTP端點,其接受一個特定的JSON格式。
在每次錦標賽完成之後,都將調用一個自訂伺服器,其中有一個含有關於錦標賽、使用者及他們的獎項等等資訊的裝載。

HTTP調用是POST,其中有一個參數名為 json裝載,其含有JSON裝載。

JSON格式:

JSON

{
   "tournamentId":"64bit number as string",   
   "prizes":[{
       "ticketId":"64bit number as string",
       "userId":"64bit number as string",
       "userExternalId":"string",
       "place":1,
       "items":[{
           "id":"64bit number as string",
           "amount":1,
           "externalId":"string"}],
       "currencies":[{
           "id":"64bit number as string",
           "amount":1,
           "externalId":"string"}]
    }]
}

然後等待一個成功的回應,其中有HTTP 狀態程式碼200
如果失敗,將重複它許多次。

External prize delivery image

當有一個接受所需的JSON格式的端點的時候,請導航到:Game Settings/Tournament settings Integration並且啟用「外部獎項交付」。
插入一個有效的HTTP路徑,並且針對您的伺服器所需的授權來新增任何必要的標題/參數。

PlayFab資產伺服器整合

可以從一個PlayFab後端來載入物品/貨幣,並且使用它們作為錦標賽獎項或入場費。
同時,可以透過一個自訂雲端指令碼,來路由任何註冊,該雲端指令碼可以扣除這些物品或是拒絕錦標賽註冊(比如,使用者沒有足夠的貨幣)。

建立PlayFab密鑰

對於PlayFab整合,您將需要 標題ID密鑰
登入您的Playfab儀表板,選擇您的所需的遊戲,並且開啟設定畫面。

PlayFab game settings

您可以在API Features索引標籤中找到 標題ID。您可以在Secret Key索引標籤中建立一個新的 密鑰
請不要針對密鑰來設定失效日期,因為如果您忘記在錦標賽儀表板中設定新的密鑰的話,這樣可能會導致運行中斷。

以PlayFab提供者來登入

如果您與PlayFab服務整合,我們強烈建議在錦標賽儀表板中只啟用PlayFab登入提供者。同時請 注意,如果您將 不會使用PlayFab登入提供者,則其他整合功能,比如 錦標賽註冊 或透過雲端指令碼 交付獎項,將 無法 工作。

Dashboard playfab login provider image

在這裡輸入 標題ID密鑰 並且儲存更改。

在您的遊戲客戶端中,在您初始化及以Playfab登入之後,您將會獲得一個 遊戲階段票證
這個遊戲階段票證隨後被傳送到 Playfab登入提供者,以授權使用者及登入到錦標賽。
這個流程將確保系統有正確的及有效的,與使用者帳戶相關聯的Playfab ID。

C#

string playfabId;
string playfabSessionTicket;
bool isPlayfabLoginFinished;

// coroutine
// ...
// login playfab client
PlayFab.PlayFabClientAPI.LoginWithCustomID(
    new PlayFab.ClientModels.LoginWithCustomIDRequest() {
        CreateAccount = true,
        CustomId = "customPlayfabId"
    },
    (result) =>
    {
        isPlayfabLoginFinished = true;
        // get playfab user id and session ticket (we will use it for authentication)
        playfabId = result.PlayFabId;
        playfabSessionTicket = result.SessionTicket;
    },
    (error) =>
    {
        isPlayfabLoginFinished = true;
    });
// wait until playfab login process finishes
yield return new WaitUntil(() => isPlayfabLoginFinished);
// use playfab login provider, pass playfab id and session ticket
yield return BackboneManager.Client.Login(
    Gimmebreak.Backbone.User.LoginProvider.Playfab(
        true,
        "NickName-" + playfabId,
        playfabSessionTicket,
        playfabId));

為了獲得與使用者帳戶相關聯的Playfab ID,請調用BackboneManager.Client.User.GetLoginId(LoginProvider.Platform.Playfab)
這可以用於比較已登入的Playfab客戶端是否匹配上已登入的錦標賽客戶端。

從Playfab載入儲存物件

請導航到Game Settings/Store Integration並且啟用「外部儲存連結」。
選擇Playfab提供者。
插入一個有效的 標題ID密鑰 並且儲存更改。

External store playfab image

按一下Sync data now按鈕,其將匯入您的物品/貨幣(從主要目錄)。
當您在編輯您的錦標賽範本獎項及入場費的時候,您現在應該能夠存取已匯入物品。

如果您的資產有任何更新,只需按一下Sync data now按鈕來再次匯入它們。

透過Playfab雲端指令碼來註冊

為了透過一個Playfab雲端指令碼來路由錦標賽註冊,必須建立一個功能,其接受一個特定的JSON格式。
在每次使用者註冊,都將調用這個雲端指令碼功能,其中有一個含有關於錦標賽、使用者及入場費等等資訊的裝載。

雲端指令碼功能參數 引數 將含有JSON裝載。

JSON格式:

JSON

{
   serverSecret:"string",
   isSignup:true,
   isSignout:false,
   userId:"64bit number as string",
   userPlayfablId:"string",
   ticketId:"64bit number as string",
   tournamentId:"64bit number as string",
   customRequirements:[{
    name:"string",
    value:"string"
   }],
   fees:{
    items:[{
       id:"64bit number as string",
       externalId:"string",
       amount:1
    }],
    currencies:[{
       id:"64bit number as string",
       externalId:"string",
       amount:1
    }]
   }
}

這裡是一個處理註冊/登出的示例雲端指令碼功能:

JavaScript

// This is a example tournament signup/signout handler. If signup is requested
// check if user can sign up and deduct any required fees. If signout is requested
// return any deducted fees back to users account.
handlers.tournamentSignup = function(args, context){
    if (args.serverSecret == "secret") {
        if (args.isSignup) {
            // Check any custom requirement for the tournament. This can be
            // e.g. having required minimum rank. If player does not meet
            // specified criteria, the signup should be rejected.
            for (var i = 0; i < args.customRequirements.length; i++) {
                var name = args.customRequirements[i].name;
                var value = args.customRequirements[i].value;
                if (name == "testRequirement" &&
                    value == "reject") {
                    return { success: false };
                }
            }
            // Check if user has required signup fees.
            if (args.fees.items.length > 0 ||
                args.fees.currencies.length > 0) {
                // Get user inventory
                var userInvetoryResult = server.GetUserInventory({PlayFabId: currentPlayerId});
                // Check if user has enough currency
                for (var i = 0; i < args.fees.currencies.length; i++) {
                    var currencyFee = args.fees.currencies[i];
                    var userCurrency = userInvetoryResult.VirtualCurrency[currencyFee.externalId];
                    if (!userCurrency ||
                        userCurrency < currencyFee.amount) {
                        // User does not have required currency or amount
                        return { success: false };
                    }
                }
                // Sort user invetory items by id
                var userInventory = {};
                for (var i = 0; i < userInvetoryResult.Inventory.length; i++) {
                    var item = userInvetoryResult.Inventory[i];
                    if (!userInventory[item.ItemId]) {
                        userInventory[item.ItemId] = [];
                    }
                    userInventory[item.ItemId].push(item);
                }
                // Check if user has enough items
                for (var i = 0; i < args.fees.items.length; i++) {
                    var itemFee = args.fees.items[i];
                    var userItems = userInventory[itemFee.externalId];
                    if (!userItems ||
                        userItems.length < itemFee.amount) {
                        // User does not have required item or amount
                        return { success: false };
                    }
                }

                // Substract user's currencies
                for (var i = 0; i < args.fees.currencies.length; i++) {
                    var currencyFee = args.fees.currencies[i];
                    server.SubtractUserVirtualCurrency({PlayFabId: currentPlayerId, VirtualCurrency: currencyFee.externalId, Amount: currencyFee.amount });
                }

                // Revoke user's items
                var revokedItems = { Items: [] };
                for (var i = 0; i < args.fees.items.length; i++) {
                    var itemFee = args.fees.items[i];
                    for (var p = 0; p < itemFee.amount; p++) {
                        revokedItems.Items.push({PlayFabId: currentPlayerId, ItemInstanceId: userInventory[itemFee.externalId][p].ItemInstanceId});
                        // Maximum 25 items can be removed at once (Playfab documentation)
                        // If container is filled with 25 items, revoke and continue
                        if (revokedItems.Items.length == 25) {
                            server.RevokeInventoryItems(revokedItems);
                            revokedItems.Items = [];
                        }
                    }
                }
                // Check if any items should be revoked (last 25 items)
                if (revokedItems.Items.length > 0) {
                    server.RevokeInventoryItems(revokedItems);
                }

                // All fees deducted, confirm tournament signup
                return { success: true };
            }
            else {
                // No fees to deduct, confirm tournament signup
                return { success: true };
            }
        }
        if (args.isSignout) {
            // Return user's currencies
            for (var i = 0; i < args.fees.currencies.length; i++) {
                var currencyFee = args.fees.currencies[i];
                server.AddUserVirtualCurrency({PlayFabId: currentPlayerId, VirtualCurrency: currencyFee.externalId, Amount: currencyFee.amount });
            }
            // Return user's items
            var returnItems = { PlayFabId: currentPlayerId, ItemIds: [], Annotation: "Returned tournament fee items. TournamentId: " + args.tournamentId };
            for (var i = 0; i < args.fees.items.length; i++) {
                var itemFee = args.fees.items[i];
                for (var p = 0; p < itemFee.amount; p++) {
                    returnItems.ItemIds.push(itemFee.externalId);
                }
            }
            // Check if any items should be returned
            if (returnItems.ItemIds.length > 0) {
                server.GrantItemsToUser(returnItems);
            }
            // User fees has been returned
            return { success: true };
        }
    }
    return { success: false };
};

然後等待一個成功的回應,其中形式為 { 成功:真 }(或在拒絕的情況下的任何其他東西)。

External signup playfab image

當有一個接受所需的JSON格式的雲端指令碼功能之後,請導航到:Game Settings/Tournament settings Integration並且啟用「外部註冊」。
選擇Playfab提供者。
插入一個有效的 標題ID密鑰雲端指令碼功能名稱功能版本(修訂編號)並且儲存更改。

您可以根據需要來更改預先生成的伺服器密碼。
在雲端指令碼中使用這個密碼,以預防Playfab使用者客戶端來執行它。

在這個設定之後,來自一個客戶端的任何註冊,應該在其被接受及確認之前,經由雲端指令碼來被路由。

透過Playfab雲端指令碼的錦標賽結果

為了透過一個Playfab雲端指令碼來接收錦標賽結果,必須建立一個功能,其接受一個特定的JSON格式。
在每次錦標賽完成之後,都將調用這個雲端指令碼功能,其中有一個含有關於錦標賽、使用者及他們的獎項等等資訊的裝載。

雲端指令碼功能參數 引數 將含有JSON裝載。

JSON格式:

JSON

{
   "serverSecret":"string",
   "tournamentId":"64bit number as string",   
   "prizes":[{
       "ticketId":"64bit number as string",
       "userId":"64bit number as string",
       "userPlayfabId":"string",
       "place":1,
       "items":[{
           "id":"64bit number as string",
           "amount":1,
           "externalId":"string"}],
       "currencies":[{
           "id":"64bit number as string",
           "amount":1,
           "externalId":"string"}]
    }]
}

這裡是一個處理獎項交付的示例雲端指令碼功能:

JavaScript

// This is example tournament prize delivery handler. Once tournament is finished
// all results will be provided togather with information which items and currencies
// should be granted to user.
handlers.tournamentPrizeDelivery = function(args, context){
    if (args.serverSecret == "secret" &&
        args.prizes) {
        for (var i = 0; i < args.prizes.length; i++) {
            var prize  = args.prizes[i];
            // Grant user currency prizes
            for (var p = 0; p < prize.currencies.length; p++) {
                var wonCurrency = {
                    PlayFabId: prize.userPlayfabId,
                    VirtualCurrency: prize.currencies[p].externalId,
                    Amount: prize.currencies[p].amount

                };
                server.AddUserVirtualCurrency(wonCurrency);
            }
            // Grant user item prizes
            var wonItems = {
                PlayFabId: prize.userPlayfabId,
                ItemIds: [],
                Annotation: "Won items in tournament. Place: " + prize.place + " TournamentId: " + args.tournamentId
            };
            for (var p = 0; p < prize.items.length; p++) {
                var itemPrize = prize.items[p];
                for (var c = 0; c < itemPrize.amount; c++) {
                    wonItems.ItemIds.push(itemPrize.externalId);
                }
            }
            if (wonItems.ItemIds.length > 0) {
                server.GrantItemsToUser(wonItems);
            }
        }
    }
};

然後等待一個成功的回應,其中有HTTP 狀態程式碼200
如果失敗,將重複它許多次。

External prize delivery playfab image

當有一個接受所需JSON格式的端點之後,請導航到:Game Settings/Tournament settings Integration並且啟用「外部獎項交付」。
選擇Playfab提供者。
插入一個有效的 標題ID密鑰雲端指令碼功能名稱功能版本(修訂編號)並且儲存更改。

您可以根據需要來更改預先生成的伺服器密碼。
在雲端指令碼中使用這個密碼,以預防Playfab使用者客戶端來執行它。

Back to top