登录
Unity3D
概述
接入向导
Apple 登录
Universal Link
检测 Universal Link
授权登录
游客登录
扫码登录
微信视频号授权
第三方平台拉起登录
异账号处理
获取票据
实名制
退出登录
常见问题
Android
概述
接入向导
授权登录
扫码登录
微信视频号授权
第三方平台拉起登录
异账号处理
获取票据
实名制
退出登录
常见问题
IOS
概述
接入向导
Apple 登录
Universal Link
检测 Universal Link
授权登录
游客登录
扫码登录
微信视频号授权
第三方平台拉起登录
异账号处理
获取票据
实名制
退出登录
常见问题
其他
数据结构
系统工具
登录 / Android / 概述

概述

MSDK登录功能是游戏玩家登录游戏的最快捷方便的方式:玩家可以使用QQ账号,微信账号,游客账号(ios提供游客模式;安卓不提供游客模式,如需要游客模式则需要游戏自己处理)登录您的游戏,可用于Android的手机,平板设备。

显示详情

接入向导

1 前置条件

1) 您已经在腾讯开放平台上注册游戏并通过审核,或您的腾讯接口人已经通过内部渠道帮您注册游戏。

2) 您已经按接入配置模块说明完成 接入配置

3) 确认您的游戏登录权限已开通。完成游戏注册后此权限已经默认开通,如果您调用登录接口返回"-303, no permission",请联系MSDK联调支持的同学。

2 参考Demo示例

手Q登录示例参考 MSDKDemo/src/com/example/wegame/MainActivity.java 的登录部分。

微信登录示例参考 MSDKDemo/src/com/example/wegame/MainActivity.java 的登录部分。

3 调用此模块其他接口

完成前面Step1-Step2步骤后,即已完全接入此模块,可直接调用此模块的其他接口不需要额外的配置。此模块各部分说明如下。

1)授权登录:拉起手Q/微信客户端授权(未安装手Q客户端时,会提示用户下载qq客户端,手Q后台自动处理)。

2)扫码登录:在用户设备未安装微信的情况下游戏可通过扫码登录让用户其他设备上已登录微信客户端的账号通过扫码进行授权。

3)异账号处理:手Q/微信平台要求处理不同账号登录的异账号场景。

4)获取票据:在游戏需要票据(如支付)的地方调用此接口可获取当前用户的票据信息。

5)退出登录:用户需要注销或切换账号时可调用此接口清除登录用户的票据信息。

授权登录

1 概要说明

拉起手Q/微信客户端授权(未安装手Q客户端时,会提示用户下载qq客户端,手Q后台自动处理),在用户授权以后通过 WGPlatformObserver通知游戏获取到LoginRet登录信息。

2 注册回调

1)功能描述

为接收MSDK的登录回调,您需要注册回调函数进行处理。登录结果会通过回调函数通知给您。

2)接口声明
void WGSetObserver(WGPlatformObserver *pObserver);
3)参数说明
参数名称 类型 说明
observer WGPlatformObserver类 MSDK回调类,参考示例代码
4)返回值

