////////////////////////////////////////////////////////////////////////// // // 文件:Assets/Code/Scripts/Gameplay/Net/Client/AppConfig.cs // 作者:Xoen Xie // 时间:2023/07/19 // 描述:app config // 说明: // ////////////////////////////////////////////////////////////////////////// using Framework; using UnityEngine; using System.Collections.Generic; using UnityEngine.Networking; using System.Xml; using System; using System.IO; using System.Text; using Cysharp.Threading.Tasks; using PhxhSDK; using PhxhSDK.AOT.VersionUpdate; namespace Gameplay.Net { public struct AddrInfo { public string ip; public uint port; } public struct ServerInfo { public string name; public AddrInfo[] addrs; } public class CompulsoryUpdate { public bool NeedUpdate; public Dictionary AppUrl; } public class NoticeInfo { public string Title; public string Content; } public enum ACDownloadStatus { None = 0, OK, Error, } public sealed class AppConfig : Singlenton, IInitable, ACDownloadHanlder { #if UNITY_EDITOR private readonly string appDir = "editor"; #elif UNITY_ANDROID private readonly string appDir = "android"; #elif UNITY_IOS private readonly string appDir = "ios"; #else private readonly string appDir = "other"; #endif private readonly string appURLPrefix = "http://132.232.113.98/config"; // editor/server.0.0.1.xml"; private string m_sAppUrl; private List m_ServerInfos; public CompulsoryUpdate UpdateInfo { get; private set; } public List NoticeInfos { get; private set; } public ServerInfo Current { get; private set; } public string URL { get { return m_sAppUrl;}} public ACDownloadStatus DownloadStatus { get; private set; } public void Init() { string version = Application.version; var workSpace = PackDataInst.inst == null ? "Dev" : PackDataInst.inst.localInfo.workSpace; DebugUtil.Log("AppConfig Current App Version:{0}", version); m_sAppUrl = $"{appURLPrefix}/{appDir}/server.{workSpace}.{version}.xml"; DebugUtil.Log("AppConfig Current App Config Url:{0}", m_sAppUrl); m_ServerInfos = new List(); } public List GetServerInfo() { return m_ServerInfos; } public ServerInfo GetCurrent() { return Current; } public void Release() { } public async UniTask UnityRequest() { GameObject obj = new GameObject(); obj.name = "AppConfigDownload"; var mono = obj.AddComponent(); mono.Init(this); while (DownloadStatus == ACDownloadStatus.None) { await UniTask.Yield(); // 在这里执行需要循环检测的操作 } return DownloadStatus; } public void OnRequestFinished(UnityWebRequest request) { DownloadStatus = ACDownloadStatus.Error; switch (request.result) { // The request finished without any problem. case UnityWebRequest.Result.Success: OnServerInfo(request.downloadHandler.text); DownloadStatus = ACDownloadStatus.OK; break; case UnityWebRequest.Result.ConnectionError: // TODO, retry several times DebugUtil.LogError("Request Finished with Error, error = {0} ", request.error); break; case UnityWebRequest.Result.ProtocolError: // TODO, version error DebugUtil.LogError("Request Finished with Error, error = {0} ", request.error); break; case UnityWebRequest.Result.DataProcessingError: // TODO, version error DebugUtil.LogError("Request Finished with Error, error = {0} ", request.error); break; default: DebugUtil.LogError("Request Finished with Error, error = {0} ", request.error); break; } } private void OnServerInfo(string text) { var settings = new XmlReaderSettings(); settings.IgnoreComments = true; var reader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(text)), settings); var doc = new XmlDocument(); doc.Load(reader); //获取强更信息 UpdateInfo = new CompulsoryUpdate(); var configNode = doc.SelectSingleNode("root/config"); UpdateInfo.NeedUpdate = bool.Parse(configNode.SelectSingleNode("AppUpdate").InnerText); DebugUtil.Log("Need to force update:{0}", UpdateInfo.NeedUpdate); if (UpdateInfo.NeedUpdate) { OpenNeedUpdateWindows(); return; } var appUrls = configNode.SelectNodes("AppUrl/u"); UpdateInfo.AppUrl = new Dictionary(); foreach (XmlNode urlNode in appUrls) { string type = urlNode.Attributes["type"].Value; string data = urlNode.Attributes["data"].Value; UpdateInfo.AppUrl.Add(type, data); } //获取公告信息 NoticeInfos = new List(); var noticeNode = doc.SelectSingleNode("root/notice"); if (noticeNode != null) { var noticeList = noticeNode.ChildNodes; for (int i = 0; i < noticeList.Count; i++) { var noticeElement = noticeList[i] as XmlElement; NoticeInfo noticeInfo = new NoticeInfo(); noticeInfo.Title = noticeElement.SelectSingleNode("title").InnerText; noticeInfo.Content = noticeElement.SelectSingleNode("body").InnerText; NoticeInfos.Add(noticeInfo); } } var rootNode = doc.SelectSingleNode("root"); var nodeList = rootNode.SelectSingleNode("ServerList").ChildNodes; for (var i = 0; i < nodeList.Count; ++i) { var ele = nodeList[i] as XmlElement; ServerInfo sni; sni.name = ele.GetAttribute("name"); sni.addrs = new AddrInfo[ele.ChildNodes.Count]; for (var J = 0; J < ele.ChildNodes.Count; J++) { var eleAddr = ele.ChildNodes[J] as XmlElement; AddrInfo adi; adi.ip = eleAddr.GetAttribute("ip"); string port = eleAddr.GetAttribute("port"); adi.port = Convert.ToUInt32(port); sni.addrs[J] = adi; } foreach (var info in NoticeInfos) { DebugUtil.Log("AppConfig.NoticeInfo Title={0},Content={1}", info.Title, info.Content); } DebugUtil.Log("AppConfig.OnServerInfo name={0}, count={1} ip={2}, port={3}", sni.name, sni.addrs.Length, sni.addrs[0].ip, sni.addrs[0].port); m_ServerInfos.Add(sni); } if (EventManager.Instance != null) EventManager.Instance.Send(EventManager.EventName.NetLoginServerInfo); } public void Select(int nIndex) { if (nIndex >= m_ServerInfos.Count) { Current = m_ServerInfos[0]; DebugUtil.LogError("AppConfig Select nIndex:{0} >= m_ServerInfos.Count:{1}, set default as 0", nIndex, m_ServerInfos.Count); return; } Current = m_ServerInfos[nIndex]; DebugUtil.Log("AppConfig Select name={0}, length={1}", Current.name, Current.addrs.Length); } private void OpenNeedUpdateWindows() { UIManager.Instance.CreateAndOpenWindow(UINameConst.UI_Update); DebugUtil.LogError("需要下载正确客户端版本"); } } }