仿LOL项目开发第二天
by草帽
接着上节来讲,上节更新还没开始写代码逻辑,今天我们补充完整。
我们找到VersionManager脚本里面的CheckVersion方法:
首先我们想到检测版本,需要从服务器下载信息,那么肯定要提前检测下网络是否良好,并比较版本信息。
所以,我们写个BeforeCheck方法:
/// <summary>
/// 检测网络状况并对照版本信息是否一致
/// </summary>
/// <param name="AsynResult">版本信息是否一致的处理委托</param>
/// <param name="OnError">错误处理委托</param>
public void BeforeCheck(Action<bool> AsynResult, Action OnError)
{
CheckTimeout checkTimeout = new CheckTimeout();
checkTimeout.AsynIsNetworkTimeout((success) =>
{
//如果网络良好,开始下载服务器版本xml
if (success)
{
}
else
{
if (OnError != null)
{
OnError();
}
}
});
}
在写网络良好判断的带参匿名委托之前,我们先来思考一个问题,网络良好接下来需要做什么?
就是下载服务端的版本信息,但是得需要一个url地址来访问?
那么这个服务端版本信息的URL在哪里?难道要把绝对的URl定死的写入到代码中。
假如我以后服务器的URL换了呢?那么就要重新改写代码。这种方案否决,不可取。
所以呢,这个服务器的URL应该得写入到配置文件中,从服务器那边下载。
非常nice,之前我们不是写个一个SystemConfig,我们就在里面初始化服务器的URL。
所以SystemConfig需要一个Init()的初始方法。
初始配置文件分为两类:
1.从服务器那边获取的配置信息,比如版本信息,游戏服务器各个大区的信息
2.本地配置信息,比如声音大小,屏幕分辨率等等
首先,先来加载服务器相关的配置信息,与服务器相关的,我们需要分类:所以写个CfgInfo类:
public class CfgInfo
{
public int id { get; set; }
public string name { get; set; }
public string url { get; set; }
}
比如版本信息类id=0,游戏服务器大区类id=1,然后分别对应着不同的url,这样我们管理起来就清晰多了。
那么这个CfgInfo信息是哪里来的,肯定也需要访问服务器那边的url获取,所以呢,我们在Resources文件夹下面创建一个txt,里面写着这个Url,然后访问URl,读取里面的内容初始化所有的CfgInfo类存到列表中List<CfgInfo>,最后还要把Url文本保存在持久文件夹下,以便以后使用,OK分析完之后。
在SystemConfig类下创建常量:CfgPath持久路径
public readonly static string CfgPath = Application.persistentDataPath + "/cfg.xml";
然后我们在SystemConfig里面创建LoadCfgInfo()方法,在Init()里面调用:
private static bool LoadCfgInfo()
{
string cfgStr = null;
//如果存在持久路径,就直接加载文本
if (File.Exists(CfgPath))
{
cfgStr = UnityTools.LoadFileText(CfgPath);
}
else
{
//从Resources从加载配置文本
TextAsset cfgUrl = Resources.Load("cfg") as TextAsset;
if (cfgUrl)
{
//从网页上下载与服务端有关的所有配置xml字符串
cfgStr = DownloadMgr.Instance.DownLoadHtml(cfgUrl.text);
}
else
{
cfgStr = null;
}
}
//加载xml内容为列表类
CfgInfoList = LoadXMLText<CfgInfo>(cfgStr);
return true;
}
LoadXMLText<T>(string xmlText):
/// <summary>
/// 将xml转换成list<T>列表类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xmlText"></param>
/// <returns></returns>
private static List<T> LoadXMLText<T>(string xmlText)
{
List<T> list = new List<T>();
try
{
if (string.IsNullOrEmpty(xmlText))
{
return list;
}
Type type = typeof(T);
XmlDocument doc = XmlResAdapter.GetXmlDocument(xmlText);
Dictionary<int,Dictionary<string,string>> map = XmlResAdapter.LoadXMLToMap(doc,xmlText);
var props = type.GetProperties(~System.Reflection.BindingFlags.Static);
foreach (var item in map)
{
var obj = type.GetConstructor(Type.EmptyTypes).Invoke(null);
foreach (var prop in props)
{
if (prop.Name == "id")
{
prop.SetValue(obj,item.Key,null);
}
else
{
try
{
if (item.Value.ContainsKey(prop.Name))
{
var value = UnityTools.GetValue(item.Value[prop.Name],prop.PropertyType);
prop.SetValue(obj,value,null);
}
}
catch(Exception e)
{
Debug.LogException(e);
}
}
}
list.Add((T)obj);
}
}
catch(Exception e)
{
Debug.LogException(e);
}
return list;
}
XmlResAdapter.LoadXMLToMap():
/// <summary>
/// 将xml内容转换成map
/// </summary>
/// <param name="doc"></param>
/// <param name="content"></param>
/// <returns></returns>
public static Dictionary<int, Dictionary<string, string>> LoadXMLToMap(XmlDocument doc, string content)
{
var result = new Dictionary<int, Dictionary<string, string>>();
int index = 0;
foreach (XmlNode item in doc.SelectSingleNode("root").ChildNodes)
{
index++;
if (item.ChildNodes == null || item.ChildNodes.Count == 0)
{
continue;
}
int key = int.Parse(item.ChildNodes[0].InnerText);
if (result.ContainsKey(key))
{
continue;
}
var children = new Dictionary<string, string>();
result.Add(key, children);
for (int i = 1; i < item.ChildNodes.Count; i++)
{
XmlNode node = item.ChildNodes[i];
string tag = null;
if (node.Name.Length < 3)
{
tag = node.Name;
}
else
{
string tagTial = node.Name.Substring(node.Name.Length - 2, 2);
if (tagTial == "_i" || tagTial == "_s" || tagTial == "_f" || tagTial == "_l" || tagTial == "_k" || tagTial == "_m")
{
tag = node.Name.Substring(0, node.Name.Length - 2);
}
else
{
tag = node.Name;
}
}
if (node != null && !children.ContainsKey(tag))
{
if (string.IsNullOrEmpty(node.InnerText))
{
children.Add(tag, "");
}
else
{
children.Add(tag, node.InnerText.Trim());
}
}
}
}
return result;
}
所以这里我们就需要用到第一节提到的准备工具:WampServer集成的网页开发工具:
因为这里我们需要涉及到访问服务器的url,所以我们自己架设一个http服务器站点。
打开WampServer,找到www目录