5)示例代码
class GlobalCallback : public WGPlatformObserver
{
   public:
    virtual void OnLoginNotify(LoginRet &loginRet)
    {
        LOGD("OnLoginNotify: flag:%d platform:%d OpenId:%s, Token Size: %d", loginRet.flag, loginRet.platform,
            loginRet.open_id.c_str(), loginRet.token.size());
        //下面是MSDKSample使用的逻辑, 游戏忽略此部分内容
        if(gActivity == NULL){
            LOGD("OnLoginNotify:Activity is null %d", loginRet.flag);
            return;
        }
        jclass activitycls = mEnv->GetObjectClass(gActivity);
        jmethodID method = mEnv->GetMethodID(activitycls, "stopWaiting", "()V");
        mEnv->CallVoidMethod(gActivity, method);
        if (loginRet.flag == eFlag_NeedRealNameAuth)
        {  // 需要实名认证
            LOGD("OnLoginNotify:Need_Realname_Auth %d", loginRet.flag);

            //TODO 游戏如果配置MSDK_REAL_NAME_AUTH_SWITCH=0或者1在这里取消对msdk的超时处理

            //TODO 游戏如果配置MSDK_REAL_NAME_AUTH_SWITCH=2在这里调用自定义的实名认证界面

            //这里模拟用户在游戏自定义界面填好信息准备提交注册

            jmethodID method = mEnv->GetMethodID(activitycls, "isCustomUI", "()Z");
            bool isCustom = mEnv->CallBooleanMethod(gActivity, method);
            if (isCustom)
            {
                RealNameAuthInfo authinfo;
                authinfo.name = "zhangsan";
                authinfo.identityType = eIDType_IDCards;
                authinfo.identityNum = "430455198411262142";
                authinfo.province = 11;
                WGPlatform::GetInstance()->WGRealNameAuth(authinfo);
            }

            return;
        }
        if (loginRet.platform == ePlatform_QQ)
        {
            // 读取QQ的登录票据
            switch (loginRet.flag)
            {
                case eFlag_Succ:
                {
                    std::string accessToken = "";
                    std::string payToken = "";
                    for (int i = 0; i < loginRet.token.size(); i++)
                    {
                        if (loginRet.token.at(i).type == eToken_QQ_Access)
                        {
                            accessToken.assign(loginRet.token.at(i).value);
                        }
                        else if (loginRet.token.at(i).type == eToken_QQ_Pay)
                        {
                            payToken.assign(loginRet.token.at(i).value);
                        }
                    }
                    LOGD("accessToken : %s", accessToken.c_str());
                    LOGD("payToken : %s", payToken.c_str());

                    // 下面是MSDKSample使用的逻辑, 游戏忽略此部分内容
                    jmethodID method = mEnv->GetMethodID(activitycls, "letUserLogin", "()V");
                    mEnv->CallVoidMethod(gActivity, method);
                    LOGD("OnLoginNotify call letUserLogin end%s", "");
                    break;
                }
                case eFlag_NotInWhiteList:
                case eFlag_NeedRealNameAuth:
                case eFlag_QQ_NotInstall:
                case eFlag_QQ_NotSupportApi:
                case eFlag_QQ_UserCancel:
                case eFlag_QQ_NoAcessToken:
                case eFlag_QQ_LoginFail:
                case eFlag_QQ_NetworkErr:
                default:
                {
                    std::stringstream ss;
                    ss << "OnLoginNotify";
                    ss << "flag:" << loginRet.flag << " platform:" << loginRet.platform << " desc:" << loginRet.desc;
                    jstring j_result = mEnv->NewStringUTF(ss.str().c_str());
                    // 显示登录界面
                    jmethodID method2 = mEnv->GetMethodID(activitycls, "letUserLogout", "(Ljava/lang/String;)V");
                    mEnv->CallVoidMethod(gActivity, method2,j_result);

                }
            }
        }
        else if (loginRet.platform == ePlatform_Weixin)
        {
            switch (loginRet.flag)
            {
                case eFlag_Succ:
                {
                    std::string accessToken = "";
                    std::string refreshToken = "";
                    for (int i = 0; i < loginRet.token.size(); i++)
                    {
                        if (loginRet.token.at(i).type == eToken_WX_Access)
                        {
                            accessToken.assign(loginRet.token.at(i).value);
                        }
                        else if (loginRet.token.at(i).type == eToken_WX_Refresh)
                        {
                            refreshToken.assign(loginRet.token.at(i).value);
                        }
                    }
                    LOGD("accessToken : %s", accessToken.c_str());
                    LOGD("payToken : %s", refreshToken.c_str());

                    // 下面是MSDKSample使用的逻辑, 游戏忽略此部分内容
                    jmethodID method = mEnv->GetMethodID(activitycls, "letUserLogin", "()V");
                    mEnv->CallVoidMethod(gActivity, method);
                    LOGD("OnLoginNotify call letUserLogin end%s", "");

                    break;
                }
                case eFlag_WX_RefreshTokenSucc:
                {
                    // WGRefreshWXToken调用成功, 成功用当前的refreshToken换到新的accessToken
                    std::string accessToken = "";
                    std::string refreshToken = "";
                    for (int i = 0; i < loginRet.token.size(); i++)
                    {
                        if (loginRet.token.at(i).type == eToken_WX_Access)
                        {
                            accessToken.assign(loginRet.token.at(i).value);
                        }
                        else if (loginRet.token.at(i).type == eToken_WX_Refresh)
                        {
                            refreshToken.assign(loginRet.token.at(i).value);
                        }
                    }
                    LOGD("accessToken : %s", accessToken.c_str());
                    LOGD("payToken : %s", refreshToken.c_str());

                    // 下面是MSDKSample使用的逻辑, 游戏忽略此部分内容
                    jmethodID method = mEnv->GetMethodID(activitycls, "letUserLogin", "()V");
                    mEnv->CallVoidMethod(gActivity, method);
                    mEnv->DeleteLocalRef(activitycls);
                    LOGD("OnLoginNotify call letUserLogin end%s", "");
                    break;
                }
                case eFlag_NotInWhiteList:
                case eFlag_NeedRealNameAuth:
                case eFlag_WX_NotSupportApi:
                case eFlag_WX_UserCancel:
                case eFlag_WX_UserDeny:
                case eFlag_WX_AccessTokenExpired:
                case eFlag_WX_RefreshTokenExpired:
                case eFlag_WX_LoginFail:
                case eFlag_Error:
                case eFlag_WX_RefreshTokenFail:
                default:
                {
                    std::stringstream ss;
                    ss << "OnLoginNotify";
                    ss << "flag:" << loginRet.flag << " platform:" << loginRet.platform << " desc:" << loginRet.desc;
                    jstring j_result = mEnv->NewStringUTF(ss.str().c_str());
                    // 显示登录界面
                    jmethodID method2 = mEnv->GetMethodID(activitycls, "letUserLogout", "(Ljava/lang/String;)V");
                    mEnv->CallVoidMethod(gActivity, method2,j_result);
                    /*std::stringstream ss;
                    ss << "OnShareNotify";
                    ss << "flag:" << loginRet.flag << " platform:" << loginRet.platform << " desc:" << loginRet.desc;
                    displayResult(ss.str());*/
                }
            }
        }
        else
        {
            // 显示登录界面
            jmethodID method2 = mEnv->GetMethodID(activitycls, "letUserLogout", "()V");
            mEnv->CallVoidMethod(gActivity, method2);
        }
        // 下面是MSDKSample使用的逻辑, 游戏忽略此部分内容
        jmethodID methodResetLoginOpt = mEnv->GetMethodID(activitycls, "resetLoginOpt", "()V");
        mEnv->CallVoidMethod(gActivity, methodResetLoginOpt);
        mEnv->DeleteLocalRef(activitycls);
    } 

