首页 文章 精选 留言 我的

精选列表

搜索[通用人工智能],共10006篇文章
优秀的个人博客,低调大师

通用智能体的应用和最佳实践

现如今,开发者普遍已能借助 Codex、Claude Code、Cursor 这类编程助手来写代码。但写代码只是第一步,业务侧的需求会不断加码——比如自动抓取券商研报并做对比,这类实践已有不少人尝试;而让客服系统真正理解客户意图,难度又上了一个台阶。更进一步,有人已经把从数据采集到报告生成的整条流水线做成了无人值守的自动化流程,基于目标驱动的业务也随之升级。

优秀的个人博客,低调大师

ASCSDK-------通用包接入文档(COCOS篇)

先说下大体的思路。和之前说的在Unity中接入ASCSDK一样,在Cocos2dx中接入ASCSDK,我们也分为两步,一个Android中的部分,另 一个是Coccos2dx中的部分。同时,我们希望尽可能地封装不同平台之间数据的传递,以及接口的调用。使得大部分游戏基于这个封装,都可以最快地速度来完成ASCSDK的接入。 新建一个Android工程,作为ASCSDK和Cocos2dx的一个中间工程(ASCSDK_Cocos2dx),主要负责ASCSDK的接口调用封装,参数传递和解析等。这个工程,对于所有游戏都试用。 在Cocos2dx中封装JNI调用,以及和Android中交互的数据格式等的定义和解析。同样地,这部分对于所有游戏也都适用。游戏中只需要调用这里提供的相关接口,以及实现相应的回调即可完成接入。 首先, 我们使用cocos new 新建一个Cocos2dx(我这里使用的是Cocos2dx 3.10版本)工程,名为Cocos_Demo。 目录如下图 demo中我们创建了5个按钮,分别为登陆,支付,评价,展示横幅,展示插屏。代码以及运行效果如下。 #include "HelloWorldScene.h" USING_NS_CC; Scene* HelloWorld::createScene() { // 'scene' is an autorelease object auto scene = Scene::create(); // 'layer' is an autorelease object auto layer = HelloWorld::create(); // add layer as a child to scene scene->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(); auto bg = Sprite::create("HelloWorld.jpg"); bg->setAnchorPoint(Vec2(0.5f, 0.5f)); bg->setPosition(Vec2(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2)); bg->setScale(2.0f); this->addChild(bg); ///////////////////////////// // 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 - 5.0f , origin.y + closeItem->getContentSize().height/2 + 5.0f)); // create menu, it's an autorelease object auto menu = Menu::create(closeItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1); ///////////////////////////// // 3. add your codes below... // add a label shows "Hello World" // create and initialize a label this->labelUsername = Label::createWithTTF("ASCSDK", "fonts/Marker Felt.ttf", 24); // position the label on the center of the screen this->labelUsername->setPosition(Vec2(origin.x + visibleSize.width / 2, origin.y + visibleSize.height * 0.9 - this->labelUsername->getContentSize().height)); // add the label as a child to this layer this->addChild(this->labelUsername, 1); ui::Button* btnLogin = ui::Button::create("login_normal.png", "login_selected.png"); btnLogin->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y + 200)); btnLogin->addClickEventListener(CC_CALLBACK_1(HelloWorld::loginClickCallback, this)); btnLogin->setScale(0.6f); // add the sprite as a child to this layer this->addChild(btnLogin, 0); ui::Button* btnPay = ui::Button::create("pay_normal.png", "pay_selected.png"); btnPay->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y + 100)); btnPay->addClickEventListener(CC_CALLBACK_1(HelloWorld::payClickCallback, this)); btnPay->setScale(0.6f); // add the sprite as a child to this layer this->addChild(btnPay, 0); ui::Button* btnRate = ui::Button::create("rate_normal.png", "rate_selected.png"); btnRate->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y)); btnRate->addClickEventListener(CC_CALLBACK_1(HelloWorld::rateClickCallback, this)); btnRate->setScale(0.6f); // add the sprite as a child to this layer this->addChild(btnRate, 0); ui::Button* btnBanner = ui::Button::create("banner_normal.png", "banner_selected.png"); btnBanner->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y - 100)); btnBanner->addClickEventListener(CC_CALLBACK_1(HelloWorld::showBannerClickCallback, this)); btnBanner->setScale(0.6f); // add the sprite as a child to this layer this->addChild(btnBanner, 0); ui::Button* btnInters = ui::Button::create("inters_normal.png", "inters_selected.png"); btnInters->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y - 200)); btnInters->addClickEventListener(CC_CALLBACK_1(HelloWorld::showIntersClickCallback, this)); btnInters->setScale(0.6f); // add the sprite as a child to this layer this->addChild(btnInters, 0); //NDKHelper::addSelector("ASCSelectors", "onASCLoginResult", CC_CALLBACK_2(HelloWorld::onASCLoginResult, this), this); ASCSDKInterface::getInstance()->initSDK(this); return true; } void HelloWorld::OnInitSuc() { CCLOG("SDK初始化成功..."); //一般不需要做什么处理 } void HelloWorld::OnLoginSuc(ASCLoginResult* result) { CCLOG("SDK登录并认证成功...%s",result->userId.c_str()); this->labelUsername->setString(result->sdkUsername); if (result->isSwitchAccount) { //TODO:这里退回到登录界面,并且SDK是已经登录成功状态,不用再弹出SDK的登录界面 } else { //TODO:登录认证成功,获取服务器列表,进入游戏服... } } void HelloWorld::OnSwitchLogin() { CCLOG("切换帐号成功..."); //TODO:退回到登录界面,并弹出SDK登录界面(调用ASCSDKInterface::getInstance()->login()) } void HelloWorld::OnLogout() { CCLOG("SDK帐号退出成功..."); this->labelUsername->setString("ASCSDK"); //TODO:退回到登录界面,并弹出SDK登录界面(调用ASCSDKInterface::getInstance()->login()) } void HelloWorld::loginClickCallback(Ref *pSender) { CCLOG("Btn Login Clicked...ASC Login..."); ASCSDKInterface::getInstance()->login(); } void HelloWorld::payClickCallback(Ref *pSender) { CCLOG("Btn Pay Clicked...ASC Pay..."); ASCPayParams* params = ASCPayParams::create(); params->productId = "1"; params->productName = "元宝"; params->productDesc = "购买100元宝,赠送20元宝"; params->price = 100; params->buyNum = 1; params->coinNum = 300; params->serverId = "10"; params->serverName = "地狱之恋"; params->roleId = "asc_24532452"; params->roleName = "麻利麻利吼"; params->roleLevel = 15; params->vip = "v15"; //去服务器获取游戏中商品的订单号以及扩展数据,这里测试 params->orderID = "345435634534"; params->extension = "test111"; ASCSDKInterface::getInstance()->pay(params); } void HelloWorld::rateClickCallback(cocos2d::Ref* pSender){ CCLOG("Btn rate Clicked...ASC Rate..."); ASCSDKInterface::getInstance()->rate(); } void HelloWorld::showBannerClickCallback(cocos2d::Ref* pSender){ CCLOG("Btn showBanner Clicked...ASC showBanner..."); ASCSDKInterface::getInstance()->showBanner(); } void HelloWorld::showIntersClickCallback(cocos2d::Ref* pSender){ CCLOG("Btn showInters Clicked...ASC showInters..."); ASCSDKInterface::getInstance()->showInters(); } void HelloWorld::menuCloseCallback(Ref* pSender) { Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif } 说明: HelloWorldScene.cpp中init方法的最后,我们调用ASCSDK的初始化方法:ASCSDKInterface::getInstance()->initSDK(this); 实现回调接口 void HelloWorld::OnInitSuc() { CCLOG("SDK初始化成功..."); //一般不需要做什么处理 } void HelloWorld::OnLoginSuc(ASCLoginResult* result) { CCLOG("SDK登录并认证成功...%s",result->userId.c_str()); this->labelUsername->setString(result->sdkUsername); if (result->isSwitchAccount) { //TODO:这里退回到登录界面,并且SDK是已经登录成功状态,不用再弹出SDK的登录界面 } else { //TODO:登录认证成功,获取服务器列表,进入游戏服... } } void HelloWorld::OnSwitchLogin() { CCLOG("切换帐号成功..."); //TODO:退回到登录界面,并弹出SDK登录界面(调用ASCSDKInterface::getInstance()->login()) } void HelloWorld::OnLogout() { CCLOG("SDK帐号退出成功..."); this->labelUsername->setString("ASCSDK"); //TODO:退回到登录界面,并弹出SDK登录界面(调用ASCSDKInterface::getInstance()->login()) } 登陆以及支付以及广告调用,回调方法,具体调用,请参考demo。 3.将Cocos_Demo生成proj.android导入到eclipse中,然后将ASCSDK3和ASCSDK_Cocos2dx工程生成的jar包(分别是ascsdk2.jar和ascsdk_cocos2dx.jar)拷贝到HelloCocos安卓工程的libs目录下以及一些外部jar。然后,将生成的 AppActivity.java,本来是继承Cocos2dxActivity的,改为继承ASCCocosActivity。同时,将AndroidManifest.xml中的application节点中,加上android:name=”com.ascsdk.ASCApplication” 目录如图 AndroidManifest.xml内容 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.asc.sdk.demo.cocos" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> <uses-sdk android:minSdkVersion="19"/> <uses-feature android:glEsVersion="0x00020000" /> <application android:label="@string/app_name" android:icon="@drawable/icon" android:name="com.asc.sdk.ASCApplication" > <!-- Tell Cocos2dxActivity the name of our .so --> <meta-data android:name="android.app.lib_name" android:value="cocos2dcpp"/> <activity android:name=".AppActivity" android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|keyboardHidden|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true"/> <uses-permission android:name="android.permission.INTERNET"/> </manifest> 最后,为了能够在Android中编译并运行,我们还需要将ASCSDK包含的这些Cpp文件,添加到Android.mk中,最终的文件如下: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) $(call import-add-path,$(LOCAL_PATH)/../../cocos2d) $(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external) $(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos) LOCAL_MODULE := cocos2dcpp_shared LOCAL_MODULE_FILENAME := libcocos2dcpp LOCAL_SRC_FILES := hellocpp/main.cpp \ ../../Classes/AppDelegate.cpp \ ../../Classes/HelloWorldScene.cpp \ ../../Classes/jansson/value.c \ ../../Classes/jansson/utf.c \ ../../Classes/jansson/strconv.c \ ../../Classes/jansson/strbuffer.c \ ../../Classes/jansson/pack_unpack.c \ ../../Classes/jansson/memory.c \ ../../Classes/jansson/load.c \ ../../Classes/jansson/hashtable.c \ ../../Classes/jansson/error.c \ ../../Classes/jansson/dump.c \ ../../Classes/NDKHelper/CallFuncNV.cpp \ ../../Classes/NDKHelper/NDKCallbackNode.cpp \ ../../Classes/NDKHelper/NDKHelper.cpp \ ../../Classes/ascsdk/ASCSDKData.cpp \ ../../Classes/ascsdk/ASCSDKNativeCallback.cpp \ ../../Classes/ascsdk/ASCSDKInterface.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes # _COCOS_HEADER_ANDROID_BEGIN # _COCOS_HEADER_ANDROID_END LOCAL_STATIC_LIBRARIES := cocos2dx_static # _COCOS_LIB_ANDROID_BEGIN # _COCOS_LIB_ANDROID_END include $(BUILD_SHARED_LIBRARY) $(call import-module,.) # _COCOS_LIB_IMPORT_ANDROID_BEGIN # _COCOS_LIB_IMPORT_ANDROID_END 4.到这里,接入就算完成了。我们可以使用cocos compile -p android 命令来编译Android平台,之前的操作如果稍有不慎,这里编译的过程中,也许会遇到一些错误,不过,看着啥错误,一一解决即可。

