백엔드 통합
서버 통합 사용자 정의 에셋
사용자 정의 에셋 서버에서 아이템/통화를 로딩하여 토너먼트 보상 또는 참가 비용으로 사용할 수 있습니다.
또한 모든 등록은 해당 항목을 공제하거나 토너먼트 등록을 거부할 수 있는 사용자 지정 서버를 통해 라우팅 될 수 있습니다(예: 사용자에게 충분한 통화가 없음).
서버에서 상점 아이템 불러오기
사용자 지정 서버에서 아이템과 통화를 로드하려면 특정 JSON 형식으로 항목을 반환하는 HTTP 엔드포인트를 만들어야 합니다.
서버가 내부 사용을 위해 항목을 로드하고 외부 리소스에서 해당 항목/통화를 "로드함"으로 표시하도록 하려면 이 작업을 수행해야 합니다.
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에 응답해야 합니다.
항상 불러들일 모든 아이템들을 되돌려줍니다.
기존에 존재했던 아이템/통화들은 업데이트됩니다.
필요한 형식을 반환하는 엔드포인트가 있으면 게임 설정/스토어 통합
으로 이동하여 "외부 저장소 연결"을 사용하도록 설정합니다.
사용자 지정 URL
공급자를 선택합니다.
올바른 HTTP 경로를 삽입하고 서버에 필요한 인증에 필요한 헤더/파라미터들을 추가합니다.
지금 데이터 동기화
버튼을 클릭하면 아이템/통화를 가져올 수 있습니다.
이제 토너먼트 템플릿 보상 및 참가비를 편집할 때 가져온 아이템에 접근할 수 있습니다.
에셋에 대한 업데이트가 있을 경우 지금 데이터 동기화
버튼을 클릭하여 에셋을 다시 가져옵니다.
사용자 지정 서버를 통한 사용자 등록
사용자 지정 서버를 통해 토너먼트 등록을 라우팅하려면 특정 JSON 형식을 허용하는 HTTP 엔드포인트를 만들어야 합니다.
모든 사용자 등록 시 토너먼트, 사용자, 참가비 등에 대한 정보가 포함된 페이로드로 사용자 지정 서버에 호출됩니다.
HTTP 호출은 POST이며, JSON 페이로드가 포함된 userTicket라는 파라미터를 사용합니다.
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 형식을 수락하는 엔드포인트가 있으면 게임 설정/토너먼트 설정 통합
으로 이동하여 "외부 사용자 등록"을 사용하도록 설정합니다.
올바른 HTTP 경로를 삽입하고 서버에 필요한 인증에 필요한 헤더/파라미터를 추가합니다.
이 설정을 한 후, 클라이언트로부터의 모든 등록은 승인되고 확인되기 전에 사용자 지정 서버를 통해 라우팅 되어야 합니다.
사용자 지정 서버로 토너먼트 결과 리포트
사용자 지정 서버를 통해 토너먼트 결과를 수신하려면 특정 JSON 형식을 허용하는 HTTP 엔드포인트를 만들어야 합니다.
모든 토너먼트가 끝난 후, 토너먼트, 사용자 및 경품 등에 대한 정보가 포함된 페이로드와 함께 사용자 지정 서버로 호출이 이루어집니다.
HTTP 호출은 POST이며, JSON 페이로드가 포함된 jsonPayload라는 파라미터가 포함되어 있습니다.
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 형식을 수락하는 엔드포인트가 있으면 게임 설정/토너먼트 설정 통합
으로 이동하여 "외부 경품 전달"을 활성화합니다.
올바른 HTTP 경로를 삽입하고 서버에 필요한 인증에 필요한 헤더/파라미터를 추가합니다.
서버 통합 PlayFab 에셋
PlayFab 백엔드에서 아이템/통화를 로딩하여 토너먼트 보상 또는 참가비로 사용할 수 있습니다.
또한 모든 등록은 해당 항목을 공제하거나 토너먼트 등록을 거부할 수 있는 사용자 지정 클라우드 스크립트를 통해 라우팅 될 수 있습니다(예: 사용자에게 충분한 통화가 없음).
PlayFab 비밀 키 생성
PlayFab 통합을 위해서는 TitleId 및 SecretKey가 필요합니다.
playfab 관리 화면에 로그인하여 원하는 게임을 선택하고 설정 화면을 엽니다.
API Features
탭에는 TitleId가 있습니다. Secret Key
탭에서 새로운 SecretKey를 생성할 수 있습니다.
토너먼트 관리 화면에서 만료일 설정을 잊어버릴 경우 게임이 중지될 수 있으므로 비밀 키의 만료 날짜를 설정하지 않습니다.
PlayFab 공급자로 로그인
PlayFab 서비스와 통합하는 경우 토너먼트 대시보드에서 PlayFab 로그인 공급자만 활성화할 것을 권장합니다. 또한 PlayFab 로그인 공급자를 사용하지 않을 경우 토너먼트 가입 또는 상품 제공과 같은 기타 통합 기능이 작동되지 않습니다.
여기에 TitleId 그리고 SecretKey를 입력하고 변경사항을 저장합니다.
초기화하고 로그인한 이후, 게임 클라이언트에서는 세션 티켓을 얻게 됩니다.
이 세션 티켓은 인증 사용자에게 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
공급자를 선택합니다.
유효한 title id와 secret key를 입력하고 변경사항을 저장합니다.
에셋에 변경사항이 있는 경우 지금 데이터 동기화
버튼을 클릭하여 다시 불러오세요.
Playfab CloudScript를 통한 가입
Playfab CloudScript를 통해 토너먼트 등록을 라우팅하려면 특정 JSON 형식을 수용하는 기능이 생성되어야 합니다.
모든 사용자 등록 시, 토너먼트, 사용자, 참가비 등에 대한 정보가 포함된 페이로드와 함께 이 cloudscript 함수가 호출됩니다.
CloudScript 함수 파라미터 args에는 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
}]
}
}
다음은 가입/탈퇴를 처리하는 CloudScript 함수의 예제입니다:
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 };
};
성공적인 응답으로 **{ success: true }**형식이며 (또는 이외는 거부) 형식을 기다리게 됩니다.
필요한 JSON 형식을 수락하는 CloudScript 함수가 있으면 게임 설정/토너먼트 설정 통합
으로 이동하여 "외부 등록"을 활성화합니다.
Playfab
제공자를 선택합니다.
유효한 제목 id, secret key, CloudScript 함수 이름, 기능 버전(개정 번호)를 입력하고 변경 사항을 저장합니다.
원하는 경우 변경할 수 있는 사전 생성된 서버 암호가 있습니다.
클라우드 스크립트에 이 암호를 사용하여 플레이팹 사용자 클라이언트가 이를 실행하는 것을 방지합니다.
이 설정 후, 승인 및 확인 전에 클라이언트의 모든 등록이 클라우드 스크립트를 통해 라우팅 되어야 합니다.
Playfab CloudScript를 통한 토너먼트 결과
Playfab CloudScript를 통해 토너먼트 결과를 수신하려면 특정 JSON 형식을 허용하는 기능이 생성되어야 합니다.
모든 토너먼트가 끝난 후, 토너먼트, 사용자 및 경품 등에 대한 정보가 포함된 페이로드와 함께 이 cloudscript 함수가 호출됩니다.
CloudScript 함수 파라미터 args에는 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"}]
}]
}
다음은 경품 전달을 처리하는 CloudScript 함수의 예제입니다:
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 형식을 받는 엔드포인트가 있으면 게임 설정/토너먼트 설정 통합
으로 이동하여 "외부 경품 전달"을 활성화합니다.
Playfab
제공자를 선택합니다.
유효한 제목 id, secret key, CloudScript 함수 이름, 기능 버전(개정 번호)를 입력하고 변경 사항을 저장합니다.
원하는 경우 변경할 수 있는 사전 생성된 서버 암호가 있습니다.
클라우드 스크립트에 이 암호를 사용하여 플레이팹 사용자 클라이언트가 이를 실행하는 것을 방지합니다.