    virtual ~GlobalCallback()
    {
    }
};
6)特殊说明

V3.3.21 版本 开始新增授权登录回调中微信授权scope字段透传能力,如下:

授权登录回调OnLoginNotify中,新增微信授权scope字段透传,业务侧可根据该字段判断用户是否有授权关系链权限;scope字段在LoginRetextra_json中,示例如下:

    用户授权关系链权限的scope样式:
    loginRet.extra_json = "{\"scope\":\"snsapi_userinfo,snsapi_friend,snsapi_message\"}";

    用户未授权关系链权限的scope样式:
    loginRet.extra_json = "{\"scope\":\"snsapi_userinfo,snsapi_message\"}";

注意事项:

1.授权登录scope透传仅限微信平台,QQ平台不支持

2.授权登录时默认个人信息与好友关系链在同一页面授权。如需好友关系链单独授权页面:

  • 微信平台需向微信(企业微信wxgame)平台侧申请开通
  • QQ平台当前不再支持该特性配置,请关注后续版本更新
7)名称解释
名称 描述 支持平台 调用接口
授权登录 游戏通过拉起平台的授权界面,引导用户授权游戏获得登录所需票据 手Q/微信 WGLogin
快速登录 玩家的操作使平台拉起游戏时会透传登录相关的票据信息从而登录进入游戏。 手Q
自动登录 登录时不指定平台参数,不会拉起手Q或者微信,只使用本地有效票据进行授权。 手Q/微信 WGLogin(EPlatform.ePlatform_None)
自动刷新 MSDK会自动处理微信票据刷新 MSDK 提供功能
异账号 当前游戏内登录的账号和平台登录的账号不一致 MSDK 提供功能 WGSwitchUser

ePlatform定义说明

LoginRet定义说明

QQ大厅登录 : QQ大厅登录是早期棋牌类游戏通过QQ游戏大厅拉起传递票据进行登录的方式,不接入QQ游戏大厅的游戏可以不关注

推荐登录流程

3 调用登录

1)功能描述

您可以通过调用WGLogin 接口进行指定平台拉起授权登录 或者 进行自动登录,调用结果会通过回调函数通知给您,函数声明及调用示例代码如下:

