Getting started with SDKBOX!

Thanks @slackmoehrle for the fast reply, the command line works now but I get some errors when I run sdkbox import -b command:


|______ | \ |____/ |] | | _/
| |/ | _ |
] |____| _/ _
Copyright © 2015 Chukong Technologies Inc. v0.5.3

Traceback (most recent call last):
File “monolith.py”, line 4044, in init monolith (sdkbox.c:115129)
File “monolith.py”, line 4029, in monolith.main (sdkbox.c:98704)
File “monolith.py”, line 3322, in monolith.installer.perform (sdkbox.c:79514)
File “monolith.py”, line 3330, in monolith.installer.perform (sdkbox.c:79691)
File “monolith.py”, line 3725, in monolith.installer.main (sdkbox.c:91252)
File “monolith.py”, line 3450, in monolith.installer.load_cocos_project (sdkbox.c:83075)
File “monolith.py”, line 1086, in monolith.CocosProject.init (sdkbox.c:29563)
File “monolith.py”, line 1292, in monolith.CocosProject.setup_script_constants (sdkbox.c:33282)
File “monolith.py”, line 1304, in monolith.CocosProject.get_android_sdk_dir (sdkbox.c:33466)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/UserDict.py”, line 23, in getitem
raise KeyError(key)
KeyError: ‘ANDROID_SDK_ROOT’

I’m working on iOS.

Can you please help me bro?

A few things:

  1. can you please do sdkbox symbols from within your project directory, post output

  2. can you do sdkbox import -vv -b <plugin>, post output

  3. what plugin are you trying, what version of the plugin, what version of cocos2d-x, what version of android?

I’m using cocos2dx-3.4, with the latest versions of SDKBOX and plugin sdkbox-iap_cpp_v1.1.5.tar.gz , I work on iOS, so I don’t need SDK root for Android (or yes?)

I do the following command:

sdkbox import -b …/sdkbox-iap_cpp_v1.1.5.tar.gz

Output:


|______ | \ |____/ |] | | _/
| |/ | _ |
] |____| _/ _
Copyright © 2015 Chukong Technologies Inc. v0.5.3

Traceback (most recent call last):
File “monolith.py”, line 4044, in init monolith (sdkbox.c:115129)
File “monolith.py”, line 4029, in monolith.main (sdkbox.c:98704)
File “monolith.py”, line 3322, in monolith.installer.perform (sdkbox.c:79514)
File “monolith.py”, line 3330, in monolith.installer.perform (sdkbox.c:79691)
File “monolith.py”, line 3725, in monolith.installer.main (sdkbox.c:91252)
File “monolith.py”, line 3450, in monolith.installer.load_cocos_project (sdkbox.c:83075)
File “monolith.py”, line 1086, in monolith.CocosProject.init (sdkbox.c:29563)
File “monolith.py”, line 1292, in monolith.CocosProject.setup_script_constants (sdkbox.c:33282)
File “monolith.py”, line 1304, in monolith.CocosProject.get_android_sdk_dir (sdkbox.c:33466)
File “/usr/lib/python2.7/UserDict.py”, line 23, in getitem
raise KeyError(key)
KeyError: ‘ANDROID_SDK_ROOT’

Can you make sure you are using the latest sdkbox installer?

Yes… What can I do?

can you run an sdkbox symbols import -b <path to plugin> and post the output.

Ok I’ve solved the issue

I did: sdkbox import -b …/sdkbox-iap_cpp_v1.1.5.tar.gz

And a new version was released (you were right), I typed yes and it download and istall ok, but ending with the same error.

I just did again the same command: sdkbox import -b …/sdkbox-iap_cpp_v1.1.5.tar.gz

And I get it work:


|______ | \ |____/ |] | | _/
| |/ | _ |
] |____| _/ _
Copyright © 2015 Chukong Technologies Inc. v0.5.4

[/]
Please reference to the following section in the doc/installation_guide.pdf from the downloaded zip file to finish the integration:

  1. Step 2.5: modify the Android Java code

  2. Step 3: modify your game code

Installation Successful :slight_smile:

Then I followed your video and all seems to be fine, but when I run the project I get some errors:


