using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using Module.Log; using UnityEngine; /// PC部分的SDK接口类 public abstract class SdkBase { public int defaultServer { get; protected set; } public string loadUri { get; private set; } // 防止反复发送LoadData的功能 private readonly HashSet _loadData = new HashSet(); protected abstract string noticeUri { get; } protected abstract string redemptionUri { get; } public abstract bool useGm { get; } public abstract string platformId { get; } public abstract string sdkAccount { get; } public virtual string tableVariant { get { return "tables"; } } public abstract void Dispose(); protected static bool IsSuccess(string args) { var result = args == "success"; // 注:失败必然有报错信息,因此不考虑 if (!result) { var i = args.IndexOf(','); if (i < 1) { LogModule.ErrorLog("Unable to parse Sdk Message:\n" + args); } else { result = "success" == args.Remove(i); if (!result) LogModule.ErrorLog("Unable to parse Sdk Message:\n" + args); } } return result; } #region Unity输入指令 public abstract void Logout(); public abstract void SwitchAccount(); public abstract void ShakeDevice(); public virtual void SubmitData(RoleDataSubmit submitType) { // 大部分不需要提交数据,所以不使用abstract处理 } public abstract void CloseGame(); public abstract bool IsLogin(); public abstract void GetServerList(); public void SubmitLoadData(LoadDataType action) { if (!string.IsNullOrEmpty(loadUri) && _loadData.Add(action)) { int level; if (GameManager.gameManager && GameManager.gameManager.PlayerDataPool != null && GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr != null) { level = GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.Level; } else level = default(int); if (level < 1) level = 1; var endPoint = NetWorkLogic.GetMe().GetLocalEndPoint() as IPEndPoint; var dateTime = DateTime.Now; var loadBuilder = new StringBuilder(); loadBuilder.Append(platformId); loadBuilder.Append('|'); loadBuilder.Append(SdkControl.instance.currentServerData.m_id); loadBuilder.Append('|'); loadBuilder.Append(sdkAccount); loadBuilder.Append('|'); loadBuilder.Append(level); loadBuilder.Append('|'); loadBuilder.Append((int)action); loadBuilder.Append('|'); loadBuilder.Append(GetType().IsSubclassOf(typeof(SdkIosBase)) ? 2 : 1); loadBuilder.Append('|'); loadBuilder.Append(endPoint == null ? "0.0.0.0" : endPoint.Address.ToString()); loadBuilder.Append('|'); loadBuilder.Append(string.Format("{0:yyyy-MM-dd HH:mm:ss}", dateTime)); var loadData = loadBuilder.ToString(); loadBuilder.Append("027a47eabf1ebcb409b7fe680ff69008"); var loadMd5 = loadBuilder.ToString(); loadMd5 = AssetUtils.GetTextMd5(loadMd5); Debug.Log("Load Data: " + loadData); var data = new Dictionary(); data["counter"] = "load"; data["data"] = loadData; data["sign"] = loadMd5; var jsonDownloader = new DownloadJsonFile(loadUri, 10f, data); jsonDownloader.Start(); } } protected static Dictionary GetRoleInfoDict(RoleDataSubmit submitType) { var playerData = GameManager.gameManager.PlayerDataPool; var mainPlayer = playerData.MainPlayerBaseAttr; var serverData = SdkControl.instance.currentServerData; var result = new Dictionary(); result["Event"] = submitType.ToString(); result["ServerId"] = serverData.m_id.ToString(); result["ServerName"] = serverData.m_name; result["RoleName"] = mainPlayer.RoleName; result["RoleId"] = mainPlayer.Guid.ToString(); result["Level"] = mainPlayer.Level.ToString(); var vip = playerData.VipCost; if (vip < 0) vip = 0; result["Vip"] = vip.ToString(); result["Balance"] = playerData.Money.GetMoney_YuanBao().ToString(); result["OnlineTime"] = Mathf.FloorToInt(Time.realtimeSinceStartup).ToString(); // 暂时客户端没有这个数据,只能做个假的 result["CreateTime"] = ((long) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds).ToString(); return result; } // Hack:临时用这个方式进行模块统一 protected void LoginPhpWithToken(DownloadJsonFile action, string token) { string ip; int port; var userId = default(string); var serverId = default(int); var channel = default(string); if (!string.IsNullOrEmpty(action.error)) { port = -1; ip = action.error; } else { try { var json = action.jsonData; var msg = json["msg"].ToString(); if (msg != "success") { Debug.LogError(string.Format("OnPhpLoginComplete Error: " + msg)); port = -1; ip = msg; } else { var data = json["data"]; userId = data["user"].ToString(); serverId = int.Parse(data["serverid"].ToString()); ip = data["srvaddr"].ToString(); port = int.Parse(data["srvport"].ToString()); channel = data["cchid"].ToString(); var newPlayer = int.Parse(data["isnew"].ToString()) > 0; if (newPlayer) loadUri = data["loadurl"].ToString(); } } catch (Exception e) { Debug.LogError(e); ip = e.ToString(); port = -1; } } if (port >= 0) { var accountData = new LoginData.AccountData(); LoginData.accountData = accountData; accountData.SetSDKData(userId, serverId, token, channel); } SdkControl.instance.LoginPhpComplete(ip, port); } protected object ParseServerList(DownloadJsonFile action) { // 特殊处理,字符串代表报错,服务器列表代表有效 object result = null; if (!string.IsNullOrEmpty(action.error)) { Debug.LogError(action.error); } else { var jsonData = action.jsonData; var msg = jsonData["msg"]; if (msg == null || msg.ToString() != "success") { if (msg != null) result = msg.ToString(); } else { try { var serverData = jsonData["data"]; var serverListJson = serverData["server_list"]; //服务器分区列表 var zoneListJson = serverData["server_zone"]; var defaultServerJson = serverData["default_server"]; var zoneList = new List>(); for (var i = 0; i < zoneListJson.Count; i++) { var json = zoneListJson[i]; var zoneStart = int.Parse(json["start"].ToString()); var zoneEnd = int.Parse(json["end"].ToString()); var zoneName = string.Format("{0}区-{1}区", zoneStart, zoneEnd); var zoneId = zoneStart.ToString() + zoneEnd; var page = new LoginData.ServerPageData(zoneName); zoneList.Add(new MyTuple(zoneId, page)); } var list = new List(); foreach (var zoneId in serverListJson.Keys) { var zoneTuple = zoneList.Find(a => a.first == zoneId); if (zoneTuple == null) { Debug.LogError(string.Format("Unable to find server in zone {0}!", zoneId)); } else { var zoneJson = serverListJson[zoneId]; var zone = zoneTuple.second; for (var i = 0; i < zoneJson.Count; i++) { var serverJson = zoneJson[i]; var id = int.Parse(serverJson["server_id"].ToString()); var name = serverJson["name"].ToString(); var state = int.Parse(serverJson["status"].ToString()); var recommend = state == 7 ? 1 : 0; // 翻译Php的State到实际游戏State ServerListItem.State serverState; switch (state) { case 1: case 2: case 6: serverState = ServerListItem.State.STOP; break; case 5: serverState = ServerListItem.State.HOT; break; default: serverState = ServerListItem.State.NORAML; break; } var server = new LoginData.ServerListData(id, name, serverState, recommend, 0); list.Add(server); zone.pageList.Add(server); } } } var defaultId = int.Parse(defaultServerJson["server_num"].ToString()); this.defaultServer = defaultId; var defaultServer = list.Find(a => a.m_id == defaultId); if (defaultServer != null) defaultServer.isDefault = true; result = zoneList.Select(a => a.second).ToList(); } catch (Exception e) { Debug.LogError(e); result = e.ToString(); } } } return result; } /// /// 通知Php服务器登录事件 /// public abstract void LoginPhp(int serverId); /// /// 打开SDK登陆界面 /// public abstract void LoginSdk(bool isAuto); /// /// Php服务器支付,然后Sdk支付流程 /// 可能部分Sdk会交换顺序,因此处理成这个鸟样 /// public abstract void Payment(int goodsId); public void Notice(bool alwaysOpen) { if (!string.IsNullOrEmpty(noticeUri)) { Debug.Log("NoticeUri: " + noticeUri); var jsonDownloader = new DownloadJsonFile(noticeUri, 10f) { // 标志位,是为空object,否为null; token = alwaysOpen ? new object() : null, onDownloadComplete = OnNoticeComplete }; jsonDownloader.Start(); } } private void OnNoticeComplete(DownloadJsonFile action) { var title = default(string); var content = default(string); var willOpen = false; if (!string.IsNullOrEmpty(action.error)) { Debug.LogError(action.error); } else { var jsonData = action.jsonData; var msg = jsonData["msg"]; if (msg == null || msg.ToString() != "success") Debug.LogError("Get Notice didn't get success!"); else try { var data = jsonData["data"]; if (data.IsArray) { data = data[0]; title = data["title"].ToString(); content = data["content"].ToString(); willOpen = !data["is_show"].ToString().Equals("0"); } } catch (Exception e) { Debug.LogError(e); title = default(string); content = default(string); } } SdkControl.instance.NoticeComplete(title, content, willOpen || action.token != null); } public void RedemptionCode(string code) { if (!string.IsNullOrEmpty(redemptionUri)) { var data = new Dictionary(); data["server_id"] = LoginData.accountData.serverId.ToString(); data["cch_id"] = LoginData.accountData.channel; data["actorid"] = GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.Guid.ToString(); data["code"] = code; var jsonDownloader = new DownloadJsonFile(redemptionUri, 10f, data) { onDownloadComplete = OnRedemptionCodeComplete }; jsonDownloader.Start(); } } private void OnRedemptionCodeComplete(DownloadJsonFile action) { if (!string.IsNullOrEmpty(action.error)) { MessageBoxLogic.OpenOKBox("兑换失败,请在网络通畅时重试!"); } else { var jsonData = action.jsonData; var msg = jsonData["msg"]; var msgText = msg == null ? string.Empty : msg.ToString(); if (msgText != "success") MessageBoxLogic.OpenOKBox(msgText); // 激活成功由服务器发消息 // else // MessageBoxLogic.OpenOKBox("(Not Localized)兑换成功!"); } } #endregion #region Sdk输入指令 public abstract bool LoginComplete(string args); public abstract bool LogOutComplete(string args); public abstract bool PaymentComplete(string data); #endregion } public enum LoadDataType { EnterCreate = 2, // 进入创角页面 StartCreate = 3, // 开始创建角色 EndCreate = 4, // 完成创建角色 EnterGame = 5, // 进入游戏 }