2)接口声明
void WGLogin(ePlatform platform = ePlatform_None);
3)参数说明
参数名称 类型 说明
platform int 游戏需要授权登录的平台类型
4)返回值

无,登录信息通过 WGPlatformObserver 回调返回给游戏

5)示例代码
WGPlatform::GetInstance()->WGLogin((ePlatform)Platform);
6)特殊说明

MSDK 3.3.22版本开始支持微信视频号授权,调用WGLogin接口,传入 ePlatform.ePlatform_WeixinVideoLive,在MSDK的回调中获取tdiAuthBuffer,用于后续的直播登录。

视频号授权注意事项:

  • 视频号直播授权当前仅支持微信渠道
  • 登录回调中tdiAuthBuffer存在于_extra_json字段中,以Base64的格式返回,通过Json解析获取,请使用标准的Base64解码后使用
  • MSDK仅做tdiAuthBuffer内容的返回,具体使用方法联系MSDK助手对接
7)名称解释

4 调用登录(3.0.8及以上版本使用)

1)功能描述

具有防重复点击,防超时功能,您可以通过调用WGLoginOpt 接口进行指定平台拉起授权登录 或者 进行自动登录,调用成功返回eFlag_Succ,如果正在登录中返回eFlag_Logining,登录结果会通过回调函数通知给您,函数声明及调用示例代码如下:

2)接口声明
eFlag WGLoginOpt(ePlatform platform = ePlatform_None, int overtime = DEFAUTL_LOGIN_OVERTIME);
3)参数说明
参数名称 类型 说明
platform int 游戏需要授权登录的平台类型
overtime int 登录超时时间,超时从授权回来开始计算,单位秒
4)返回值

成功返回eFlag_Succ,如果正在登录中返回eFlag_Logining,登录信息通过 WGPlatformObserver 回调返回给游戏

5)示例代码
WGPlatform::GetInstance()->WGLoginOpt((ePlatform)Platform, 20);
6)特殊说明

7)名称解释

扫码登录

1)功能描述

支持拉起登录二维码显示界面,玩家可以通过另外一个已经登录微信/QQ 对应社交账号的手机扫描二维码,根据提示授权后,游戏即可获得登录票据信息,一般用于电视或平板环境,或者手机未安装平台客户端的情况。无论机器上是否有安装微信/QQ APP,均可拉起二维码进行扫码授权登录。

备注:3.3.16 版本开始支持QQ 扫码登录。

2)接口声明
void WGQrCodeLogin(ePlatform platform);
3)参数说明
参数名称 类型 说明
platform int 游戏需要授权登录的平台类型
4)返回值

无,登录信息通过 WGPlatformObserver 回调返回给游戏

5)示例代码
WGPlatform::GetInstance()->WGQrCodeLogin((ePlatform)Platform);
6)特殊说明

关于微信扫码登录权限:非精品的游戏统一由游戏邮件向微信申请,精品的游戏由协同统一接入处理。

拉取到的二维码图片有效期5分钟,过期扫码无法登录成功。

7)名称解释

微信视频号授权(跨平台)

1)功能描述

MSDK 封装视频号授权接口,通过调用 WGChannelPermissionAuth 接口,当前微信要求传入 snsapi_channels_livestream,在 MSDK 的回调中获取 tdiAuthBuffer,用于后续的直播登录。3.3.26 版本开始新增该接口。

2)示例代码

请使用 WGChannelPermissionAuth 接口,参数设置为 ePlatform.ePlatform_WeixinVideoLive、snsapi_channels_livestream,在视频号授权的接口 ChannelPermissionAuthEvent 接收回调。调用示例:


// ePlatform_WeixinVideoLive,表示微信视频号渠道
// snsapi_channels_livestream,同时也是一个特殊标记权限

WGPlatform.Instance.WGChannelPermissionAuth(ePlatform.ePlatform_WeixinVideoLive, "snsapi_channels_livestream");

回调示例:


MsdkEvent.Instance.ChannelPermissionAuthEvent += (LoginRet ret) =>
{
    Debug.Log(ret.ToString());
    message = ret.ToString();
    switch (ret.flag)
    {
        case eFlag.eFlag_Succ:
            // 视频号授权成功
            Debug.Log("视频号授权成功!");
            break;
        case eFlag.eFlag_WX_UserCancel:
            Debug.Log("视频号授权-用户取消!");
            break;
        case eFlag.eFlag_WX_UserDeny:
            Debug.Log("视频号授权-用户拒绝!");
            break;
        default:
            // 视频号授权失败
            Debug.Log("视频号授权失败!");
            break;
    }
};

