‹ Facebook Gameroom Doc Home

Facebook Gameroom 集成指南

For the C++ version of cocos2d-x v3.x - (all other versions)

预备条件

请参考 Facebook 的官方文档,在你的 Facebook Application 中设置 Gameroom 相关的配置。

与 Cocos 工程集成

使用 SDKBOX Installer (推荐)

sdkbox import gameroom
sdkbox import -b c:\the_path_to_gameroom_plugin\sdkbox-gameroom_v0.01

手动集成

如果你想手动集成 Gameroom 插件,你需要一步步的完成下列多种配置。这些步骤比较复杂,我们并不推荐你手动集成插件。

  1. 找到 Visual Studio Solution 文件并且打开它。对于被 cocos 创建的 Cpp 工程,你可以在 ./proj.win32 子目录下找到这个文件。为了便于下面的描述,我们将 proj.win32 这个目录命名为项目目录

  2. 解压 Gameroom 插件包,你会得到一个目录,我们把这个目录称作插件目录

  3. 拷贝头文件。对于 Cpp 工程,你需要拷贝插件目录下的 win32/include/*.h 文件到项目目录include 文件夹下。

  4. 拷贝插件目录下的 win32/libs/*.lib 库文件到项目目录下的 libs 文件夹下。

  5. 部署 Facebook Gameroom SDK 文件。

    a. 拷贝插件目录下的 sdk/fbg 头文件目录到你的项目目录下的 include 子文件夹下。

    b. 拷贝插件目录下的 sdk/libs/*.lib 库文件到你的项目目录下的 libs 子文件夹下。

  6. 修改 Visual Studio 配置:

    a. 为编译器添加头文件目录,依次单击:项目 -> 属性 -> 配置属性 -> VC++ 目录 -> 包含目录 (单击编辑,添加新项)。

    然后添加 $(solutiondir)include

    b. 添加库文件目录,依次单击:项目 -> 属性 -> 配置属性 -> VC++ 目录 -> 库目录(单击编辑,添加新项)。

    然后添加 $(solutiondir)libs

    c. 链接库文件,依次单击:项目 -> 属性 -> 配置属性 -> 链接器 -> 输入 -> 附加依赖项 (单击编辑,添加新项)。

    然后添加 GameroomPlugin32.lib 以及 LibFBGPlatform32.lib

    对于 debug 版本,请添加 GamerommPlugin32.debug.lib

  7. 打开项目目录子文件夹 /Classes 中的 AppDelegate.cpp 文件,准备为其打代码补丁。

  8. 接下来打补丁的步骤也可以使用 patch 工具完成。对于 Cpp 工程,请使用插件目录下的 AppDelegate.cpp3.15.patch 文件。

patch AppDelegate.cpp ./plugin-dir/path/AppDelegate.cpp3.15.patch
#ifdef SDKBOX_ENABLED
#include "PluginGameroom.h"
#endif
AppDelegate::AppDelegate()
{
    freopen("fbg.log", "w", stdout);
}
AppDelegate::~AppDelegate()
{
    ...
    fclose(stdout);
}
#ifdef SDKBOX_ENABLED
    sdkbox::PluginGameroom::init("your_app_id");
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
    const wchar_t title[]{ L"Facebook Gameroom" };
    auto parentWin = FindWindow(NULL, title);

    // set dpi for app.
    auto res_dpi = SetProcessDPIAware();

    RECT rect;
    GetWindowRect(parentWin, &rect);
    glview = GLViewImpl::createWithRect("cocos_sample_cpp", Rect(0, 0, rect.right - rect.left - 20, rect.bottom - rect.top - 100), 1.0f, true);
    director->setOpenGLView(glview);
    auto currentWin = Director::getInstance()->getOpenGLView()->getWin32Window();
    SetParent(currentWin, parentWin);
#else
    glview = GLViewImpl::create("cocos_sample_cpp");
    director->setOpenGLView(glview);
#endif

用法

关于本章下面提到的方法的细节,你可以访问 API Reference 一节。并且如果你想进一步了解这些方法在 Facebook Gameroom SDK 中对应的细节,你可以参考 Facebook Gameroom SDK 官方网页

初始化 Gameroom 插件

在你调用其他 API 之前,你应该初始化插件。我们建议你在 AppDelegate::applicationDidFinishLaunching() 或者 AppController:didFinishLaunchingWithOptions() 函数中调用初始化语句。并且确保你包含了正确的头文件:

#ifdef SDKBOX_ENABLED
#include "PluginGameroom.h"
#endif


bool AppDelegate::applicationDidFinishLaunching() {
#ifdef SDKBOX_ENABLED
    // fill your Facebook Application ID
    sdkbox::PluginGameroom::init("1234567890");
#endif
}

设置 Listener

与其他 SDKBOX 的插件一样,你需要设置一个 listener 类去处理回调事件。

sdkbox::PluginGameroom::setListener(pointer_to_listener_class);

这个 listener 类应该继承至 sdkbox::GameroomListener

class HelloWorldListener : public sdkbox::GameroomListener
{
    public:
        // ...

        virtual void onLoginAccessTokenMsg(sdkbox::AccessTokenHandle);
        virtual void onFeedShareMsg(sdkbox::FeedShareHandle);
        virtual void onPurchaseIAPMsg(sdkbox::PurchaseHandle);
        virtual void onHasLicenseMsg(sdkbox::HasLicenseHandle);
        virtual void onAppRequestMsg(sdkbox::AppRequestHandle);

};

这个类中的每一个回调函数将在下面的小节中解释。

用户登录

在插件初始化之后,当你的游戏在 Gameroom 运行时,你应该让玩家登录你的游戏并且获取玩家的信息。你可以使用简单的 login() 方法或者另一个稍复杂的 loginWithScopes() 方法去完成这一功能。

这两个方法的不同之处在于 login() 方法在完成用户登录时总是申请使用以下3种权限: user_friendsemail 以及 public_profile

SDKBOX::PluginGameroom::login();

而使用另一个方法 loginWithScopes() ,你可以在玩家登录时指定申请的权限。在下面的例子里,user_friendsemail 权限将被申请使用。

std::vector<std::string> loginScopes{ "user_friends", "email" };
sdkbox::PluginGameroom::loginWithScopes(2, loginScopes);

你也可以像下面的例子那样来检测用户是否已经完成登录:

auto ret = sdkbox::PluginGameroom::isLoggedIn();
if (!ret) {
    // do something
}

玩家登录将会触发 listener 类中的 onLoginAccessTokenMsg 回调。你可以通过使用下面例子中的一些方法从回调函数的参数 accessTokenHandle 中取得玩家的信息。

void HelloWorld::onLoginAccessTokenMsg(sdkbox::AccessTokenHandle accessTokenHandle) {
    auto isValid = sdkbox::PluginGameroom::accessTokenIsValid(accessTokenHandle);
    if (!isValid) {
        // user not logged in
        return;
    }
    auto userid = sdkbox::PluginGameroom::accessTokenGetUserID(accessTokenHandle);

    char token_string[512];
    auto size = sdkbox::PluginGameroom::accessTokenGetTokenString(accessTokenHandle, token_string, 512);
    auto expiration_timestamp = sdkbox::PluginGameroom::accessTokenGetExpirationTimestamp(accessTokenHandle);

    fbgLoginScope permissions[512];
    auto permission_size = sdkbox::PluginGameroom::accessTokenGetPermissions(accessTokenHandle, permissions, 512);

    ::CCLOG(
        "OnLoginAccessTokenMsg, User ID: %lld\nAccess Token: %s\nExpiration Timestamp: %lld, Permission Count: %zu\nPermissions: ",
        (long long)userid,
        token_string,
        (long long)expiration_timestamp,
        permission_size
    );

    for (size_t i = 0; i < permission_size; i++) {
        ::CCLOG("%s", sdkbox::PluginGameroom::loginScopeToString(permissions[i]));
    }
    ::CCLOG("\n");
}

分享至 Facebook

在你的游戏中,你可以给玩家提供分享功能:

sdkbox::PluginGameroom::feedShare(
    nullptr,
    "https://www.facebook.com",
    "Testing Link Name",
    "Testing Link Caption",
    "Testing Link Description",
    "http://www.pamperedpetz.net/wp-content/uploads/2015/09/Puppy1.jpg",
    nullptr
);

上面的例子将会分享一个图片到玩家的 Facebook 。

在分享发生之后,listener 类里的 onFeedShareMsg 回调将会被调用。你可以通过 feedShareGetPostID() 方法从它的参数 feedShareHandle 中取到 Post ID

void HelloWorld::onFeedShareMsg(sdkbox::FeedShareHandle feedShareHandle) {
    auto postId = sdkbox::PluginGameroom::feedShareGetPostID(feedShareHandle);
    ::CCLOG(
        "onFeedShareMsg, Feed Share Post ID: %ld\n",
        (long)postId
    );
}

IAP

插件的 IAP 功能包括以下3种类型:

sdkbox::PluginGameroom::purchaseIAP(
    "sdkbox_product_2",
    1,
    1,
    1,
    nullptr,
    nullptr,
    nullptr
);
sdkbox::PluginGameroom::purchaseIAPWithProductURL(
    "https://friendsmash-unity.herokuapp.com/payments/100coins.php",
    1,
    1,
    1,
    nullptr,
    nullptr,
    nullptr
);
sdkbox::PluginGameroom::payPremium();

这3种类型的 IAP 都会触发 onPurchaseIAPMsg 回调。这里有一个例子说明了如何在这个回调中通过 handle 对象的属性得到 IAP 相关的结果。

void HelloWorld::onPurchaseIAPMsg(sdkbox::PurchaseHandle payHandle) {
    size_t size;
    char paymentId[512];
    size = sdkbox::PluginGameroom::purchaseGetPaymentID(payHandle, paymentId, 512);

    auto amount = sdkbox::PluginGameroom::purchaseGetAmount(payHandle);

    char currency[512];
    size = sdkbox::PluginGameroom::purchaseGetCurrency(payHandle, currency, 512);

    auto purchaseTime = sdkbox::PluginGameroom::purchaseGetPurchaseTime(payHandle);

    char productId[512];
    size = sdkbox::PluginGameroom::purchaseGetProductID(payHandle, productId, 512);

    char purchaseToken[512];
    size = sdkbox::PluginGameroom::purchaseGetPurchaseToken(payHandle, purchaseToken, 512);

    auto quantity = sdkbox::PluginGameroom::purchaseGetQuantity(payHandle);

    char requestId[512];
    size = sdkbox::PluginGameroom::purchaseGetRequestID(payHandle, requestId, 512);

    char status[512];
    size = sdkbox::PluginGameroom::purchaseGetStatus(payHandle, status, 512);

    char signedRequest[512];
    size = sdkbox::PluginGameroom::purchaseGetSignedRequest(payHandle, signedRequest, 512);

    auto errorCode = sdkbox::PluginGameroom::purchaseGetErrorCode(payHandle);

    char errorMessage[512];
    size = sdkbox::PluginGameroom::purchaseGetErrorMessage(payHandle, errorMessage, 512);

    ::CCLOG(
        "onPurchaseIAPMsg, Purchase Handle: %s\nAmount: %d\nCurrency: %s\nPurchase Time: %lld\n"
        "Product Id:%s\nPurchase Token: %s\nQuantity: %d\nRequest Id: %s\n"
        "Status: %s\nSignedRequest: %s\nError Code: %lld\nErrorMessage: %s\n",
        paymentId,
        (int)amount,
        currency,
        (long long)purchaseTime,
        productId,
        purchaseToken,
        (int)quantity,
        requestId,
        status,
        signedRequest,
        (long long)errorCode,
        errorMessage
    );
}

另外,你可以调用 hasLicense() 方法去检测该玩家是否购买了许可证或者付费版。

sdkbox::PluginGameroom::hasLicense();

值得注意的是,这个方法将会触发 onHasLicenseMsg 回调。奇怪之处在于,你必须在这个回调中用 purchaseGetLicense() 方法去取得许可证或者付费版的 ID 。(Facebook Gameroom SDK 要求这样做)

void HelloWorld::onHasLicenseMsg(sdkbox::HasLicenseHandle hasLicenseHandle) {
    auto hasLicense = sdkbox::PluginGameroom::purchaseGetLicense(hasLicenseHandle);
    ::CCLOG(
            "onHasLicenseMsg, Has License: %llu",
            hasLicense
    );
}

发送 App 日志事件

你可以通过下面的方法将你的游戏事件日志记录到 Facebook Analytics:

auto formData = sdkbox::PluginGameroom::formDataCreateNew();
char key[sdkbox::FBG_BUFFER_SIZE]{"sdkbox_key"};
char value[sdkbox::FBG_BUFFER_SIZE]{"3.1415"};
sdkbox::PluginGameroom::formDataSet(formData, key, sdkbox::FBG_BUFFER_SIZE, value, sdkbox::FBG_BUFFER_SIZE);
sdkbox::PluginGameroom::logAppEvent("test_event", formData);

::CCLOG("Gameroom Send App Event with sum value");
sdkbox::PluginGameroom::logAppEventWithValueToSum("test_event", formData, 1024.2);
sdkbox::PluginGameroom::formDataDispose(formData);

键值对数据存储在 FormData 结构中。如果你想在事件中提供额外的值,你应该使用 logAppEventWithValueToSum() 方法。

发送游戏请求

你可以使用下面的方法触发一个对话框以在你的游戏内发送游戏请求:

sdkbox::PluginGameroom::appRequest(
    "hello world, try this gameroom sdk demo.",
    nullptr,
    nullptr,
    "faceboo_user_id_1,facebook_user_id_2",
    nullptr,
    nullptr,
    20,
    nullptr,
    "hello"
);

通常情况下,你不需要设置用户 ID ,这样就可以让玩家在对话框里选择他想发送请求的朋友。

sdkbox::PluginGameroom::appRequest(
    "hello world, try this gameroom sdk demo.",
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    20,
    nullptr,
    "hello"
);

在游戏请求的回调里,你可以像下面这样得到请求的相关属性和结果:

void HelloWorld::onAppRequestMsg(fbgAppRequestHandle appRequestHandle) {
    char objectID[sdkbox::FBG_BUFFER_SIZE];
    //auto size = sdkbox::PluginGameroom::appRequestGetRequestObjectID(appRequestHandle, objectID, sdkbox::FBG_BUFFER_SIZE);
    auto size = fbg_AppRequest_GetRequestObjectId(appRequestHandle, objectID, sdkbox::FBG_BUFFER_SIZE);
    ::CCLOG("onAppRequestMsg");
    ::CCLOG("size = %lu\n", size);  // return 0 here, indicating that appRequestHandle is invalid.

    char toUser[sdkbox::FBG_BUFFER_SIZE];
    size = sdkbox::PluginGameroom::appRequestGetTo(appRequestHandle, toUser, sdkbox::FBG_BUFFER_SIZE);
    ::CCLOG("size = %lu\n", size);

    ::CCLOG(
        "object id: %s, to user: %s",
        objectID,
        toUser
    );
}

API Reference

Although you can use these methods anywhere, some methods need Gameroom handle object in practice. So this document distinguishes the common Methods and the Methods in Listener Callbacks. 虽然理论上你可以在任何地方使用这些方法,但是有一些方法需要 handle 对象作为参数。所以本文档区分普通的方法以及在 Listener 类的回调函数中使用的方法。

Methods

static int init(const char* appID);

Initialize the Gameroom Plugin. appID is your Facebook Application ID. The method will return 0 if the plugin is Initialized successfully.

static std::string login();

Player login. It will return a string representing GameroomReq. 用户登录。这个方法将返回一串表示 GameroomReq 的字符串。

static std::string loginWithScopes(uint32_t scopeCount, const std::vector<std::string>& loginScopes);

Player login with some permissions. scopeCount is the total of the permissions. loginScopes is a vector which can include these values: public_profile, email, user_friends and publish_actions. The method will return a string representing GameroomReq.

static bool isLoggedIn();

Check whether the player has logged in.

static std::string feedShare(
    const char* toId,
    const char* link,
    const char* linkName,
    const char* linkCaption,
    const char* linkDescription,
    const char* pictureLink,
    const char* mediaSource
);

Share to Facebook. The meaning of each parameters is as its name. The method will return a string representing GameroomReq.

static std::string purchaseIAP(
    const char* product,
    uint32_t quantity,
    uint32_t quantityMin,
    uint32_t quantityMax,
    const char* requestId,
    const char* pricePointId,
    const char* testCurrency
);

Purchase a product with a prouduct ID. quantity is the number of product, quantityMin is the minimum number of quantity of product, quantityMax is the maximum of quantity of product. For other parameters, you can refer to Facebook Gameroom SDK and SDKBOX Gameroom Plugin Sample. The method will return a string representing GameroomReq.

static std::string purchaseIAPWithProductURL(
    const char* product,
    uint32_t quantity,
    uint32_t quantityMin,
    uint32_t quantityMax,
    const char* requestId,
    const char* pricePointId,
    const char* testCurrency
);

Purchase a product with a prouduct url link. quantity is the number of product, quantityMin is the minimum number of quantity of product, quantityMax is the maximum of quantity of product. For other parameters, you can refer to Facebook Gameroom SDK. The method will return a string representing GameroomReq.

static std::string payPremium();

Purchase a premium version or license. It will return a string representing GameroomReq.

static std::string hasLicense();

Check whether the player has license or premium version. The method will return a string representing GameroomReq.

static std::string logAppEvent(const char* eventName, const FormDataHandle formData);

Send an event to Facebook Analytics. FormDataHandle is created and set by other APIs. The method will return a string representing GameroomReq.

static std::string logAppEventWithValueToSum(const char* eventName, const FormDataHandle formData, float valueToSum);

Send an event to Facebook Analytics with an extra value valueToSum. FormDataHandle is created and set by other APIs. The method will return a string representing GameroomReq.

static const FormDataHandle formDataCreateNew();

Create a FormDataHandle object to store key-value pairs in an app event.

static void formDataSet(
    const FormDataHandle obj,
    char *fieldNameBuffer,
    size_t fieldNameBufferLen,
    char *valueBuffer,
    size_t valueBufferLen
);

Store a key-value pair into FormDataHandle object.

static size_t formDataGet(
    const FormDataHandle obj,
    char *fieldNameBuffer,
    size_t fieldNameBufferLen,
    char *valueBuffer,
    size_t valueBufferLen
);

Get a key-value pair from FormDataHandle object.

static void formDataDelete(const FormDataHandle obj, char *fieldNameBuffer, size_t fieldNameBufferLen);

Delete a key-value pair from FormDataHandle object.

static bool formDataHas(const FormDataHandle obj, char* fieldNameBuffer, size_t fieldNameBufferLen);

Check whether the FormDataHandle object has a specified key-value pair.

static void formDataDispose(const FormDataHandle obj);

Destory FormDataHandle object.

static std::string appRequest(
    const char* message,
    const char* actionType,
    const char* objectID,
    const char* to,
    const char* filters,
    const char* excludeIDs,
    uint32_t maxRecipients,
    const char* data,
    const char* title
);

Send an app request to some users. if parameter to is nullptr, this method will let player to choose which users he want to send the request. For other parameters, please refer to Facebook Game Service Requests and SDKBOX Gameroom Plugin Sample. The method will return a string representing GameroomReq.

Listener Callbacks

virtual void onLoginAccessTokenMsg(sdkbox::AccessTokenHandle);

Triggered by login() or loginWithScopes().

virtual void onFeedShareMsg(sdkbox::FeedShareHandle);

Triggered by feedShare().

virtual void onPurchaseIAPMsg(sdkbox::PurchaseHandle);

Triggered by purchaseIAP(), purchaseIAPWithProductURL() or payPremium().

virtual void onHasLicenseMsg(sdkbox::HasLicenseHandle);

Triggered by hasLicense().

virtual void onAppRequestMsg(sdkbox::AppRequestHandle);

Triggered by appRequest().

static int setListener(GameroomListener *);

Set a pointer to listener object.

static GameroomListener* removeListener();

Delete current listener object, return the pointer to it.

static GameroomListener* listener();

Return the pointer to current listener object.

Methods in Listener Callbacks

These methods can be called in onLoginAccessTokenMsg to get some information from the AccessTokenHandle object.

static bool accessTokenIsValid(AccessTokenHandle obj);

Check the access token is valid.

static FacebookID accessTokenGetUserID(AccessTokenHandle obj);

Get the Facebook User ID.

static size_t accessTokenGetTokenString(AccessTokenHandle obj, char* buffer, size_t bufferLen);

Get the access token string.

static uint64_t accessTokenGetExpirationTimestamp(AccessTokenHandle obj);

Get the expired time of access Token.

static size_t accessTokenGetPermissions(AccessTokenHandle obj, LoginScope* buffer, size_t bufferLen);

Get the applied permissions.

static const char* loginScopeToString(LoginScope loginScope);

Get the string name of applied permission.

This method can be called in onFeedShareMsg to get the post ID.

static FacebookID feedShareGetPostID(FeedShareHandle obj);

Get the post ID.

These methods can be called in onPurchaseIAPMsg to get some information from the PurchaseHandle object.

static size_t purchaseGetPaymentID(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the payment ID.

static uint32_t purchaseGetAmount(PurchaseHandle obj);

Get the of purchasing.

static size_t purchaseGetCurrency(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the currency of purchasing.

static uint64_t purchaseGetPurchaseTime(PurchaseHandle obj);

Get the time of purchasing.

static size_t purchaseGetProductID(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the product ID.

static size_t purchaseGetPurchaseToken(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the token of purchasing.

static uint32_t purchaseGetQuantity(PurchaseHandle obj);

Get the quantity of purchasing.

static size_t purchaseGetRequestID(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the request ID of purchasing.

static size_t purchaseGetStatus(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the status of purchasing.

static size_t purchaseGetSignedRequest(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the signed request.

static uint64_t purchaseGetErrorCode(PurchaseHandle obj);

Get the error code of purchasing.

static size_t purchaseGetErrorMessage(PurchaseHandle obj, char* buffer, size_t bufferLen);

Get the error message of purchasing.

This method can be called on onHasLicenseMsg to get license ID.

static FacebookID purchaseGetLicense(HasLicenseHandle obj);

Get the license ID.

This methods can be called on onAppRequestMsg to get some information of app request.

static size_t appRequestGetRequestObjectID(const AppRequestHandle obj, char *buffer, size_t bufferLen);

Get the request ID of app request.

static size_t appRequestGetTo(const AppRequestHandle obj, char *buffer, size_t bufferLen);

Get the receivers of app request.