Adding CocosPlayerJS for Android

This commit is contained in:
Rohan Kuruvilla 2013-01-24 18:29:39 -08:00
parent be305f84b6
commit 43229cb440
31 changed files with 1911 additions and 0 deletions

View File

@ -0,0 +1,152 @@
#include "AppDelegate.h"
#include "PlayerStatus.h"
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "ScriptingCore.h"
#include "generated/cocos2dx.hpp"
#include "cocos2d_specifics.hpp"
#include "js_bindings_chipmunk_registration.h"
#include "js_bindings_ccbreader.h"
#include "MainSceneHelper.h"
#ifdef JSLOG
#undef JSLOG
#endif
#define JSLOG CocosBuilder_log
char *_js_log_buf_ccbuilder = NULL;
USING_NS_CC;
using namespace CocosDenshion;
AppDelegate::AppDelegate()
{
}
AppDelegate::~AppDelegate()
{
CCScriptEngineManager::sharedManager()->purgeSharedManager();
}
void handle_ccb_run() {
ScriptingCore::getInstance()->runScript("main.js");
}
void handle_connected() {
CCBHelper::setStatusMessage("Connected!");
}
void handle_disconnected() {
CCBHelper::setStatusMessage("Disconnected");
}
void handle_ccb_stop() {
CCLOG("STOP UNIMPLEMENTED");
}
extern "C" {
bool runMainScene() {
PlayerStatus::loadMainScene("StatusLayer.ccbi");
return true;
}
bool AppDelegate::applicationDidFinishLaunching()
{
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
pDirector->setProjection(kCCDirectorProjection2D);
CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
CCSize designSize = CCSizeMake(320, 480);
CCSize resourceSize = CCSizeMake(320, 480);
if (screenSize.height > 1024)
{
resourceSize = CCSizeMake(1280, 1920);
CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(CCArray::create(CCString::create("resources-xlarge"), CCString::create(""), NULL));
}
else if (screenSize.height > 960)
{
resourceSize = CCSizeMake(640, 960);
CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(CCArray::create(CCString::create("resources-large"), CCString::create(""), NULL));
}
else if (screenSize.height > 480)
{
resourceSize = CCSizeMake(480, 720);
CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(CCArray::create(CCString::create("resources-medium"), CCString::create(""), NULL));
}
else
{
resourceSize = CCSizeMake(320, 568);
CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(CCArray::create(CCString::create("resources-small"), CCString::create(""), NULL));
}
pDirector->setContentScaleFactor(resourceSize.height/designSize.height);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);
CCFileUtils::sharedFileUtils()->setSearchPath(CCArray::create(CCString::create(CCFileUtils::sharedFileUtils()->getWriteablePath()),
CCString::create("assets/"), CCString::create(""), NULL));
// turn on display FPS
pDirector->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
ScriptingCore* sc = ScriptingCore::getInstance();
sc->addRegisterCallback(register_all_cocos2dx);
sc->addRegisterCallback(register_cocos2dx_js_extensions);
sc->addRegisterCallback(register_CCBuilderReader);
sc->addRegisterCallback(jsb_register_chipmunk);
sc->start();
CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
runMainScene();
}
void handle_signal(int signal) {
static int internal_state = 0;
ScriptingCore* sc = ScriptingCore::getInstance();
// should start everything back
CCDirector* director = CCDirector::sharedDirector();
if (director->getRunningScene()) {
director->popToRootScene();
} else {
CCPoolManager::sharedPoolManager()->finalize();
if (internal_state == 0) {
//sc->dumpRoot(NULL, 0, NULL);
sc->start();
internal_state = 1;
} else {
sc->runScript("hello.js");
internal_state = 0;
}
}
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground()
{
CCDirector::sharedDirector()->stopAnimation();
SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
SimpleAudioEngine::sharedEngine()->pauseAllEffects();
}
// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground()
{
CCDirector::sharedDirector()->startAnimation();
SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
SimpleAudioEngine::sharedEngine()->resumeAllEffects();
}
}

View File