返回结果:


{
	"_flag": 0,
	"_desc": "",
	"_platform": 8,
	"_open_id": "",
	"_user_id": "",
	"_pf": "",
	"_pf_key": "",
	"_token": [],
	"_prajna_ext": "",
	"_extra_json": "{\"tdiAuthBase64\":\"Cp4BMV9CZ0FBYTRpb3RxYVA3aUgwQ1AzejkzRlZWY0Y4OG55NmZPZlZtaXh3ZUZNVHMwYVdJK0FF\\nVFpQR1c1SnpKbDdySWpnSnV6MEJRL2EyUXlQQlJWMG0xejNlTzRTR25ZN1VvSmt4N01idmxyemVp\\nOGNRU21lSnkxZGt6M0JubTFsNkgxZGJIMWVYRWNMMDdJa3dlYzJQMVZCUmhnPT0SF2lsaW5rYXBw\\nXzA2MDAwMDNiNzhjMTc2\\n\"}"
}
3)注意事项
  • 视频号授权当前仅支持微信视频号
  • 当前传入 snsapi_channels_livestream,后续微信可能会变动
  • 登录回调中 tdiAuthBuffer 存在于 _extra_json 字段中,以 Base64 的格式返回,通过 Json 解析获取,请使用标准的 Base64 解码后使用
  • 该功能不限制登录渠道及登录态,即可以跨平台调用该接口
  • MSDK 仅做 tdiAuthBuffer 内容的返回,具体使用方法联系MSDK助手对接

第三方平台拉起登录

MSDK 3.3.21及以上版本需关注

为对抗租号平台,从MSDK 3.3.21版本开始屏蔽QQ游戏中心启动游戏时的快速登录能力,游戏未登录状态下从QQ游戏中心启动将无法直接登录成功进入游戏;游戏中心启动异账号场景相关操作指引(游戏评估处理):

1) 游戏未登录:保持在登录页或调用QQ登录拉起QQ授权
2) 游戏已登录:
    2.1) 无异账号:等待MSDK登录回调,登录成功则可进游戏
    2.2) 有异账号:
        2.2.1) 用户选择本地账号:等待MSDK登录回调,登录成功则可进游戏
        2.2.2) 用户选择拉起账号:退回登录页或调用QQ登录拉起QQ授权页

注意事项:

更新到3.3.21版本的业务需联系QQ游戏中心侧,取消业务在QQ游戏中心启动时scheme携带的accesstoken、paytoken字段,避免已登录用户游戏内登录态受影响。

1)功能描述

是指当玩家在手Q或者微信内点击分享消息直接拉起并进入游戏时,平台会透传登录相关的票据信息从而直接完成登录进入游戏。这种场景下,游戏在被拉起以后无需用户再次授权才能进入游戏

手Q游戏中心快速登录配置

手Q通过游戏中心点击启动的时候可以直接快速登录游戏,但是通过游戏中心详情页进入的时候取决于游戏的配置,具体配制方法由游戏的运营协同规划PM提交需求给手Q游戏中心,由游戏中心的负责人完成配置。配置如下:

  • 支持openID:

    勾选openID一项,如下图

    1

  • 支持带openID、accessToken、PayToken

    1. 勾选对应的选项

    2. 填写游戏支持异账号的版本对应的versionCode。填写以后此code及以上的版本可以带票据拉起游戏,之前版本只会带openID拉起游戏,不会影响游戏的正常逻辑。

    2

  • 注意事项

    在配置的时候一般只需要配置前三项即可,后面几项不用配置。

2)接口声明

3)参数说明

4)返回值

无,登录信息通过 WGPlatformObserver 回调返回给游戏

5)示例代码

游戏需要在自己的主Activity的声明周期中配置如下代码

public void onCreate(Bundle savedInstanceState) {
      ... 
      WGPlatform.handleCallback(getIntent());
      ...
}
public void onNewIntent(Intent intent) {
      ... 
      WGPlatform.handleCallback(intent);
      ...
}

异账号处理

1 概括说明