Ld /Users/David/Library/Developer/Xcode/DerivedData/ProbaBox-egtsqwzstdtarvgjtszivbhueiqo/Build/Products/Debug-iphonesimulator/ProbaBox\ iOS.app/ProbaBox\ iOS normal x86_64
    cd /Users/David/Desktop/ProbaBox/proj.ios_mac
    export IPHONEOS_DEPLOYMENT_TARGET=5.0
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.4.sdk -L/Users/David/Library/Developer/Xcode/DerivedData/ProbaBox-egtsqwzstdtarvgjtszivbhueiqo/Build/Products/Debug-iphonesimulator -Lsdkbox.framework -LPluginIAP.framework -F/Users/David/Library/Developer/Xcode/DerivedData/ProbaBox-egtsqwzstdtarvgjtszivbhueiqo/Build/Products/Debug-iphonesimulator -F/Users/David/Desktop/ProbaBox/proj.ios_mac -filelist /Users/David/Library/Developer/Xcode/DerivedData/ProbaBox-egtsqwzstdtarvgjtszivbhueiqo/Build/Intermediates/ProbaBox.build/Debug-iphonesimulator/ProbaBox\ iOS.build/Objects-normal/x86_64/ProbaBox\ iOS.LinkFileList -Xlinker -objc_abi_version -Xlinker 2 -stdlib=libc++ -Xlinker -no_implicit_dylibs -fobjc-link-runtime -mios-simulator-version-min=5.0 -framework Security /Users/David/Library/Developer/Xcode/DerivedData/ProbaBox-egtsqwzstdtarvgjtszivbhueiqo/Build/Products/Debug-iphonesimulator/libcocos2d\ iOS.a -framework CoreMotion -framework Foundation -framework UIKit -framework CoreGraphics -framework OpenGLES -lz -framework QuartzCore -framework OpenAL -framework AVFoundation -framework AudioToolbox -framework sdkbox -framework PluginIAP -framework StoreKit -Xlinker -dependency_info -Xlinker /Users/David/Library/Developer/Xcode/DerivedData/ProbaBox-egtsqwzstdtarvgjtszivbhueiqo/Build/Intermediates/ProbaBox.build/Debug-iphonesimulator/ProbaBox\ iOS.build/Objects-normal/x86_64/ProbaBox\ iOS_dependency_info.dat -o /Users/David/Library/Developer/Xcode/DerivedData/ProbaBox-egtsqwzstdtarvgjtszivbhueiqo/Build/Products/Debug-iphonesimulator/ProbaBox\ iOS.app/ProbaBox\ iOS