@ -0,0 +1,53 @@
//
// GCTestAppDelegate.h
// GCTest
//
// Created by Rohan Kuruvilla on 06/08/2012.
// Copyright __MyCompanyName__ 2012. All rights reserved.
//
#ifndef _APP_DELEGATE_H_
#define _APP_DELEGATE_H_
#include "CCApplication.h"
/**
@brief The cocos2d Application.
The reason for implement as private inheritance is to hide some interface call by CCDirector.
*/
class AppDelegate : private cocos2d::CCApplication
{
public:
AppDelegate();
virtual ~AppDelegate();
/**
@brief Implement CCDirector and CCScene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching();
/**
@brief The function be called when the application enter background
@param the pointer of the application
*/
virtual void applicationDidEnterBackground();
/**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
};
void handle_ccb_run();
void handle_ccb_stop();
void handle_connected();
void handle_disconnected();
#endif // _APP_DELEGATE_H_

View File

@ -0,0 +1,34 @@
#include <stdlib.h>
#include <jni.h>
#include <android/log.h>
#include <string>
#include "platform/android/jni/JniHelper.h"
#include "cocoa/CCString.h"
#include "Java_org_cocos2dx_cocosplayer_CocosPlayerSocket.h"
#define LOG_TAG "Java_org_cocos2dx_cocosplayer_CocosPlayerSocket.cpp"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define SOCKET_CLASS_NAME "org/cocos2dx/cocosplayer/CocosPlayerSocket"
#define HELPER_CLASS_NAME "org/cocos2dx/cocosplayer/CCBFileUtilsHelper"
using namespace cocos2d;
using namespace std;
extern "C" {
void setPairingCodeJNI(int code) {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, SOCKET_CLASS_NAME, "setPairingCode", "(I)V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID, code);
t.env->DeleteLocalRef(t.classID);
}
}
void cleanCacheDirJNI() {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, HELPER_CLASS_NAME, "cleanCache", "()V")) {
t.env->CallStaticVoidMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
}

View File

@ -0,0 +1,34 @@
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __Java_org_cocos2dx_cocosplayer_CocosPlayerSocket_H__
#define __Java_org_cocos2dx_cocosplayer_CocosPlayerSocket_H__
#include <string>
extern "C" {
extern void setPairingCodeJNI(int code);
extern void cleanCacheDirJNI();
}
#endif

View File

@ -0,0 +1,87 @@
#include "MainSceneHelper.h"
CCMenuItemImage * CCBHelper::mBtnRun = NULL;
CCMenuItemImage * CCBHelper::mBtnPair = NULL;
CCMenuItemImage * CCBHelper::mBtnReset = NULL;
CCLabelTTF * CCBHelper::mLblStatus = NULL;
CCLabelTTF * CCBHelper::mLblPair = NULL;
CCLabelTTF * CCBHelper::mLblInstructions = NULL;
std::string CCBHelper::mLblStatus_background = "";
std::string CCBHelper::mLblPair_background = "";
bool CCBHelper::mLblInstructions_visible = true;
void CCBHelper::setStatusObject(CCLabelTTF *status) {
if(mLblStatus == NULL) {
mLblStatus = CCLabelTTF::create();
}
status->retain();
mLblStatus = status;
if(mLblStatus_background != "") {
status->setString(mLblStatus_background.c_str());
}
}
void CCBHelper::setStatusMessage(std::string str) {
if(mLblStatus == NULL) {
mLblStatus_background = str;
} else {
mLblStatus->setString(str.c_str());
}
}
void CCBHelper::setInstructionsObject(CCLabelTTF *status) {
if(mLblInstructions == NULL) {
mLblInstructions = CCLabelTTF::create();
}
status->retain();
mLblInstructions = status;
if(!mLblInstructions_visible) {
mLblInstructions->setVisible(false);
}
}
void CCBHelper::setInstructionsMessage(bool isVisible) {
if(mLblInstructions == NULL) {
mLblInstructions_visible = isVisible;
} else {
mLblInstructions_visible = isVisible;
mLblInstructions->setVisible(isVisible);
}
}
void CCBHelper::setPairObject(CCLabelTTF *pair) {
if(mLblPair == NULL) {
mLblPair = CCLabelTTF::create();
}
pair->retain();
mLblPair = pair;
if(mLblPair_background != "") {
mLblPair->setString(mLblPair_background.c_str());
}
}
void CCBHelper::setPairMessage(std::string str) {
if(mLblPair == NULL) {
mLblPair_background = str;
} else {
mLblPair->setString(str.c_str());
}
}
bool CCBHelper::isMainJSPresent() {
std::string path = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("main.js");
CCLOG("PATH RETURNED: %s", path.c_str());
if(path == "") {
return false;
}
return true;
}

View File

@ -0,0 +1,29 @@
#include "cocos2d.h"
#include "string.h"
USING_NS_CC;
class CCBHelper {
public:
static CCMenuItemImage * mBtnRun;
static CCMenuItemImage * mBtnReset;
static CCMenuItemImage * mBtnPair;
static CCLabelTTF *mLblStatus;
static std::string mLblStatus_background;
static CCLabelTTF *mLblPair;
static std::string mLblPair_background;
static CCLabelTTF *mLblInstructions;
static bool mLblInstructions_visible;
static void setPairObject(CCLabelTTF *pair);
static void setPairMessage(std::string str);
static void setInstructionsObject(CCLabelTTF *instr);
static void setInstructionsMessage(bool isVisible);
static void setStatusObject(CCLabelTTF *status);
static void setStatusMessage(std::string str);
static bool isMainJSPresent();
};

View File

@ -0,0 +1,156 @@
#include "PlayerStatus.h"
#include "PlayerStatusLoader.h"
#include "MainSceneHelper.h"
#include "AppDelegate.h"
#include "GUI/CCEditBox/CCEditBox.h"
#include "jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
USING_NS_CC;
USING_NS_CC_EXT;
PlayerStatus::PlayerStatus(): mBtnRun(NULL), mBtnReset(NULL), mBtnPair(NULL),
mLblStatus(NULL), mLblInstructions(NULL), mLblPair(NULL)
{
}
PlayerStatus::~PlayerStatus()
{
CC_SAFE_RELEASE(mBtnRun);
CC_SAFE_RELEASE(mBtnReset);
CC_SAFE_RELEASE(mBtnPair);
CC_SAFE_RELEASE(mLblStatus);
CC_SAFE_RELEASE(mLblPair);
CC_SAFE_RELEASE(mLblInstructions);
}
void PlayerStatus::onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader) {
}
SEL_CCControlHandler PlayerStatus::onResolveCCBCCControlSelector(CCObject * pTarget, const char * pSelectorName) {
return NULL;
}
SEL_MenuHandler PlayerStatus::onResolveCCBCCMenuItemSelector(CCObject * pTarget, const char * pSelectorName) {
CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "pressedPair:", PlayerStatus::pressedPair);
CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "pressedReset:", PlayerStatus::pressedReset);
CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this, "pressedRun:", PlayerStatus::pressedRun);
return NULL;
}
void editBoxCallbackFunc(const char* pText, void* ctx)
{
PlayerStatus *thiz = (PlayerStatus *)ctx;
std::string text(pText);
if(text == "" || text == " ") {
thiz->mLblPair->setString("Auto");
setPairingCodeJNI(-1);
} else {
thiz->mLblPair->setString(pText);
setPairingCodeJNI(atoi(pText));
}
}
void PlayerStatus::pressedPair(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent) {
showEditTextDialogJNI("Enter pairing code", "", kEditBoxInputModeNumeric, kEditBoxInputFlagInitialCapsWord,
kKeyboardReturnTypeDone, 4, editBoxCallbackFunc, (void*)this);
}
void PlayerStatus::pressedReset(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent) {
cleanCacheDirJNI();
this->mBtnRun->setEnabled(false);
this->mBtnReset->setEnabled(false);
}
void PlayerStatus::pressedRun(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent) {
handle_ccb_run();
}
bool PlayerStatus::onAssignCCBMemberVariable(CCObject * pTarget, const char * pMemberVariableName, CCNode * pNode) {
CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "btnRun", CCMenuItemImage *, this->mBtnRun);
if(strcmp(pMemberVariableName, "btnRun")) {
if(this->mBtnRun == NULL) {
this->mBtnRun = CCMenuItemImage::create();
}
if(CCBHelper::isMainJSPresent()) {
this->mBtnRun->setEnabled(true);
} else {
this->mBtnRun->setEnabled(false);
}
}
CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "btnReset", CCMenuItemImage *, this->mBtnReset);
if(strcmp(pMemberVariableName, "btnReset")) {
if(this->mBtnReset == NULL) {
this->mBtnReset = CCMenuItemImage::create();
}
if(CCBHelper::isMainJSPresent()) {
this->mBtnReset->setEnabled(true);
} else {
this->mBtnReset->setEnabled(false);
}
}
CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "btnPair", CCMenuItemImage *, this->mBtnPair);
CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "lblStatus", CCLabelTTF *, this->mLblStatus);
if(strcmp(pMemberVariableName, "lblStatus") && this->mLblStatus != NULL) {
CCBHelper::setStatusObject(this->mLblStatus);
}
CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "lblPair", CCLabelTTF *, this->mLblPair);
if(strcmp(pMemberVariableName, "lblPair") && this->mLblPair != NULL) {
CCBHelper::setPairObject(this->mLblPair);
}
CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "lblInstructions", CCLabelTTF *, this->mLblInstructions);
if(strcmp(pMemberVariableName, "lblInstructions") && this->mLblInstructions != NULL) {
CCBHelper::setInstructionsObject(this->mLblInstructions);
}
return false;
}
void PlayerStatus::loadMainScene(const char *pCCBFileName) {
CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary();
ccNodeLoaderLibrary->registerCCNodeLoader("PlayerStatusLayer", PlayerStatusLoader::loader());
/* Create an autorelease CCBReader. */
cocos2d::extension::CCBReader * ccbReader = new cocos2d::extension::CCBReader(ccNodeLoaderLibrary);
ccbReader->autorelease();
/* Read a ccbi file. */
// Load the scene from the ccbi-file, setting this class as
// the owner will cause lblTestTitle to be set by the CCBReader.
// lblTestTitle is in the TestHeader.ccbi, which is referenced
// from each of the test scenes.
CCNode * node = ccbReader->readNodeGraphFromFile(pCCBFileName, NULL);
CCScene * scene = CCScene::create();
if(node != NULL) {
scene->addChild(node);
}
/* Push the new scene with a fancy transition. */
ccColor3B transitionColor;
transitionColor.r = 0;
transitionColor.g = 0;
transitionColor.b = 0;
CCDirector::sharedDirector()->runWithScene(CCTransitionFade::create(0.5f, scene, transitionColor));
}

