QQHallManager.cs
using BestHTTP.WebSocket; using LitJson; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.Networking; public class QQHallManager : MonoBehaviour { #region //单例和通用参数设置 protected int BUFFER_LRN = 1024; public const long AppId = /*由QQ大厅提供*/; public const string AppKey = /*由QQ大厅提供*/; protected string ZoneId = "2"; #region //大厅发送消息到游戏 //老板键 protected const string HALL_CMD_BOSS_KEY = "boss_key"; protected const string BOSS_KEY_SHOW = "show"; //前置显示 protected const string HALL_CMD_BRING_TO_TOP = "bring_to_top"; //页面关闭 protected const string HALL_CMD_WEB_CLOSE = "web_close"; //支付关闭 protected const string HALL_CMD_PAY_CLOSE = "pay_close"; //购买蓝钻页面关闭 protected const string HALL_CMD_BUY_VIP_CLOSE = "buy_vip_close"; #endregion //大厅发送消息到游戏 protected WebSocket _kWebSocket = null; protected CancellationToken _kCancellation = new CancellationToken(); protected static QQHallManager _kInstance = null; public static QQHallManager Instance { get { if (_kInstance == null) { _kInstance = GameObject.FindObjectOfType<QQHallManager>(); if (_kInstance == null) { _kInstance = new GameObject("QQHallManager").AddComponent<QQHallManager>(); } if (_kInstance != null) { GameObject.DontDestroyOnLoad(_kInstance.gameObject); } } return _kInstance; } } protected bool _kCanWork = false; protected string[] argsName = { "id", "key", "pfkey", "port" }; protected Dictionary<string, string> _kQQHallArgsDic = new Dictionary<string, string>(); /// <summary> /// QQ大厅传过来的Openid,用于游戏与后台连接,实现拉取玩家信息、支付等功能 /// </summary> protected string _kId = string.Empty; public string OpenId { get { return _kId; } } public string OpenKey { get { return _kKey; } } /// <summary> /// QQ大厅传过来的Openkey,用于游戏与后台连接,实现拉取玩家信息、支付等功能 /// </summary> protected string _kKey = string.Empty; /// <summary> /// QQ大厅传过来的pfkey,支付参数, /// </summary> protected string _kPfKey = string.Empty; /// <summary> /// QQ大厅传过来的port,用于游戏和大厅建立websocket连接 /// </summary> protected string _kPort = string.Empty; /// <summary> /// 自动解析命令行后,得到的WebSocket的URL /// </summary> protected string _kWebURL = string.Empty; protected string _kBUY_GOODS_URL = string.Empty; protected bool _kSandBox = false; public int SandBox { get { return _kSandBox ? 1 : 0; } } /// <summary> /// 初始化 /// </summary> /// <param name="actionCallback">bool参数表示初始化是否成功,主要是检查能否正常从命令行获取参数</param> public void Init(bool isTest,Action<bool> initCallback) { ParseCommondLine(); _kId = string.Empty; _kKey = string.Empty; _kPfKey = string.Empty; _kPort = string.Empty; _kBUY_GOODS_URL = string.Empty; if (!CheckOrGetArgs("id", out _kId) || !CheckOrGetArgs("key", out _kKey) || !CheckOrGetArgs("pfkey", out _kPfKey) || !CheckOrGetArgs("port", out _kPort) ) { _kCanWork = false; } else { _kCanWork = true; } _kWebURL = string.Format("ws://localhost:{0}/websocket/{1}", _kPort, _kId); if (isTest) { _kBUY_GOODS_URL = @"https://api-sandbox.urlshare.cn/v3/pay/buy_goods"; _kSandBox = true; } else { _kBUY_GOODS_URL = @"https://openapi.tencentyun.com/v3/pay/buy_goods"; _kSandBox = false; } QQHallDataReport.Instance.Init(); QQHallTextFilter.Instance.Init(); if (initCallback != null) { initCallback(_kCanWork); } } #region //解析获取命令行参数 protected void ParseCommondLine() { _kQQHallArgsDic.Clear(); var args = Environment.GetCommandLineArgs(); for (int i = 0; i < args.Length; i++) { var item = args[i]; if (string.IsNullOrEmpty(item)) { continue; } bool isFind = false; string tempKey = string.Empty; string tempValue = string.Empty; for (int j = 0; j < argsName.Length; j++) { var itemArgsName = argsName[j]; if (string.IsNullOrEmpty(itemArgsName)) { continue; } if (item.StartsWith(itemArgsName + "=") && item.Length > itemArgsName.Length + 1) { isFind = true; tempKey = itemArgsName; tempValue = item.Substring(itemArgsName.Length + 1); break; } } if (!isFind) { continue; } if (!_kQQHallArgsDic.ContainsKey(tempKey)) { _kQQHallArgsDic.Add(tempKey, tempValue); } else { _kQQHallArgsDic[tempKey] = tempValue; } } } protected bool CheckOrGetArgs(string key, out string value) { value = string.Empty; if (!_kQQHallArgsDic.ContainsKey(key)) { return false; } value = _kQQHallArgsDic[key]; return true; } #endregion //解析获取命令行参数 //处理接受到的QQ大厅的消息 protected void HandleQQHallReceivedCallback(string json) { var resultData = JsonMapper.ToObject<JsonData>(json); if (resultData == null) { return; } var cmd = string.Empty; try { cmd = resultData["cmd"].ToString(); } catch (Exception) { return; } switch (cmd) { case HALL_CMD_BOSS_KEY: HandleQQHallMsg_Callback_BOSS_KEY(resultData); break; case HALL_CMD_BRING_TO_TOP: HandleQQHallMsg_Callback_Bring2Top(resultData); break; case HALL_CMD_WEB_CLOSE: HandleQQHallMsg_Callback_WebClose(resultData); break; case HALL_CMD_PAY_CLOSE: HandleQQHallMsg_Callback_PayClose(resultData); break; case HALL_CMD_BUY_VIP_CLOSE: HandleQQHallMsg_Callback_BuyVipClose(resultData); break; } } #region //处理大厅发送过来的消息 //购买蓝钻页面关闭 protected void HandleQQHallMsg_Callback_BuyVipClose(JsonData data) { } //支付页页面关闭 protected void HandleQQHallMsg_Callback_PayClose(JsonData data) { } //Web页面关闭 protected void HandleQQHallMsg_Callback_WebClose(JsonData data) { } //前置显示 protected void HandleQQHallMsg_Callback_Bring2Top(JsonData data) { QQHallUltility.BringToTop(); } //老板键 protected void HandleQQHallMsg_Callback_BOSS_KEY(JsonData data) { var showStr = data["show"].ToString(); int showCmd = -1; if (!int.TryParse(showStr, out showCmd)) { return; } if (showCmd == 0) { //隐藏游戏窗口 QQHallUltility.HideWnd(); } else { //显示游戏窗口 QQHallUltility.ShowWnd(); } } #endregion //处理大厅发送过来的消息 //向米大师获取请求充值的参数 protected void RequestPayInfo(string serverID, string serverName, string gameUserLevel, string charid, string playerName, string price, string orderid, string productid, string productName, string productDescription, Action<JsonData> callback) { int amt = 0; amt = (int)Convert.ToDouble(price); amt = amt * 10;//Q点为单位 var goodsMeta = string.Format("{0}*{1}", productName, productDescription); ; var goodsURL = string.Empty; var payItem = string.Format("{0}_{1}*{2}*1", productid, orderid, amt); var pf = "qqgame"; var ts = QQHallUltility.GetTimestamps().ToString(); Dictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("amt", amt.ToString()); dic.Add("appid", AppId.ToString()); dic.Add("appmode", "1"); dic.Add("format", "json"); dic.Add("goodsmeta", goodsMeta); dic.Add("goodsurl", goodsURL); dic.Add("openid", _kId); dic.Add("openkey", _kKey); dic.Add("payitem", payItem); dic.Add("pf", pf); dic.Add("pfkey", _kPfKey); dic.Add("ts", ts); dic.Add("zoneid", ZoneId); //对dic的key进行字典排序 List<string> keyList = new List<string>(); foreach (var item in dic) { keyList.Add(item.Key); } keyList.Sort((x, y) => { return x.CompareTo(y); }); StringBuilder sbOri = new StringBuilder(); StringBuilder sbURLEncode = new StringBuilder(); for (int i = 0; i < keyList.Count; i++) { var tempKey = keyList[i]; if (i>0) { sbOri.Append('&'); sbURLEncode.Append('&'); } sbOri.Append(tempKey + "=" + dic[tempKey]); sbURLEncode.Append(tempKey + "=" + QQHallUltility.URLEncode(dic[tempKey])); } var sig = QQHallUltility.GenerateSig("/v3/pay/buy_goods", sbOri.ToString(), AppKey, QQHallUltility.GET); StringBuilder sb2 = new StringBuilder(); sb2.Append(_kBUY_GOODS_URL); sb2.Append('?'); sb2.Append(sbURLEncode.ToString()); sb2.Append("&sig="); sb2.Append(QQHallUltility.URLEncode(sig)); string url = sb2.ToString(); StartCoroutine(IE_SendGET(url, callback)); } protected IEnumerator IE_SendGET(string url, Action<JsonData> callback) { if (string.IsNullOrEmpty(url)) { yield break; } using (UnityWebRequest request = UnityWebRequest.Get(url)) { yield return request.SendWebRequest(); JsonData jsonData = null; if (request.isNetworkError || request.isHttpError) { Debug.LogError(request.error); } else { var json = request.downloadHandler.text; //Debug.Log("米大师返回结果:" + json); jsonData = JsonMapper.ToObject<JsonData>(json); } request.Abort(); request.disposeDownloadHandlerOnDispose = true; request.Dispose(); if (callback!=null) { callback(jsonData); } } } protected IEnumerator IE_ConnectQQHall() { if (!_kCanWork) { yield break; } _kWebSocket = new WebSocket(new Uri(_kWebURL)); _kWebSocket.OnOpen += OnWebSocketOpen; _kWebSocket.OnMessage += OnWebSocketMessageReceived; _kWebSocket.OnError += OnWebSocketError; _kWebSocket.OnClosed += OnWebSocketClosed; yield return 0; _kWebSocket.Open(); } private void OnWebSocketClosed(WebSocket webSocket, ushort code, string message) { Debug.Log("与QQ大厅连接断开:" + message); } private void OnWebSocketError(WebSocket webSocket, Exception ex) { Debug.Log("与QQ大厅之间连接的错误:" + ex.ToString()); } private void OnWebSocketMessageReceived(WebSocket webSocket, string message) { Debug.Log("接收到消息:" + message); HandleQQHallReceivedCallback(message); } private void OnWebSocketOpen(WebSocket webSocket) { Debug.Log("连接回调,状态:" + webSocket.State.ToString()); } #endregion //单例和通用参数设置 /// <summary> /// 连接QQ大厅 /// </summary> public void ConnectQQHall() { StartCoroutine(IE_ConnectQQHall()); } //支付 public void Pay(string serverID, string serverName, string gameUserLevel, string charid, string playerName, string price, string orderid, string productid, string productName, string productDescription) { RequestPayInfo(serverID, serverName, gameUserLevel, charid, playerName, price, orderid, productid, productName, productDescription, (response) => { if (response!=null) { StartPay(response); } }); } //显示开通蓝钻窗口 public void ShowOpenBlueDiamond() { //先判断是否是蓝钻,如果是蓝钻就不再去开通了。 JsonData jsonData = new JsonData(); jsonData["action"] = "openVip"; jsonData["appid"] = AppId; jsonData["openid"] = OpenId; jsonData["openkey"] = OpenKey; var json = JsonMapper.ToJson(jsonData); const string url = "https://qqgame.qq.com/midaspay/?param="; var openUrl = UT_Helper.BuildString2(url, json); Debug.Log("开通蓝钻地址:" + url); StartCoroutine(IE_SendGET(openUrl, (resultData) => { })); } protected void StartPay(JsonData responceData) { var goodstokenurl = string.Empty; try { goodstokenurl = responceData["url_params"].ToString(); } catch (Exception) { Debug.LogError("米大师返回的参数错误,没有url_params"); return; } JsonData paramData = new JsonData(); paramData["action"] = "buy"; paramData["appid"] = AppId; paramData["goodstokenurl"] = goodstokenurl; paramData["openid"] = _kId; paramData["openkey"] = _kKey; paramData["sandbox"] = _kSandBox ? "1" : "0"; var param = string.Empty; param = JsonMapper.ToJson(paramData); //生成的json不能有空格 param = param.Replace(" ", ""); param = QQHallUltility.URLEncode(param); StringBuilder sb = new StringBuilder(); sb.Append("{"cmd":"pay","param":""); sb.Append(param); sb.Append(""}"); var json = sb.ToString(); _kWebSocket.Send(json); } /// <summary> /// 退出游戏大厅 /// </summary> public void Exit() { QQHallDataReport.Instance.OnLogout(); QQHallDataReport.Instance.Exit(); try { var json = "{"cmd":"game_exit"}"; _kWebSocket.Send(json); Debug.Log("已通知大厅退出游戏"); } catch (Exception) { } } }
下一篇:没有了!