优秀的个人博客,低调大师

ASCSDK-------通用包接入文档(UNITY篇)

1. Untiy接入文档------Android端 Android端的作用是对接ASCSDK打包工具与unity原生端的中间件。 ASCUnityContext是主要的连接类,这个类继承UnityPlayerActivity ,也是游戏的启动Activity。 package com.asc.sdk; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; import com.asc.sdk.platform.ASCExitListener; import com.asc.sdk.platform.ASCInitListener; import com.asc.sdk.platform.ASCPlatform; import com.asc.sdk.plugin.ASCUser; import com.asc.sdk.verify.UToken; import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; /*** * 记得将游戏工程中的AndroidManifest.xml中application节点,增加一个android:name="ASCApplication" * 如果游戏有自己的Application。那么通过实现IApplicationListener接口来实现,而不要使用继承Application。 * 然后将自己的Application类,配置到AndroidManifest.xml中的meta-data节点中,name为"ASC_Game_Application" * @author xiaohei * */ public class ASCUnityContext extends UnityPlayerActivity{ public final static String CALLBACK_GAMEOBJECT_NAME = "(ascsdk_callback)"; //unity中接收回调通知的GameObject的名称 public final static String CALLBACK_INIT = "OnInitSuc"; //SDK初始化成功的回调方法名称和Unity中一致 public final static String CALLBACK_LOGIN = "OnLoginSuc"; //SDK登录成功的回调方法名称和Unity中一致 public final static String CALLBACK_SWITCH_LOGIN = "OnSwitchLogin"; //SDK切换帐号的回调方法名称和Unity中一致 public final static String CALLBACK_LOGOUT = "OnLogout"; //SDK登出的回调方法名称和Unity中一致 public final static String CALLBACK_PAY = "OnPaySuc"; //SDK支付成功回调方法名称和Unity中一致 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initSDK(); } private void initSDK(){ ASCPlatform.getInstance().init(this, new ASCInitListener() { @Override public void onSwitchAccount(UToken data) { //游戏中通过SDK切换到新账号的回调,游戏收到该回调,需要引导用户重新登录,重新加载该新用户对应的角色数据 if(data == null){ tip("切换帐号失败,请重试"); return; } sendLoginResult(data, true); } @Override public void onPayResult(int code, String msg) { Log.d("ASCSDK", "pay result. code:"+code+";msg:"+msg); /*switch(code){ case ASCCode.CODE_PAY_SUCCESS: //tip("支付成功"); break; case ASCCode.CODE_PAY_FAIL: //tip("支付失败"); break; case ASCCode.CODE_PAY_CANCEL: //tip("支付取消"); break; case ASCCode.CODE_PAY_UNKNOWN: //tip("支付失败,未知错误"); break; }*/ } @Override public void onLogout() { //用户登出回调(需要收到该回调需要返回游戏登录界面,并调用login接口,打开SDK登录界面) sendCallback(ASCUnityContext.CALLBACK_LOGOUT, null); } @Override public void onLoginResult(int code, UToken data) { switch(code){ case ASCCode.CODE_LOGIN_SUCCESS: sendLoginResult(data, false); tip("登录成功"); break; case ASCCode.CODE_LOGIN_FAIL: tip("登录失败"); break; } } @Override public void onInitResult(int code, String msg) { Log.d("ASCSDK", "init result.code:"+code+";msg:"+msg); switch(code){ case ASCCode.CODE_INIT_SUCCESS: sendCallback(CALLBACK_INIT, null); tip("初始化成功"); break; case ASCCode.CODE_INIT_FAIL: tip("初始化失败"); break; } } @Override public void onProductQueryResult(List<ProductQueryResult> result) { // TODO Auto-generated method stub } @Override public void onVideoResult(int code, String msg) { // TODO Auto-generated method stub Log.d("ASCSDK", "onVideoResult result:"+msg); Toast.makeText(ASCUnityContext.this, "视频回调成功", Toast.LENGTH_LONG).show(); } @Override public void onSinglePayResult(int code, ASCOrder order) { Log.d("ASCSDK", "onSinglePayResult result:"+order.getProductID()); JSONObject json = new JSONObject(); String pId = ""; pId = order.getProductID(); try{ if(code == ASCCode.CODE_PAY_SUCCESS){ json.put("payResult", 0); }else{ json.put("payResult", 1); } json.put("productId", pId); }catch(Exception e){ e.printStackTrace(); } sendCallback(ASCUnityContext.CALLBACK_PAY,json.toString()); } @Override public void onDestroy() { // TODO Auto-generated method stub } }); } public void sendLoginResult(UToken authResult, boolean isSwitchAccount) { JSONObject json = new JSONObject(); try{ json.put("isSuc", authResult.isSuc()); json.put("isSwitchAccount", isSwitchAccount); if(authResult.isSuc()){ json.put("userID", authResult.getUserID()); json.put("sdkUserID", authResult.getSdkUserID()); json.put("username", authResult.getUsername()); json.put("sdkUsername", authResult.getSdkUsername()); json.put("token", authResult.getToken()); } }catch(Exception e){ e.printStackTrace(); } this.sendCallback(ASCUnityContext.CALLBACK_LOGIN, json.toString()); } public void nativeLog(String msg){ Log.d("ASC_LOG_UNITY", msg); } //登录接口 public void login(){ ASCPlatform.getInstance().login(this); } //显示用户中心接口 public void showAccountCenter(){ ASCPlatform.getInstance().showAccountCenter(); } //登出 public void logout(){ ASCPlatform.getInstance().logout(); } //提交扩展数据 public void submitExtraData(String data){ final UserExtraData extraData = parseGameData(data); ASCPlatform.getInstance().submitExtraData(extraData); } //SDK退出接口 public void exit(){ ASCPlatform.getInstance().exitSDK(new ASCExitListener() { @Override public void onGameExit() { //游戏自己的退出确认框 AlertDialog.Builder builder = new AlertDialog.Builder(ASCUnityContext.this); builder.setTitle("退出确认"); builder.setMessage("现在还早,要不要再玩一会?"); builder.setCancelable(true); builder.setPositiveButton("好吧", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { //这里什么都不用做 } }); builder.setNeutralButton("一会再玩", new DialogInterface.OnClickListener() { @SuppressLint("NewApi") public void onClick(DialogInterface dialog, int whichButton) { //退出游戏 ASCUnityContext.this.finish(); System.exit(0); } }); builder.show(); } }); } //支付接口 public void pay(String data){ final PayParams params = parsePayParams(data); ASCPlatform.getInstance().pay(this, params); } //SDK是否支持用户中心 public boolean isSupportAccountCenter(){ return ASCUser.getInstance().isSupport("showAccountCenter"); } //SDK是否支持退出确认框 public boolean isSupportExit(){ return ASCUser.getInstance().isSupport("exit"); } //SDK是否支持退出确认框 public boolean isSupportLogout(){ return ASCUser.getInstance().isSupport("logout"); } public boolean isSDKShowSplash(){ return ASCSDK.getInstance().isSDKShowSplash(); } //向Unity中发送消息 public void sendCallback(String name, String jsonParams){ if(jsonParams == null){ jsonParams = ""; } UnityPlayer.UnitySendMessage(CALLBACK_GAMEOBJECT_NAME, name, jsonParams); } private UserExtraData parseGameData(String str){ UserExtraData data = new UserExtraData(); try { JSONObject json = new JSONObject(str); data.setDataType(json.getInt("dataType")); data.setRoleID(json.getString("roleID")); data.setRoleName(json.getString("roleName")); data.setRoleLevel(json.getString("roleLevel")); data.setServerID(json.getInt("serverID")); data.setServerName(json.getString("serverName")); data.setMoneyNum(json.getInt("moneyNum")); String roleCreateTime = json.getString("roleCreateTime"); String roleLevelUpTime = json.getString("roleLevelUpTime"); if(!TextUtils.isEmpty(roleCreateTime.trim())){ data.setRoleCreateTime(Long.valueOf(roleCreateTime.trim())); } if(!TextUtils.isEmpty(roleLevelUpTime.trim())){ data.setRoleLevelUpTime(Long.valueOf(roleLevelUpTime.trim())); } data.setVip(json.optString("vip", "0")); } catch (JSONException e) { e.printStackTrace(); } return data; } private PayParams parsePayParams(String str){ PayParams params = new PayParams(); try{ JSONObject json = new JSONObject(str); params.setProductId(json.getString("productId")); params.setProductName(json.getString("productName")); params.setProductDesc(json.getString("productDesc")); params.setPrice(json.getInt("price")); params.setRatio(0);//该字段废弃不用 params.setBuyNum(json.getInt("buyNum")); params.setCoinNum(json.getInt("coinNum")); params.setServerId(json.getString("serverId")); params.setServerName(json.getString("serverName")); params.setRoleId(json.getString("roleId")); params.setRoleName(json.getString("roleName")); params.setRoleLevel(json.getInt("roleLevel")); params.setPayNotifyUrl(json.getString("payNotifyUrl")); params.setVip(json.getString("vip")); params.setExtension(json.getString("extension")); }catch(Exception e){ e.printStackTrace(); } return params; } public void onActivityResult(int requestCode, int resultCode, Intent data){ ASCSDK.getInstance().onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data); } public void onStart(){ ASCSDK.getInstance().onStart(); super.onStart(); } public void onPause(){ ASCSDK.getInstance().onPause(); super.onPause(); } public void onResume(){ ASCSDK.getInstance().onResume(); super.onResume(); } public void onNewIntent(Intent newIntent){ ASCSDK.getInstance().onNewIntent(newIntent); super.onNewIntent(newIntent); } public void onStop(){ ASCSDK.getInstance().onStop(); super.onStop(); } public void onDestroy(){ ASCSDK.getInstance().onDestroy(); super.onDestroy(); } public void onRestart(){ ASCSDK.getInstance().onRestart(); super.onRestart(); } private void tip(final String tip){ ASCSDK.getInstance().runOnMainThread(new Runnable() { @Override public void run() { //Toast.makeText(ASCUnityContext.this, tip, Toast.LENGTH_SHORT).show(); } }); } private void OnRate(){ try { String str = "market://details?id=" + ASCSDK.getInstance().getApplication().getPackageName(); Log.d("ASCSDK", "OnRate url:"+str); Intent localIntent = new Intent(Intent.ACTION_VIEW); localIntent.setData(Uri.parse(str)); ASCSDK.getInstance().getContext().startActivity(localIntent); } catch (Exception e) { // 打开应用商店失败 可能是没有手机没有安装应用市场 e.printStackTrace(); Toast.makeText(ASCSDK.getInstance().getContext().getApplicationContext(), "打开应用商店失败", Toast.LENGTH_SHORT).show(); // 调用系统浏览器进入商城 String url = "http://app.mi.com/detail/163525?ref=search"; openLinkBySystem(url); } } private void openLinkBySystem(String url) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); ASCSDK.getInstance().getContext().startActivity(intent); } } 说明: 其中,CALLBACK_GAMEOBJECT_NAME就是Unity中这个负责接收回调通知的GameObject的名称 此类包含了初始化SDK,登陆,登出,退出,支付,提交扩展数据方法。 ASCInitListener此接口为所有回调的监听接口。 onPayResult------支付回调(网游专用接口)。 onLoginResult------登陆结果回调。 onInitResult------初始化结果回调。 onSinglePayResult------单机支付结果回调。 还有一些登出,查询订单,视频回调等,详情看代码注解。 2. Untiy接入文档------Unity端 拷贝上面Android端生成的ascsdk_unitylib.jar到unity工程libs目录中。 拷贝ASCSDK的抽象层工程中的bin目录下生成的ascsdk3.jar拷贝到libs目录中。 在Unity中怎么来完成Android中相关接口的调用以及封装。 我们定义一个ASCSDKInterface的抽象单例类: public abstract class ASCSDKInterface{ public delegate void LoginSucHandler(ASCLoginResult data); public delegate void LogoutHandler(); private static ASCSDKInterface _instance; public LoginSucHandler OnLoginSuc; public LogoutHandler OnLogout; public static ASCSDKInterface Instance { get { if (_instance == null) { #if UNITY_EDITOR || UNITY_STANDLONE _instance = new SDKInterfaceDefault(); #elif UNITY_ANDROID _instance = new SDKInterfaceAndroid(); #elif UNITY_IOS _instance = new SDKInterfaceIOS(); #endif } return _instance; } } //初始化 public abstract void Init(); //登录 public abstract void Login(); //自定义登录,用于腾讯应用宝,QQ登录,customData="QQ";微信登录,customData="WX" public abstract void LoginCustom(string customData); //切换帐号 public abstract void SwitchLogin(); //登出 public abstract bool Logout(); //显示个人中心 public abstract bool ShowAccountCenter(); //上传游戏数据 public abstract void SubmitGameData(ASCExtraGameData data); //调用SDK的退出确认框,返回false,说明SDK不支持退出确认框,游戏需要使用自己的退出确认框 public abstract bool SDKExit(); //调用SDK支付界面 public abstract void Pay(ASCPayParams data); //SDK是否支持退出确认框 public abstract bool IsSupportExit(); //SDK是否支持用户中心 public abstract bool IsSupportAccountCenter(); //SDK是否支持登出 public abstract bool IsSupportLogout(); //去ASCServer获取游戏订单号,这里逻辑是访问游戏服务器,然后游戏服务器去ASCServer获取订单号 //并返回 public ASCPayParams reqOrder(ASCPayParams data) { //TODO 去游戏服务器获取订单号 //测试 data.orderID = "345435634534"; data.extension = "test"; return data; } } 有了这个抽象类,对于各个平台,我们需要分别实现该抽象类中的接口,从而间接地调用平台中的方法。对于Android平台,我们定义一个SDKInterfaceAndroid类: public class SDKInterfaceAndroid : ASCSDKInterface { private AndroidJavaObject jo; public SDKInterfaceAndroid() { using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); } } private T SDKCall<T>(string method, params object[] param) { try { return jo.Call<T>(method, param); } catch (Exception e) { Debug.LogError(e); } return default(T); } private void SDKCall(string method, params object[] param) { try { jo.Call(method, param); } catch (Exception e) { Debug.LogError(e); } } //这里Android中,在onCreate中直接调用了initSDK,所以这里就不用调用了 public override void Init() { //SDKCall("initSDK"); } public override void Login() { SDKCall("login"); } public override void LoginCustom(string customData) { SDKCall("loginCustom", customData); } public override void SwitchLogin() { SDKCall("switchLogin"); } public override bool Logout() { if (!IsSupportLogout()) { return false; } SDKCall("logout"); return true; } public override bool ShowAccountCenter() { if (!IsSupportAccountCenter()) { return false; } SDKCall("showAccountCenter"); return true; } public override void SubmitGameData(ASCExtraGameData data) { string json = encodeGameData(data); SDKCall("submitExtraData", json); } public override bool SDKExit() { if (!IsSupportExit()) { //return false; } SDKCall("exit"); return true; } public override void Pay(ASCPayParams data) { string json = encodePayParams(data); SDKCall("pay", json); } public override bool IsSupportExit() { return SDKCall<bool>("isSupportExit"); } public override bool IsSupportAccountCenter() { return SDKCall<bool>("isSupportAccountCenter"); } public override bool IsSupportLogout() { return SDKCall<bool>("isSupportLogout"); } private string encodeGameData(ASCExtraGameData data) { Dictionary<string, object> map = new Dictionary<string, object>(); map.Add("dataType", data.dataType); map.Add("roleID", data.roleID); map.Add("roleName", data.roleName); map.Add("roleLevel", data.roleLevel); map.Add("serverID", data.serverID); map.Add("serverName", data.serverName); map.Add("moneyNum", data.moneyNum); return MiniJSON.Json.Serialize(map); } private string encodePayParams(ASCPayParams data) { Dictionary<string, object> map = new Dictionary<string, object>(); map.Add("productId", data.productId); map.Add("productName", data.productName); map.Add("productDesc", data.productDesc); map.Add("price", data.price); map.Add("buyNum", data.buyNum); map.Add("coinNum", data.coinNum); map.Add("serverId", data.serverId); map.Add("serverName", data.serverName); map.Add("roleId", data.roleId); map.Add("roleName", data.roleName); map.Add("roleLevel", data.roleLevel); map.Add("vip", data.vip); map.Add("orderID", data.orderID); map.Add("extension", data.extension); return MiniJSON.Json.Serialize(map); } } 接下来,我们就定义一个专门负责回调的脚本: public class ASCSDKCallback : MonoBehaviour { private static ASCSDKCallback _instance; private static object _lock = new object(); //初始化回调对象 public static ASCSDKCallback InitCallback() { UnityEngine.Debug.LogError("Callback->InitCallback"); lock (_lock) { if (_instance == null) { GameObject callback = GameObject.Find("(ascsdk_callback)"); if (callback == null) { callback = new GameObject("(ascsdk_callback)"); UnityEngine.Object.DontDestroyOnLoad(_instance); _instance = callback.AddComponent<ASCSDKCallback>(); } else { _instance = callback.GetComponent<ASCSDKCallback>(); } } return _instance; } } //初始化成功回调 public void OnInitSuc() { //一般不需要处理 UnityEngine.Debug.LogError("Callback->OnInitSuc"); } //登录成功回调 public void OnLoginSuc(string jsonData) { UnityEngine.Debug.LogError("Callback->OnLoginSuc"); ASCLoginResult data = parseLoginResult(jsonData); if (data == null) { UnityEngine.Debug.LogError("The data parse error." + jsonData); return; } if (ASCSDKInterface.Instance.OnLoginSuc != null) { ASCSDKInterface.Instance.OnLoginSuc.Invoke(data); } } //切换帐号回调 public void OnSwitchLogin() { UnityEngine.Debug.LogError("Callback->OnSwitchLogin"); if (ASCSDKInterface.Instance.OnLogout != null) { ASCSDKInterface.Instance.OnLogout.Invoke(); } } //登出回调 public void OnLogout() { UnityEngine.Debug.LogError("Callback->OnLogout"); if (ASCSDKInterface.Instance.OnLogout != null) { ASCSDKInterface.Instance.OnLogout.Invoke(); } } //支付回调,网游不需要实现该接口,该接口用于单机游戏 public void OnPaySuc(string jsonData) { //Nothing... } private ASCLoginResult parseLoginResult(string str) { object jsonParsed = MiniJSON.Json.Deserialize(str); if (jsonParsed != null) { Dictionary<string, object> jsonMap = jsonParsed as Dictionary<string, object>; ASCLoginResult data = new ASCLoginResult(); if (jsonMap.ContainsKey("isSuc")) { data.isSuc = bool.Parse(jsonMap["isSuc"].ToString()); } if (jsonMap.ContainsKey("isSwitchAccount")) { data.isSwitchAccount = bool.Parse(jsonMap["isSwitchAccount"].ToString()); } if (jsonMap.ContainsKey("userID")) { data.userID = jsonMap["userID"].ToString(); } if (jsonMap.ContainsKey("sdkUserID")) { data.sdkUserID = jsonMap["sdkUserID"].ToString(); } if (jsonMap.ContainsKey("username")) { data.username = jsonMap["username"].ToString(); } if (jsonMap.ContainsKey("sdkUsername")) { data.sdkUsername = jsonMap["sdkUsername"].ToString(); } if (jsonMap.ContainsKey("token")) { data.token = jsonMap["token"].ToString(); } return data; } return null; } } 到这里,ASCSDK在Unity中的封装基本就算完成了,接下来,我们就来测试下接口的调用。我们用UGUI建立一个建立一个简单的面板,然后包含一个登录按钮和支付按钮,然后通过绑定一个ClickObject.cs脚本来简体按钮的响应事件: public class ClickObject : MonoBehaviour { // Use this for initialization private Text txtState; void Start () { ASCSDKCallback.InitCallback(); GameObject loginObj = GameObject.Find("BtnLogin"); Button btnLogin = loginObj.GetComponent<Button>(); btnLogin.onClick.AddListener(delegate() { OnLoginClick(); }); GameObject payObj = GameObject.Find("BtnPay"); Button btnPay = payObj.GetComponent<Button>(); btnPay.onClick.AddListener(delegate() { OnPayClick(); }); GameObject stateObj = GameObject.Find("TxtState"); txtState = stateObj.GetComponent<Text>(); ASCSDKInterface.Instance.OnLoginSuc = delegate(ASCLoginResult result) { OnLoginSuc(result); }; ASCSDKInterface.Instance.OnLogout = delegate() { OnLogout(); }; } void Update() { if (Input.GetKeyUp(KeyCode.Escape)) { if (!ASCSDKInterface.Instance.SDKExit()) { //TODO 退出确认框 Application.Quit(); } } } void OnLoginSuc(ASCLoginResult result) { if (!result.isSuc) { txtState.text = "登录失败"; return; } if (result.isSwitchAccount) { txtState.text = "切换帐号成功:" + result.token; } else { txtState.text = "登录成功:" + result.token; } } void OnLogout() { txtState.text = "未登录"; } void OnLoginClick() { ASCSDKInterface.Instance.Login(); } void OnPayClick() { ASCPayParams data = new ASCPayParams(); data.productId = "1"; data.productName = "元宝"; data.productDesc = "购买100元宝,赠送20元宝"; data.price = 100; data.buyNum = 1; data.coinNum = 300; data.serverId = "10"; data.serverName = "地狱之恋"; data.roleId = "asc_24532452"; data.roleName = "麻利麻利吼"; data.roleLevel = 15; data.vip = "v15"; data = ASCSDKInterface.Instance.reqOrder(data); ASCSDKInterface.Instance.Pay(data); } } 最后说明:我们将提供unity的工程的demo,具体可以参考我们demo,此文档暂时没有提供广告接口的说明,原理与login支付一样,调用我给你们提供的方法就可以,具体以我们给的demo为准。有任何问题可以联系我们的商务人员。

优秀的个人博客,低调大师

大型网站性能优化的通用方法(转)

1、HTML静态化 其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。 除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来说,尽可能的静态化也是提高性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。 同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛中论坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这部分内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。 2、图片服务器分离 大家知道,对于Web服务器来说,不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃,在应用服务器和图片服务器上,可以进行不同的配置优化,比如apache在配置ContentType的时候可以尽量少支持,尽可能少的LoadModule,保证更高的系统消耗和执行效率。 3、数据库集群和库表散列 大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。 在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。 上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制,于是我们需要从应用程序的角度来考虑改善系统架构,库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架构,将论坛的用户、设置、帖子等信息进行数据库分离,然后对帖子、用户按照板块和ID进行散列数据库和表,最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。 4、缓存 缓存一词搞技术的都接触过,很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。 架构方面的缓存,对Apache比较熟悉的人都能知道Apache提供了自己的缓存模块,也可以使用外加的Squid模块进行缓存,这两种方式均可以有效的提高Apache的访问响应能力。 网站程序开发方面的缓存,Linux上提供的Memory Cache是常用的缓存接口,可以在web开发中使用,比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯共享,一些大型社区使用了这样的架构。另外,在使用web语言开发的时候,各种语言基本都有自己的缓存模块和方法,PHP有Pear的Cache模块,Java就更多了,.net不是很熟悉,相信也肯定有。 5、镜像 镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异,比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等工具。 6、负载均衡 负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。 负载均衡技术发展了多年,有很多专业的服务提供商和产品可以选择,我个人接触过一些解决方法,其中有两个架构可以给大家做参考。 硬件四层交换 第四层交换使用第三层和第四层信息包的报头信息,根据应用区间识别业务流,将整个区间段的业务流分配到合适的应用服务器进行处理。 第四层交换功能就象是虚IP,指向物理服务器。它传输的业务服从的协议多种多样,有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上,需要复杂的载量平衡算法。在IP世界,业务类型由终端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。 在硬件四层交换产品领域,有一些知名的产品可以选择,比如Alteon、F5等,这些产品很昂贵,但是物有所值,能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。 软件四层交换 大家知道了硬件四层交换机的原理后,基于OSI模型来实现的软件四层交换也就应运而生,这样的解决方案实现的原理一致,不过性能稍差。但是满足一定量的压力还是游刃有余的,有人说软件实现方式其实更灵活,处理能力完全看你配置的熟悉能力。 软件四层交换我们可以使用Linux上常用的LVS来解决,LVS就是Linux Virtual Server,他提供了基于心跳线heartbeat的实时灾难应对解决方案,提高系统的鲁棒性,同时可供了灵活的虚拟VIP配置和管理功能,可以同时满足多种应用需求,这对于分布式的系统来说必不可少。 一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建squid集群,这种思路在很多大型网站包括搜索引擎上被采用,这样的架构低成本、高性能还有很强的扩张性,随时往架构里面增减节点都非常容易。这样的架构我准备空了专门详细整理一下和大家探讨。 对于大型网站来说,前面提到的每个方法可能都会被同时使用到,我这里介绍得比较浅显,具体实现过程中很多细节还需要大家慢慢熟悉和体会,有时一个很小的squid参数或者apache参数设置,对于系统性能的影响就会很大,希望大家一起讨论,达到抛砖引玉之效。 本文转自灵动生活博客园博客,原文链接:http://www.cnblogs.com/ywqu/archive/2008/01/05/1027368.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册