View File

@ -0,0 +1,56 @@
#ifndef _PLAYERSTATUS_H_
#define _PLAYERSTATUS_H_
#include "cocos2d.h"
#include "cocos-ext.h"
#include "Java_org_cocos2dx_cocosplayer_CocosPlayerSocket.h"
/*
* Note: for some pretty hard fucked up reason, the order of inheritance is important!
* When CCLayer is the 'first' inherited object:
* During runtime the method call to the (pure virtual) 'interfaces' fails jumping into a bogus method or just doing nothing:
* #0 0x000cf840 in non-virtual thunk to HelloCocos....
* #1 ....
*
* This thread describes the problem:
* http://www.cocoabuilder.com/archive/xcode/265549-crash-in-virtual-method-call.html
*/
class PlayerStatus
: public cocos2d::CCLayer
, public cocos2d::extension::CCBSelectorResolver
, public cocos2d::extension::CCBMemberVariableAssigner
, public cocos2d::extension::CCNodeLoaderListener
{
public:
CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(PlayerStatus, create);
PlayerStatus();
virtual ~PlayerStatus();
void openTest(const char * pCCBFileName, const char * pCCNodeName = NULL, cocos2d::extension::CCNodeLoader * pCCNodeLoader = NULL);
virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, const char * pSelectorName);
virtual cocos2d::extension::SEL_CCControlHandler onResolveCCBCCControlSelector(cocos2d::CCObject * pTarget, const char * pSelectorName);
virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, const char * pMemberVariableName, cocos2d::CCNode * pNode);
virtual void onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader);
void pressedPair(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent);
void pressedReset(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent);
void pressedRun(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent);
static void loadMainScene(const char *fileName);
cocos2d::CCMenuItemImage* mBtnRun;
cocos2d::CCMenuItemImage* mBtnReset;
cocos2d::CCMenuItemImage* mBtnPair;
cocos2d::CCLabelTTF* mLblStatus;
cocos2d::CCLabelTTF* mLblInstructions;
cocos2d::CCLabelTTF* mLblPair;
};
#endif

