Backend Integration
自訂資產伺服器整合
可以從一個自訂資產伺服器來載入物品/貨幣,並且使用它們作為錦標賽獎項或入場費。
同時,可以透過一個自訂伺服器,來路由任何註冊,該伺服器可以扣除這些物品或是拒絕錦標賽註冊(比如,使用者沒有足夠的貨幣)。
從伺服器載入商店物品
為了從自訂伺服器載入物品及貨幣,必須建立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 回應。
總是傳回所有您希望匯入的物品。
已存在的物品/貨幣將被更新。
當有一個傳回所需格式的端點之後,請導航到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(或在拒絕的情況下的另一個程式碼)。
當有一個接受所需的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。
如果失敗,將重複它許多次。
當有一個接受所需的JSON格式的端點的時候,請導航到:Game Settings/Tournament settings Integration
並且啟用「外部獎項交付」。
插入一個有效的HTTP路徑,並且針對您的伺服器所需的授權來新增任何必要的標題/參數。
PlayFab資產伺服器整合
可以從一個PlayFab後端來載入物品/貨幣,並且使用它們作為錦標賽獎項或入場費。
同時,可以透過一個自訂雲端指令碼,來路由任何註冊,該雲端指令碼可以扣除這些物品或是拒絕錦標賽註冊(比如,使用者沒有足夠的貨幣)。
建立PlayFab密鑰
對於PlayFab整合,您將需要 標題ID 及 密鑰。
登入您的Playfab儀表板,選擇您的所需的遊戲,並且開啟設定畫面。
您可以在API Features
索引標籤中找到 標題ID。您可以在Secret Key
索引標籤中建立一個新的 密鑰。
請不要針對密鑰來設定失效日期,因為如果您忘記在錦標賽儀表板中設定新的密鑰的話,這樣可能會導致運行中斷。
以PlayFab提供者來登入
如果您與PlayFab服務整合,我們強烈建議在錦標賽儀表板中只啟用PlayFab登入提供者。同時請 注意,如果您將 不會使用PlayFab登入提供者,則其他整合功能,比如 錦標賽註冊 或透過雲端指令碼 交付獎項,將 無法 工作。
在這裡輸入 標題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 及 密鑰 並且儲存更改。
按一下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 };
};
然後等待一個成功的回應,其中形式為 { 成功:真 }(或在拒絕的情況下的任何其他東西)。
當有一個接受所需的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。
如果失敗,將重複它許多次。
當有一個接受所需JSON格式的端點之後,請導航到:Game Settings/Tournament settings Integration
並且啟用「外部獎項交付」。
選擇Playfab
提供者。
插入一個有效的 標題ID、密鑰、雲端指令碼功能名稱、功能版本(修訂編號)並且儲存更改。
您可以根據需要來更改預先生成的伺服器密碼。
在雲端指令碼中使用這個密碼,以預防Playfab使用者客戶端來執行它。