用户从平台拉起进入游戏,因为账号不一致(平台不一致或者平台一致但账号不一致),需要游戏弹框提示异账号。异账号场景详细描述参考异账号说明文档

2 注册回调

为接收MSDK提供的游戏被拉起的回调,您需要注册 WGPlatformObserver 回调。

1)功能描述

平台拉起进入游戏携带的信息,会通过 WGPlatformObserver 传递给游戏。

2)接口声明
void WGSetObserver(WGPlatformObserver *pObserver)
3)参数说明
参数名称 类型 说明
observer WGPlatformObserver类 MSDK回调类,参考示例代码
4)返回值

5)示例代码
class GlobalCallback : public WGPlatformObserver
{
   public:
    virtual void OnWakeupNotify(WakeupRet &wakeupRet)
    {
        LOGD("OnWakeupNotify: platform:%d flag:%d openid:%s", wakeupRet.platform, wakeupRet.flag,
            wakeupRet.open_id.c_str());
        // TODO GAME 这里要处理异账号的逻辑
        switch (wakeupRet.flag)
        {
            case eFlag_Succ:
                if(wakeupRet.platform == eWakeupPlatform_TencentMsdk){
                    jstring j_msg_title = mEnv->NewStringUTF("由MSDK Scheme启动");
                    std::string c_extinfo;
                    for(int i =0;i<wakeupRet.extInfo.size();i++){
                        c_extinfo = c_extinfo + wakeupRet.extInfo[i].key + ":" + wakeupRet.extInfo[i].value + "\n";
                    }
                    jstring j_msg_msg = mEnv->NewStringUTF(c_extinfo.c_str());
                    jclass cls = mEnv->GetObjectClass(gActivity);
                    jmethodID methodShowTips = mEnv->GetMethodID(cls, "showTipsDialog", "(Ljava/lang/String;Ljava/lang/String;)V");
                    mEnv->CallVoidMethod(gActivity, methodShowTips, j_msg_title, j_msg_msg);
                    mEnv->DeleteLocalRef(j_msg_title);
                    mEnv->DeleteLocalRef(j_msg_msg);
                }
            case eFlag_UrlLogin:
            case eFlag_AccountRefresh:
            {
                // 下面是MSDKSample使用的逻辑, 游戏忽略此部分内容
                jclass cls = mEnv->GetObjectClass(gActivity);
                jmethodID methodletUserLogin = mEnv->GetMethodID(cls, "letUserLogin", "()V");
                mEnv->CallVoidMethod(gActivity, methodletUserLogin);
                LOGD("OnWakeupNotify call letUserLogin end%s", "");
                break;
            }
            case eFlag_NeedSelectAccount:
            {
                LOGD("diff account%s", "");
                jclass cls = mEnv->GetObjectClass(gActivity);
                jmethodID methodshowDiffLogin = mEnv->GetMethodID(cls, "showDiffLogin", "()V");
                mEnv->CallVoidMethod(gActivity, methodshowDiffLogin);
                LOGD("OnWakeupNotify call showDiffLogin end%s", "");
                break;
            }
            case eFlag_NeedLogin:
            {
                LOGD("login%s", "");
                jclass cls = mEnv->GetObjectClass(gActivity);
                jmethodID methodletUserLogout = mEnv->GetMethodID(cls, "letUserLogout", "()V");
                if(wakeupRet.platform == eWakeupPlatform_TencentMsdk){
                    jstring j_msg_title = mEnv->NewStringUTF("由MSDK Scheme启动");
                    std::string c_extinfo = "";
                    for(int i =0;i<wakeupRet.extInfo.size();i++){
                        c_extinfo = c_extinfo + wakeupRet.extInfo[i].key + ":" + wakeupRet.extInfo[i].value + "\n";
                    }
                    jstring j_msg_msg = mEnv->NewStringUTF(c_extinfo.c_str());
                    jclass cls = mEnv->GetObjectClass(gActivity);
                    jmethodID methodShowTips = mEnv->GetMethodID(cls, "showTipsDialog", "(Ljava/lang/String;Ljava/lang/String;)V");
                    mEnv->CallVoidMethod(gActivity, methodShowTips, j_msg_title, j_msg_msg);
                    mEnv->DeleteLocalRef(j_msg_title);
                    mEnv->DeleteLocalRef(j_msg_msg);
                }
                LOGD("OnWakeupNotify call letUserLogout end%s", "");
                break;
            }
            default:
            {
                // default 不处理
                LOGD("login%s", "");
                jclass cls = mEnv->GetObjectClass(gActivity);
                jmethodID methodletUserLogout = mEnv->GetMethodID(cls, "letUserLogout", "()V");
                mEnv->CallVoidMethod(gActivity, methodletUserLogout);
                LOGD("OnWakeupNotify call letUserLogout end%s", "");
                break;
            }
        }
    }