Undefined symbols for architecture x86_64:
  "HelloWorld::onCanceled(sdkbox::Product const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "HelloWorld::onRestored(sdkbox::Product const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "HelloWorld::onRequestIAP(cocos2d::Ref*)", referenced from:
      HelloWorld::init()::$_0::operator()(cocos2d::Ref*) const in HelloWorldScene.o
  "HelloWorld::onProductRequestFailure(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "HelloWorld::onProductRequestSuccess(std::__1::vector<sdkbox::Product, std::__1::allocator > const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "HelloWorld::onFailure(sdkbox::Product const&, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "HelloWorld::onSuccess(sdkbox::Product const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "non-virtual thunk to HelloWorld::onCanceled(sdkbox::Product const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "non-virtual thunk to HelloWorld::onRestored(sdkbox::Product const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "non-virtual thunk to HelloWorld::onProductRequestFailure(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "non-virtual thunk to HelloWorld::onProductRequestSuccess(std::__1::vector<sdkbox::Product, std::__1::allocator > const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "non-virtual thunk to HelloWorld::onFailure(sdkbox::Product const&, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
  "non-virtual thunk to HelloWorld::onSuccess(sdkbox::Product const&)", referenced from:
      vtable for HelloWorld in HelloWorldScene.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

 

Did you define the listeners in your .cpp?

I have the following code:

HelloWorld.h


#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "PluginIAP/PluginIAP.h"
class HelloWorld : public cocos2d::Layer, public sdkbox::IAPListener
{
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    void onShowAds(cocos2d::Ref* sender);
    void onRequestIAP(cocos2d::Ref* sender);
    void onRestoreIAP(cocos2d::Ref* sender);
    void onIAP(cocos2d::Ref* sender);
    
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
    
private:
    void updateIAP(const std::vector& products);
    virtual void onSuccess(sdkbox::Product const& p) override;
    virtual void onFailure(sdkbox::Product const& p, const std::string &msg) override;
    virtual void onCanceled(sdkbox::Product const& p) override;
    virtual void onRestored(sdkbox::Product const& p) override;
    virtual void onProductRequestSuccess(std::vector const& products) override;
    virtual void onProductRequestFailure(const std::string &msg) override;
    
};

#endif // __HELLOWORLD_SCENE_H__

HelloWorld.cpp


include "HelloWorldScene.h"

USING_NS_CC;

template  std::string tostr(const T& t) { std::ostringstream os;
    os<addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.

    // add a "close" icon to exit the progress. it's an autorelease object
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
	closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));
    
    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
    
    // position the label on the center of the screen
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));

    // add the label as a child to this layer
    this->addChild(label, 1);

    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");

    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    // add the sprite as a child to this layer
    this->addChild(sprite, 0);
    
    auto menuNode= Node::create();
    menuNode->setName("menuNode");
    
    sdkbox::IAP::init();
    sdkbox::IAP::setDebug(true);
    sdkbox::IAP::setListener(this);
    
    auto menuitem= MenuItemFont::create("Remove Ads");
    menuitem->setFontNameObj ("Marker Felt.ttf");
    menuitem->setFontSizeObj (32);
    menuitem->setName("menuItem");
    menuitem->setPosition(400,400);
    menuitem->setCallback([&] (cocos2d::Ref *sender)
    {
        onRequestIAP(sender);
    });
    
    auto menu= Menu::create(menuitem,NULL);
    menu->setName("Menu");
    menuNode->addChild(menu, 1);
    menu->setPosition(Vec2::ZERO);
    
    this->addChild(menuNode, 2);
    

    
    return true;
}


void onRequestIAP(cocos2d::Ref* sender)
{
    sdkbox::IAP::purchase("remove_ads");
}

void onShowAds(cocos2d::Ref* sender)
{
    CCLOG("ShowA dds");
}


void onRestoreIAP(cocos2d::Ref* sender)
{
    sdkbox::IAP::restore();
}


void onIAP(cocos2d::Ref* sender)
{
    auto btn =static_cast(sender);
    sdkbox::Product* p = (sdkbox::Product*)btn->getUserData();
    
    CCLOG("Start IAP %s", p->name.c_str());
    sdkbox::IAP::purchase(p->name);
    
}



void HelloWorld::menuCloseCallback(Ref* pSender)
{
    
    
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
	MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif

    Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

What I'm doing wrong?

you need to add add HelloWorld:: to those functions in your cpp.

thanks again, what a fail! xD

I fixed it but I still have the same errors… do you see any more wrong?

Sure, it seems that you need to override:

class IAPListener
    {
    public:
        /**
        * Called when an IAP processed successfully
        */
        virtual void onSuccess(const Product& p) = 0;

        /**
        * Called when an IAP fails
        */
        virtual void onFailure(const Product& p, const std::string& msg) = 0;

        /**
        * Called when user canceled the IAP
        */
        virtual void onCanceled(const Product& p) = 0;

        /**
        * Called when server returns the IAP items user already purchased
        * @note this callback will be called multiple times if there are multiple IAP
        */
        virtual void onRestored(const Product& p) = 0;

        /**
        * Called the product request is successful, usually developers use product request to update the latest info(title, price) from IAP
        */
        virtual void onProductRequestSuccess(const std::vector<Product>& products) = 0;

        /**
        * Called when the product request fails
        */
        virtual void onProductRequestFailure(const std::string& msg) = 0;
    };

Your overrides are overriding something that doesn’t match these signatures.

I can’t find IAPListener class, I have that code in my PluginIAP.h… Does I have to create that class, or what I have to do?

you are making a HelloWorld class that subclasses IAPListener so these should be there for you?

Are you running the latest IAP plugin?

Yes, I’m using the latest version of sdkbox and IAP plugin.

so in your .h you need something like this:

class HelloWorld : public cocos2d::Layer, public sdkbox::IAPListener
{
private:    
    virtual void onSuccess(sdkbox::Product const& p) override;
    virtual void onFailure(sdkbox::Product const& p, const std::string &msg) override;
    virtual void onCanceled(sdkbox::Product const& p) override;
    virtual void onRestored(sdkbox::Product const& p) override;
    virtual void onProductRequestSuccess(std::vector<sdkbox::Product> const &products) override;
    virtual void onProductRequestFailure(const std::string &msg) override;
}

and in .cpp

void HelloWorld::onSuccess(const sdkbox::Product &p)
{
    CCLOG("Purchase Success: %s", p.id.c_str());
}

void HelloWorld::onFailure(const sdkbox::Product &p, const std::string &msg)
{
    CCLOG("Purchase Failed: %s", msg.c_str());
}

void HelloWorld::onCanceled(const sdkbox::Product &p)
{
    CCLOG("Purchase Canceled: %s", p.id.c_str());
}

void HelloWorld::onRestored(const sdkbox::Product& p)
{
    CCLOG("Purchase Restored: %s", p.name.c_str());
}

void HelloWorld::onProductRequestSuccess(const std::vector<sdkbox::Product> &products)
{
    // do something
}

void HelloWorld::onProductRequestFailure(const std::string &msg)
{
    CCLOG("Fail to load products");
}

Finally it works!! Thank you so much!

Great! Glad it works.

make tutorials for js versionnn. it will be really helpfull

Hi I am a developer of 3rd party plugins and I would like ours to work with SDKBOX

How do we go about that? Is it a partnership with you or do we do the leg work ourselves?

Thanks