View File

@ -0,0 +1,17 @@
#ifndef _PLAYERSTATUSLOADER_H_
#define _PLAYERSTATUSLOADER_H_
#include "PlayerStatus.h"
/* Forward declaration. */
class CCBReader;
class PlayerStatusLoader : public cocos2d::extension::CCLayerLoader {
public:
CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(PlayerStatusLoader, loader);
protected:
CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(PlayerStatus);
};
#endif

View File

@ -0,0 +1 @@
349baa101ddbdf4edf6d20b17362bd22c0008284

View File

@ -0,0 +1 @@
fe7e93e8e974f39426858d2bfbed7dff26c2b9c4

View File

@ -0,0 +1 @@
20213456280fa1bced942496820fd71cb35ddb64

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>CocosDragonJS</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.cocos2dx.cocosplayer"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="16"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name"
android:icon="@drawable/icon" android:largeHeap="true">
<service android:name=".CocosPlayerPresence" />
<service android:name=".CocosPlayerSocket" />
<activity android:name=".CocosPlayer"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<supports-screens android:largeScreens="true"
android:smallScreens="true"
android:anyDensity="true"
android:normalScreens="true"/>
</manifest>

View File

@ -0,0 +1 @@
aapt.ignore.assets="!*.pvr.gz:!*.gz:!.svn:!.git:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="CocosPlayer" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

View File