    virtual ~GlobalCallback()
    {
    }
};
6)特殊说明

收到 eFlag.eFlag_NeedSelectAccount 时即为触发异账号场景,此时游戏需要弹出提示框让用户选择需要登录的账号,并根据用户的选择调用WGSwitchUser接口,然后等待 WGPlatformObserver 回调获取切换账号的结果。

7)名称解释

EPlatform定义说明

WakeupRet定义说明

3 切换账号

1)功能描述

当异账号判断的wakeupRet.flag为eFlag_NeedSelectAccount时,游戏需要弹框提示用户,选择本地账号或者拉起账号登录游戏,游戏需要根据用户选择的结果调用接口WGSwitchUser完成用户登录。

2)接口声明
bool WGSwitchUser(bool flag);
3)参数说明
参数名称 类型 说明
flag bool true : 切换到外部账号; false : 继续使用原账号
4)返回值

true : 表明此账号有票据。MSDK会去验证此票据的有效性,并在 WGPlatformObserver 中返回验证结果。

false : 表明此账号无票据或票据不合法。可直接登录,让用户重新授权登录。

5)示例代码
bool flag = WGPlatform::GetInstance()->WGSwitchUser(true);
6)特殊说明

7)名称解释

获取票据

1 概括说明

您在登录回调中通过解析LoginRet中的 TokenRet可以获得登录的回调票据,除此之外,您还可以调用如下接口来获取当前的登录票据。LoginRet票据信息中包含玩家的openid,pf,pfkey,LoginRet中的TokenRet包含pay_token(QQ登录时特有),access_token(微信登录时特有)等信息。您在进行支付时将会用到这些信息。

微信票据自动刷新

  1. MSDK2.0.0版本开始, 会在游戏运行期间定时验证并刷新微信票据, 如果需要刷新,MSDK会自动刷新完成(时间间隔为30分钟), 并通过OnLoginNotify通知游戏, 3.0.0之前版本的flag为eFlag_WX_RefreshTokenSucc和eFlag_WX_RefreshTokenFail(已经包含在OnLoginNotify的回调中);3.0.0版本开始flag为eFlag_Succ(已经包含在OnLoginNotify的回调中)。
  2. 游戏接到新的票据以后需要同步更新游戏客户端保存的票据和服务器的票据, 以保证之后能使用新票据完成后续流程。
  3. 在MSDK2.7.0a以前,如果游戏不需要微信票据自动刷新功能,在assets\msdkconfig.ini中,将WXTOKEN_REFRESH设为false即可。此时游戏需要自行处理微信票据过期的逻辑。
  4. MSDK2.7.0a以后,在支持之前版本登录流程的基础上,优化新流程,对票据进行定时刷新,请务必将assets/msdkconfig.ini中WXTOKEN_REFRESH按如下设置WXTOKEN_REFRESH=true或者删除不填(即默认是开启的)。

微信票据刷新:

  • 微信accessToken只有24个小时的有效期,refreshToken的有效期为30天。只要refreshToken不过期就可以通过refreshToken刷新accessToken。刷新后会得到新的accessToken和refreshToken。如果游戏没有使用MSDK提供的票据自动刷新接口,需要使用WGRefreshWXToken()接口来进行accessToken续期。
  • 当游戏调用WGGetLoginRecord收到的flag为eFlag_WX_AccessTokenExpired时调用此接口刷新微信票据。刷新结果通过OnLoginNotify回调给游戏。eFlag_WX_RefreshTokenSucc 刷新token成功。eFlag_WX_RefreshTokenFail 刷新token失败。

2 注册回调

3 调用接口

1)功能描述

获得登录的回调票据

2)接口声明
int WGGetLoginRecord(LoginRet &ret)
3)参数说明
参数名称 类型 说明
ret LoginRet 票据信息 LoginRet
4)返回值

当前登录票据的平台id