然后新建一个文件夹,命名为LOLGameDemo

在这个文件夹下面新建一个xml,命名为Cfg.xml

然后回到Unity的Resources文件下面新建一个txt,也命名为Cfg.txt。
编辑txt里面的内容:

然后编辑Cfg.xml的内容:

然后在LOLGameDemo文件夹下,新创建一个ServerVersion.xml文本,为服务器的版本信息:

OK,大功告成。接着我们回到VersionManager里面的BeforeCheck方法里面:
我们要获取到服务器版本的url,所以得回到SystemConfig编写一个GetCfgInfoByName()方法或者GetCfgInfoById()的接口。
GetCfgInfoByName():
/// <summary>
/// 根据名字取得服务端配置信息Url
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static string GetCfgInfoUrlByName(string name)
{
string result = "";
foreach (var item in CfgInfoList)
{
if (item.name == name)
{
result = item.url;
break;
}
}
return result;
}
GetCfgInfoById():
/// <summary>
/// 根据id取得服务端配置信息Url
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static string GetCfgInfoUrlById(int id)
{
string result = "";
foreach (var item in CfgInfoList)
{
if (item.id == id)
{
result = item.url;
break;
}
}
return result;
}
因为我们下载的服务器的版本文本也要保存在持久文件目录,所以:
public readonly static string ServerVersionPath = Application.persistentDataPath + "/serverVersion.xml";
还有之前我们只是初始化本地版本信息类的实例,所以现在我们在VersionManager创建一个服务端的版本信息类:
/// <summary>
/// 本地版本信息属性
/// </summary>
public VersionManagerInfo LocalVersion { get; private set; }
/// <summary>
/// 服务版本信息属性
/// </summary>
public VersionManagerInfo ServerVersion { get; private set; }
然后再次回到BeforeCheck方法里面,终于回来了!0.0!
public void BeforeCheck(Action<bool> AsynResult, Action OnError)
{
CheckTimeout checkTimeout = new CheckTimeout();
checkTimeout.AsynIsNetworkTimeout((success) =>
{
//如果网络良好,开始下载服务器版本xml
if (success)
{
DownloadMgr.Instance.AsynDownLoadHtml(SystemConfig.GetCfgInfoUrlByName("version"),
(serverVersion) =>
{
//如果本地存在服务端的版本信息文本,覆盖下载的服务器文本
if (File.Exists(SystemConfig.ServerVersionPath))
{
serverVersion = UnityTools.LoadFileText(SystemConfig.ServerVersionPath);
}
//将文本转换成版本信息类
ServerVersion = GetVersionInXml(serverVersion);
//开始进行比较版本号
bool programVersion = ServerVersion.ProgramVersionCodeInfo.Compare(LocalVersion.ProgramVersionCodeInfo) > 0;
bool resourceVersion = ServerVersion.ResourceVersionCodeInfo.Compare(LocalVersion.ResourceVersionCodeInfo) > 0;
//执行是否更新的委托
AsynResult(programVersion || resourceVersion);
},OnError);
}
else
{
if (OnError != null)
{
OnError();
}
}
});
}
原文:http://www.cnblogs.com/CaomaoUnity3d/p/5459265.html