@ -0,0 +1,88 @@
#NDK_ROOT="/opt/android/android-ndk"
APPNAME="CocosPlayer"
# options
buildexternalsfromsource=
PARALLEL_BUILD_FLAG=
usage(){
cat << EOF
usage: $0 [options]
Build C/C++ code for $APPNAME using Android NDK
OPTIONS:
-s Build externals from source
-p Run make with -j8 option to take advantage of multiple processors
-h this help
EOF
}
while getopts "sph" OPTION; do
case "$OPTION" in
s)
buildexternalsfromsource=1
;;
p)
PARALLEL_BUILD_FLAG=\-j8
;;
h)
usage
exit 0
;;
esac
done
# exit this script if any commmand fails
set -e
# paths
if [ -z "${NDK_ROOT+aaa}" ];then
echo "please define NDK_ROOT"
exit 1
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# ... use paths relative to current directory
COCOS2DX_ROOT="$DIR/../../../../"
APP_ROOT="$DIR/.."
APP_ANDROID_ROOT="$DIR"
BINDINGS_JS_ROOT="$APP_ROOT/../../../scripting/javascript/bindings/js"
RESROUCE_ROOT="$APP_ROOT/Resources"
echo
echo "Paths"
echo " NDK_ROOT = $NDK_ROOT"
echo " COCOS2DX_ROOT = $COCOS2DX_ROOT"
echo " APP_ROOT = $APP_ROOT"
echo " APP_ANDROID_ROOT = $APP_ANDROID_ROOT"
echo
# Debug
set -x
# make sure assets is exist
if [ -d "$APP_ANDROID_ROOT"/assets ]; then
rm -rf "$APP_ANDROID_ROOT"/assets
fi
mkdir "$APP_ANDROID_ROOT"/assets
# copy bindings/*.js into assets' root
cp -f "$BINDINGS_JS_ROOT"/*.js "$APP_ANDROID_ROOT"/assets
# copy bindings/*.js into assets' root
cp -rf "$RESROUCE_ROOT"/ "$APP_ANDROID_ROOT"/assets
#cp -rf "$CCB_RESOURCE_ROOT" "$APP_ANDROID_ROOT"/assets
echo "Using prebuilt externals"
echo
set -x
"$NDK_ROOT"/ndk-build $PARALLEL_BUILD_FLAG -C "$APP_ANDROID_ROOT" $* \
"NDK_MODULE_PATH=${COCOS2DX_ROOT}:${COCOS2DX_ROOT}/cocos2dx/platform/third_party/android/prebuilt" \
NDK_LOG=0 V=0

View File

@ -0,0 +1,32 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cocosplayer_shared
LOCAL_MODULE_FILENAME := libcocosplayer
LOCAL_SRC_FILES := cocosplayer/main.cpp \
../../Classes/PlayerStatus.cpp\
../../Classes/AppDelegate.cpp \
../../Classes/MainSceneHelper.cpp \
../../Classes/Java_org_cocos2dx_cocosplayer_CocosPlayerSocket.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
LOCAL_WHOLE_STATIC_LIBRARIES += chipmunk_static
LOCAL_WHOLE_STATIC_LIBRARIES += spidermonkey_static
LOCAL_WHOLE_STATIC_LIBRARIES += scriptingcore-spidermonkey
LOCAL_EXPORT_CFLAGS := -DCOCOS2D_DEBUG=2 -DCOCOS2D_JAVASCRIPT
include $(BUILD_SHARED_LIBRARY)
$(call import-module,cocos2dx)
$(call import-module,CocosDenshion/android)
$(call import-module,external/chipmunk)
$(call import-module,scripting/javascript/spidermonkey-android)
$(call import-module,scripting/javascript/bindings)

View File

@ -0,0 +1,3 @@
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -DCOCOS2D_JAVASCRIPT=1
APP_CPPFLAGS += -DCOCOS2D_DEBUG=1 -DCC_ENABLE_CHIPMUNK_INTEGRATION=1

View File

@ -0,0 +1,79 @@
#include "AppDelegate.h"
#include "PlayerStatus.h"
#include "cocos2d.h"
#include "platform/android/jni/JniHelper.h"
#include "CCEventType.h"
#include <jni.h>
#include <android/log.h>
#define LOG_TAG "main"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
using namespace cocos2d;
extern "C"
{
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
JniHelper::setJavaVM(vm);
return JNI_VERSION_1_4;
}
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
{
if (!CCDirector::sharedDirector()->getOpenGLView())
{
CCEGLView *view = CCEGLView::sharedOpenGLView();
view->setFrameSize(w, h);
AppDelegate *pAppDelegate = new AppDelegate();
CCApplication::sharedApplication()->run();
}
else
{
ccDrawInit();
ccGLInvalidateStateCache();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
CCTextureCache::reloadAllTextures();
CCNotificationCenter::sharedNotificationCenter()->postNotification(EVNET_COME_TO_FOREGROUND, NULL);
CCDirector::sharedDirector()->setGLDefaultValues();
}
}
void Java_org_cocos2dx_lib_Cocos2dxGLSurfaceView_nativeRunCCB(JNIEnv* env, jobject thiz)
{
LOGD("INSIDE JNI RUN CALL");
handle_ccb_run();
}
void Java_org_cocos2dx_cocosplayer_CocosPlayerSocket_nativeRunCCB(JNIEnv* env, jobject thiz)
{
LOGD("INSIDE JNI RUN CALL");
handle_ccb_run();
}
void Java_org_cocos2dx_cocosplayer_CocosPlayerSocket_nativeStopCCB(JNIEnv* env, jobject thiz)
{
LOGD("INSIDE JNI STOP CALL");
handle_ccb_stop();
}
void Java_org_cocos2dx_cocosplayer_CocosPlayerSocket_nativeRunScript(JNIEnv* env, jobject thiz, jstring jsString)
{
LOGD("INSIDE JNI RUN SCRIPT CALL");
}
void Java_org_cocos2dx_cocosplayer_CocosPlayerSocket_nativeConnected(JNIEnv* env, jobject thiz)
{
handle_connected();
}
void Java_org_cocos2dx_cocosplayer_CocosPlayerSocket_nativeDisconnected(JNIEnv* env, jobject thiz)
{
handle_disconnected();
}
}

View File

@ -0,0 +1,47 @@
APPNAME="CocosPlayer"
APP_ANDROID_NAME="org.cocos2dx.cocosplayer"
if [ -z "${SDK_ROOT+aaa}" ]; then
# ... if SDK_ROOT is not set, use "$HOME/bin/android-sdk"
SDK_ROOT="$HOME/bin/android-sdk"
fi
if [ -z "${NDK_ROOT+aaa}" ]; then
# ... if NDK_ROOT is not set, use "$HOME/bin/android-ndk"
NDK_ROOT="$HOME/bin/android-ndk"
fi
if [ -z "${COCOS2DX_ROOT+aaa}" ]; then
# ... if COCOS2DX_ROOT is not set
# ... find current working directory
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# ... use paths relative to current directory
COCOS2DX_ROOT="$DIR/../../.."
APP_ROOT="$DIR/.."
APP_ANDROID_ROOT="$DIR"
else
APP_ROOT="$COCOS2DX_ROOT/samples/$APPNAME"
APP_ANDROID_ROOT="$COCOS2DX_ROOT/samples/$APPNAME/proj.android"
fi
echo "NDK_ROOT = $NDK_ROOT"
echo "SDK_ROOT = $SDK_ROOT"
echo "COCOS2DX_ROOT = $COCOS2DX_ROOT"
echo "APP_ROOT = $APP_ROOT"
echo "APP_ANDROID_ROOT = $APP_ANDROID_ROOT"
echo "APP_ANDROID_NAME = $APP_ANDROID_NAME"
echo
echo "Killing and restarting ${APP_ANDROID_NAME}"
echo
set -x
"${SDK_ROOT}"/platform-tools/adb shell am force-stop "${APP_ANDROID_NAME}"
NDK_MODULE_PATH="${COCOS2DX_ROOT}":"${COCOS2DX_ROOT}"/cocos2dx/platform/third_party/android/prebuilt \
"${NDK_ROOT}"/ndk-gdb \
--adb="${SDK_ROOT}"/platform-tools/adb \
--verbose \
--start \
--force

View File

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@ -0,0 +1,13 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-16
android.library.reference.1=../../../../cocos2dx/platform/android/java

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="@+id/widget32"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/widget33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Run"
android:layout_x="150dp"
android:layout_y="262dp" />
<EditText
android:id="@+id/widget34"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Auto"
android:textSize="18sp"
android:layout_x="40dp"
android:layout_y="302dp" />
<Button
android:id="@+id/widget35"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Reset"
android:layout_x="220dp"
android:layout_y="302dp" />
<TextView
android:id="@+id/widget36"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pairing code"
android:layout_x="30dp"
android:layout_y="282dp" />
</AbsoluteLayout>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">CocosDragonJS</string>
</resources>

View File

@ -0,0 +1,175 @@
package org.cocos2dx.cocosplayer;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import java.util.Arrays;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.content.ContextWrapper;
import android.content.Context;
import android.os.Environment;
import java.io.OutputStream;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipException;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
public class CCBFileUtilsHelper {
public static final String TAG = CocosPlayerSocket.class.getSimpleName();
private static boolean isValid(final File file) {
ZipFile zipfile = null;
try {
zipfile = new ZipFile(file);
return true;
} catch (ZipException e) {
Log.i(TAG, "ERROR: "+e.toString());
return false;
} catch (IOException e) {
Log.i(TAG, "ERROR: "+e.toString());
return false;
} finally {
try {
if (zipfile != null) {
zipfile.close();
zipfile = null;
}
} catch (IOException e) {
Log.i(TAG, "ERROR: "+e.toString());
}
}
}
private static void unzip(InputStream is, Context cw) {
try {
File path = new File(CCBFileUtilsHelper.getBaseDirectory(cw));
ZipInputStream zin = new ZipInputStream(is);
ZipEntry ze = null;
byte[] buffer = new byte[1024];
int length;
while ((ze = zin.getNextEntry()) != null) {
Log.v(TAG, "Unzipping " + ze.getName());
if(ze.isDirectory()) {
_dirChecker(path, ze.getName());
} else {
File fileToWrite = new File(path, ze.getName());
FileOutputStream fout = new FileOutputStream(fileToWrite);
while ((length = zin.read(buffer))>0) {
fout.write(buffer, 0, length);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch(Exception e) {
Log.e(TAG, "unzip", e);
}
}
// public static void unzip(String zipname) {
// try {
// String filename;
// //Context cw = getApplicationContext();
// //ContextWrapper cw = new ContextWrapper(this);
// File path = new File(CCBFileUtilsHelper.getBaseDirectory(cw));
// //File path = android.os.Environment.getExternalStorageDirectory(); //Environment.getExternalFilesDir();
// File ccbFile = new File(path, zipname);
// if(!isValid(ccbFile))
// Log.i(TAG, "Zip file recieved is INVALID: ");
// else {
// Log.i(TAG, "Zip file recieved is VALID: ");
// }
// FileInputStream fin = new FileInputStream(ccbFile);
// ZipInputStream zin = new ZipInputStream(fin);
// ZipEntry ze = null;
// byte[] buffer = new byte[1024];
// int length;
// while ((ze = zin.getNextEntry()) != null) {
// Log.v(TAG, "Unzipping " + ze.getName());
// if(ze.isDirectory()) {
// _dirChecker(path, ze.getName());
// } else {
// File fileToWrite = new File(path, ze.getName());
// FileOutputStream fout = new FileOutputStream(fileToWrite);
// while ((length = zin.read(buffer))>0) {
// fout.write(buffer, 0, length);
// }
// zin.closeEntry();
// fout.close();
// }
// }
// zin.close();
// } catch(Exception e) {
// Log.e(TAG, "unzip", e);
// }
// }
private static void _dirChecker(File path, String dir) {
File f = new File(path, dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
public static void unzipCCB(byte[] data, Context cw) {
String zipname = "ccb.zip";
unzip(new ByteArrayInputStream(data), cw);
}
public static String getBaseDirectory(Context cw) {
return cw.getCacheDir().getAbsolutePath();
}
private static File getBasePath() {
return android.os.Environment.getExternalStorageDirectory();
}
private static void cleanDir(File dir) {
long bytesDeleted = 0;
File[] files = dir.listFiles();
for (File file : files) {
if(file.isDirectory()) {
cleanDir(file);
continue;
}
Log.i(TAG, "Deleting file: "+file.getName());
bytesDeleted += file.length();
file.delete();
}
}
public static void cleanCache(Context cw) {
File path = new File(getBaseDirectory(cw));
cleanDir(path);
}
}

View File

@ -0,0 +1,107 @@
package org.cocos2dx.cocosplayer;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import java.util.Arrays;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.content.ContextWrapper;
import android.content.Context;
import android.os.Environment;
import java.io.InputStream;
import com.dd.plist.NSDictionary;
import com.dd.plist.NSData;
import com.dd.plist.UID;
import com.dd.plist.PropertyListParser;
import com.dd.plist.BinaryPropertyListParser;
import com.dd.plist.BinaryPropertyListWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class CCBStreamHandler {
public static final String TAG = CocosPlayerSocket.class.getSimpleName();
public static NSDictionary parseBinaryPLIST(InputStream is) {
try {
NSDictionary rootDict = (NSDictionary)BinaryPropertyListParser.parse(is);
String name = rootDict.objectForKey("cmd").toString();
Log.i(TAG, "Cmd: "+name);
return rootDict;
} catch(Exception ex) {
Log.i(TAG, "ERROR: "+ex.toString());
ex.printStackTrace();
}
return null;
}
public static NSDictionary parseBinaryPLIST(byte[] is) {
try {
NSDictionary rootDict = (NSDictionary)BinaryPropertyListParser.parse(is);
String name = rootDict.objectForKey("cmd").toString();
Log.i(TAG, "Cmd: "+name);
return rootDict;
} catch(Exception ex) {
Log.i(TAG, "Error parsing BinaryPLIST: "+ex.toString());
ex.printStackTrace();
}
return null;
}
private static boolean isKeepAlive(byte[] header) {
for(int i = 0; i < header.length; ++i) {
if((header[i] & 0xff) != 0) {
return false;
}
}
return true;
}
public static int processHeader(byte[] header) {
int length = 0;
if(isKeepAlive(header)) {
Log.v(TAG, "Keepalive Recieved");
return length;
}
try {
ByteBuffer bb = ByteBuffer.wrap(header);
bb.order(ByteOrder.BIG_ENDIAN); // CocosBuilder transmits in Little Endian
length = bb.getInt();
} catch (Exception e) {
Log.i(TAG, "Exception: "+e.toString());
e.printStackTrace();
}
Log.i(TAG, "Payload Length: "+length);
return length;
}
public static String getDeviceInfo() {
try {
NSDictionary root = new NSDictionary();
root.put("cmd", "deviceinfo");
root.put("devicename", "TEST_ANDROID");
root.put("devicetype", "Android");
root.put("preferredresourcetype", "xlarge");
String payload = root.toXMLPropertyList();
// String data = new String(header, 0 , header.length);
return payload;
} catch(Exception e) {
}
return null;
}
}

View File

@ -0,0 +1,44 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
package org.cocos2dx.cocosplayer;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.os.Bundle;
import android.content.Intent;
public class CocosPlayer extends Cocos2dxActivity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
CocosPlayerSocket server = new CocosPlayerSocket();
server.setContext(getApplicationContext());
server.createServer();
}
static {
System.loadLibrary("cocosdragonjs");
}
}

View File

@ -0,0 +1,206 @@
package org.cocos2dx.cocosplayer;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Semaphore;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.nsd.NsdManager;
import android.net.nsd.NsdManager.RegistrationListener;
import android.net.nsd.NsdManager.ResolveListener;
import android.net.nsd.NsdServiceInfo;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class CocosPlayerPresence extends Service {
private static boolean conn = false;
private static boolean running = false;
protected static String SERVICE_TYPE_AUTO = "_CocosPlayer._tcp.";
protected static String SERVICE_TYPE = "_CocosP-35._tcp.";
protected static String SERVICE_TYPE_PART1 = "_CocosP-";
protected static String SERVICE_TYPE_PART2 = "._tcp.";
protected static final String TAG = "CocosPlayerSocket";
private RegistrationListener mRegistrationListener;
private NsdManager.DiscoveryListener mDiscoveryListener;
private ResolveListener mResolveListener;
protected String mServiceName;
private NsdManager mNsdManager;
protected NsdServiceInfo mService;
private List<Socket> mConnections;
private List<NsdServiceInfo> mServiceList;
private Context cw;
public void setContext(Context c) {
cw = c;
}
public void setPairing(int code) {
if(code == -1) {
SERVICE_TYPE = SERVICE_TYPE_AUTO;
} else {
SERVICE_TYPE = SERVICE_TYPE_PART1+Integer.toString(code)+SERVICE_TYPE_PART2;
}
}
public int startPresence(int port, int pairingCode) {
setPairing(pairingCode);
running = true;
mServiceList = new ArrayList<NsdServiceInfo>();
mConnections = new ArrayList<Socket>();
mNsdManager = (NsdManager) cw.getSystemService(Context.NSD_SERVICE);
// initializeDiscoveryListener();
initializeRegistrationListener();
initializeResolveListener();
// mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
// mDiscoveryListener);
registerService(port);
return 1;
}
@Override
public void onDestroy() {
running = false;
mNsdManager.unregisterService(mRegistrationListener);
//mNsdManager.stopServiceDiscovery(mDiscoveryListener);
super.onDestroy();
}
public void unregisterService() {
mNsdManager.unregisterService(mRegistrationListener);
}
private void registerService(int port) {
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setServiceName(Build.SERIAL + "TEST-TEST" + new Date().getTime());
serviceInfo.setServiceType(SERVICE_TYPE);
serviceInfo.setPort(port);
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD,
mRegistrationListener);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void initializeRegistrationListener() {
mRegistrationListener = new NsdManager.RegistrationListener() {
@Override
public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
Log.i(TAG, "Service Registered");
mServiceName = NsdServiceInfo.getServiceName();
}
@Override
public void onRegistrationFailed(NsdServiceInfo serviceInfo,
int errorCode) {
Log.i(TAG, "Service Registeration failed"+errorCode);
}
@Override
public void onServiceUnregistered(NsdServiceInfo arg0) {
}
@Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo,
int errorCode) {
}
};
}
public void initializeDiscoveryListener() {
mDiscoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started");
}
@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success");
Log.d(TAG, String.format("%s %s %s %d",
service.getServiceName(), service.getServiceType(),
service.getHost(), service.getPort()));
if (!service.getServiceType().contains(SERVICE_TYPE)) {
Log.d(TAG,
"Unknown Service Type: " + service.getServiceType());
} else if (service.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same machine: " + mServiceName);
} else {
mNsdManager.resolveService(service, mResolveListener);
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
Log.e(TAG, "service lost" + service);
}
@Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, serviceType + " Discovery stopped: " + serviceType);
}
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, serviceType + " Discovery failed: Error code:"
+ errorCode);
mNsdManager.stopServiceDiscovery(this);
}
@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, serviceType + " Discovery failed: Error code:"
+ errorCode);
mNsdManager.stopServiceDiscovery(this);
}
};
}
public void initializeResolveListener() {
mResolveListener = new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo,
int errorCode) {
Log.i(TAG, "Resolve failed" + errorCode);
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
Log.i(TAG, "Resolve Succeeded. " + serviceInfo);
if (serviceInfo.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same IP.");
return;
}
mService = serviceInfo;
mServiceList.add(mService);
}
};
}
}

View File

@ -0,0 +1,271 @@
package org.cocos2dx.cocosplayer;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.content.ContextWrapper;
import android.content.Context;
import android.os.Environment;
import android.os.AsyncTask;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import com.dd.plist.NSDictionary;
import com.dd.plist.NSData;
import com.dd.plist.UID;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class CocosPlayerSocket {
public static final String TAG = CocosPlayerSocket.class.getSimpleName();
private static boolean running = false;
private static Context cw = null;
private HashMap<Socket, String> mConnections;
private static ServerSocket server;
private static int mPairingCode = -1;
private static CocosPlayerPresence presence = null;
private void runCCB() {
Cocos2dxGLSurfaceView.getInstance().queueEvent(new Runnable() {
@Override
public void run() {
nativeRunCCB();
}
});
}
private void handleConnected() {
nativeConnected();
}
private void handleDisconnected() {
nativeDisconnected();
}
private void stopCCB() {
nativeStopCCB();
}
private void runScript(String script) {
nativeRunScript(script);
}
private static native void nativeRunCCB();
private static native void nativeConnected();
private static native void nativeDisconnected();
private static native void nativeStopCCB();
private static native void nativeRunScript(final String script);
private void switchCmd(NSDictionary data) {
try {
String cmd = data.objectForKey("cmd").toString();
String [] keys = data.allKeys();
for(int i =0 ; i < keys.length; ++i ) {
}
if(cmd.equalsIgnoreCase("zip")) {
CCBFileUtilsHelper.cleanCache(cw);
try {
Log.i(TAG, "Size of NSDATA payload: "+((NSData)data.objectForKey("data")).bytes().length);
CCBFileUtilsHelper.unzipCCB(((NSData)data.objectForKey("data")).bytes(), cw);
} catch(Exception e) {
Log.i(TAG, "Size of UID payload: "+((UID)data.objectForKey("data")).getBytes().length);
CCBFileUtilsHelper.unzipCCB(((UID)data.objectForKey("data")).getBytes(), cw);
}
} else if(cmd.equalsIgnoreCase("run")) {
runCCB();
} else if(cmd.equalsIgnoreCase("stop")) {
stopCCB();
} else if(cmd.equalsIgnoreCase("script")) {
runScript(data.objectForKey("script").toString());
}
} catch(Exception e) {
Log.i(TAG, "JSON Error: "+e.toString());
e.printStackTrace();
}
}
private void parsePayload(byte[] b) {
try {
NSDictionary rootDict = CCBStreamHandler.parseBinaryPLIST(b);
switchCmd(rootDict);
} catch(Exception e) {
Log.d(TAG, "Error writing payload to file");
}
}
private class StreamHandler extends AsyncTask<ServerSocket, ByteArrayOutputStream, Void> {
private void processPayload(final Socket client,final int length) {
try {
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int dataLength = ((length/4) > 16000) ? 16000 : (length/4);
byte[] data = new byte[dataLength];
int totalRead = 0, nRead;
while ((nRead = client.getInputStream().read(data, 0, ((length - totalRead) > data.length) ? data.length : (length - totalRead))) != -1 && totalRead < length) {
totalRead += nRead;
buffer.write(data, 0, nRead);
}
Log.i(TAG, "Parsing payload. Totaly bytes read: "+totalRead);
data = null;
publishProgress(buffer);
buffer.flush();
buffer.close();
} catch (Exception e) {
Log.i(TAG, "Exception: "+e.toString());
e.printStackTrace();
}
}
protected Void doInBackground(ServerSocket... args) {
try {
handleDisconnected();
ServerSocket server = args[0];
while(true) {
Socket client = server.accept();
Log.i(TAG,"New connection from "+ client.getInetAddress());
handleConnected();
if(client == null) {
Log.i(TAG, "Client null");
break;
}
try {
String data = CCBStreamHandler.getDeviceInfo();
ByteBuffer b = ByteBuffer.allocate(4);
b.order(ByteOrder.BIG_ENDIAN);
Log.i(TAG, "Payload Length: "+data.length());
b.putInt(data.length());
byte[] header = b.array();
Log.i(TAG, "Sending name "+data);
client.getOutputStream().write(header, 0 , header.length);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.write(data);
out.flush();
processStream(client);
} catch (Exception e) {
Log.i(TAG, "Server socket start fail!");
e.printStackTrace();
}
}
Log.i(TAG, "Server Closing");
server.close();
} catch(Exception e) {
}
return null;
}
private void processStream(Socket client) {
try {
int nRead, count = 0;
byte[] header = new byte[4];
while ((nRead = client.getInputStream().read(header, 0, header.length)) != -1) {
int lengthToRead = CCBStreamHandler.processHeader(header);
if(lengthToRead > 0) {
processPayload(client, lengthToRead);
}
}
} catch (Exception e) {
Log.i(TAG, "Exception: "+e.toString());
e.printStackTrace();
}
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute() {
try {
server.close();
} catch(Exception e) {
}
}
protected void onProgressUpdate(ByteArrayOutputStream... buffer) {
try {
byte[] b = buffer[0].toByteArray();
buffer[0].close();
System.gc();
parsePayload(b);
} catch(Exception e) {
}
}
}
public void setContext(Context c) {
cw = c;
}
public static void setPairingCode(int code) {
//mPresenceAsync.cancel(true);
if(presence != null) {
presence.unregisterService();
}
mPairingCode = code;
presence = new CocosPlayerPresence();
Log.i("CocosPlayerSocket", "Registering Bonjour on Port: "+server.getLocalPort()+" With pairing code: "+code);
presence.setContext(cw);
presence.startPresence(server.getLocalPort(), mPairingCode);
//new PresenceStarter().execute(server.getLocalPort(), mPairingCode);
}
public void createServer() {
Log.i(TAG, "Creating server "+running);
try {
server = new ServerSocket(0);
Log.i(TAG, "IP " + server.getInetAddress()
+ ", running on port " + server.getLocalPort());
presence = new CocosPlayerPresence();
presence.setContext(cw);
presence.startPresence(server.getLocalPort(), mPairingCode);
new StreamHandler().execute(server);
} catch(Exception e) {
}
}
}