5)示例代码
LoginRet lr;
int platform = WGPlatform::GetInstance()->WGGetLoginRecord(lr);
6)特殊说明

1、通过此接口获取到的票据以后需要判断LoginRet.flag,如果为0(eFlag_Succ),则票据正常有效可直接使用;如果为5001(eFlag_Checking_Token),这表明MSDK正在校验票据,此时获取到的票据无效。需要稍后重试。 您通过此接口获取到的票据以后必须传到游戏Server,通过游戏Server调用MSDK后端验证票据接口验证票据有效以后才能让用户进入游戏。

2、该接口会涉及到查询本地数据库,高频调用会对性能有损耗,所以不适合高频调用。例如unity游戏不要在update函数频繁调用

7)名称解释

LoginRet定义说明

实名制

按照文化部《网络游戏管理暂行办法》的相关要求,网络游戏用户需要使用有效身份证件进行实名注册才可登录游戏,为了减轻游戏开发的负担我们为游戏定制了实名认证的界面以及整套接口,通过该模块您可以花费几分钟的时间来完成实名认证的功能。

实名制详细描述参考实名制说明文档

退出登录

1 概括说明

您可以调用WGLogout接口来退出登录,清除本地票据

2 注册回调

3 调用接口

1)功能描述

获得登录的回调票据

2)接口声明
bool WGLogout();
3)参数说明

4)返回值

返回true,您无需处理返回值

5)示例代码
bool bOk = WGPlatform::GetInstance()->WGLogout();
6)特殊说明

7)名称解释

MSDK票据自动刷新流程

MSDK2.6.0i版本之后,在支持之前版本登录流程的基础上优化了新流程,业务只需关注WGLoginWGGetLoginRecord两个接口即可完成登录和票据处理。

  • 游戏自动登录的调用逻辑:

    游戏启动直接调用WGLogin()接口,等待OnLoginNotify()回调,流程如下:

  • 游戏需要登录票据时的调用逻辑:

    调用WGGetLoginRecord()接口,当返回值flag = 5001时表明MSDK内部正在校验票据有效性,可过几秒钟再次尝试调用获取,流程如下:

  • MSDK内部票据校验、刷新逻辑:

常见问题

游戏前后台切换用检查票据吗?

游戏在前后台切换时无需校验票据有效性。如果游戏中后台时间过长再切前台时,MSDK会自动校验票据有效性。

Android微信登录不了检查步骤

第一步: 检查Log中是否有

lauchWXPlatForm wx SendReqRet: true

有这一句表示已经成功发送请求到微信

如果微信客户端被不能被拉起来,请查看 第二步, 如果微信客户端被拉起了,但是没有回调,请查看 第三步

第二步: 检查签名和包名

下载https://res.wx.qq.com/open/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android2.apk, 将此apk安装到手机上, 在输入框中输入游戏的包名,点击按钮读取游戏包的签名。

检查签名

检查上述工具获取到的签名是否和微信后台配置的签名一致(微信后台配置的签名信息查询请RTX联系MSDK)

第三步: 检查WXEntryActivity.java放置的位置(此文件在MSDKSample中)

此文件一定要放在 游戏+.wxapi 下面,例如游戏的包名为:com.tencent.msdkgame, 则WXEntryActivity.java 应该放在com.tencent.msdkgame.wxapi下。同时查看WXEntryActivity里面的内容是否和下面的一致

/**
 * !!此文件的代码逻辑部分使用者不要修改,MSDK从1.7开始,父类名称由WXEntryActivity改为BaseWXEntryActivity,如果此文件出错请优先检查此项
 */
public class WXEntryActivity extends com.tencent.msdk.weixin.BaseWXEntryActivity { }

此步骤没问题请查看 第四步

第四步:检查handleCallback

游戏的Launch Activity的onCreate和onNewIntent里面是否调用了WGPlatform.handleCallback。

第五步:检查游戏的全局Observer是否设置

检查游戏有没有正确调用WGSetObserver(C++层和Java层)。

未装手Q时用web QQ登录返回游戏时Crash检查方法

如果游戏是用Unity直接打出Apk包,出现此问题,需要把MSDK的jar包中的assets中的内容解压放入Android/assets中。如果使用其他方式打包,需要注意打包脚本中适当处理MSDK的jar包中的so文件和资源文件,如果还有问题可尝试把MSDK的jar包中的assets中的内容解压放入游戏工程中的assets目录。