using Net;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
namespace GuiltyVoid.basic.version
{
/// <summary>
/// 当前版本状态
/// </summary>
public enum VersionStatus
{
Latest = 1, //最新
NeedDownLoadNewApp = 2, //需要换包
AccessLogin = 3, //需要更新,但是可以登录
UnAccessLogin = 4, //需要更新,但是不可以登录
}
/// <summary>
/// 版本控制系统
/// </summary>
public class VersionManageSystem : Singleton<VersionManageSystem>
{
#region 变量域
/// <summary>
/// 当前版本控制系统版本状态
/// </summary>
private VersionStatus m_versionStatus;
public VersionStatus versionStatus
{
get { return m_versionStatus; }
set { m_versionStatus = value; }
}
/// <summary>
/// 版本控制系统配置文件
/// </summary>
private VersionManageSystemConfig Config;
/// <summary>
/// 当前本地的版本文件
/// </summary>
private VersionInfo m_LocalVesionFile;
public VersionInfo LocalVesionFile
{
get { return m_LocalVesionFile; }
set { m_LocalVesionFile = value; }
}
/// <summary>
/// 版本号字符串(用于ManaServer比对)
/// </summary>
private string m_Version;
/// <summary>
/// 当前服务器的版本文件
/// </summary>
private DBVersionInfo m_ServerVesionFile;
public DBVersionInfo ServerVesionFile
{
get { return m_ServerVesionFile; }
set { m_ServerVesionFile = value; }
}
#endregion
/// <summary>
/// 初始化
/// </summary>
public void Init()
{
Config = Resources.Load<VersionManageSystemConfig>("Config/VersionManageSystemConfig");
if (Config == null)
{
Debug.LogError($"[VersionManageSystem] Error: None VersionManageSystemConfig Found!");
return;
}
}
/// <summary>
/// 获取当前本地版本号字符串
/// </summary>
/// <returns></returns>
public string GetLocalVersionStr()
{
m_Version = $"{m_LocalVesionFile.AssetsVersion.Major}.{m_LocalVesionFile.AssetsVersion.Minor}.{m_LocalVesionFile.AssetsVersion.Revision}";
return m_Version;
}
/// <summary>
/// 获取当前服务器版本号字符串
/// </summary>
/// <returns></returns>
public string GetServerVersionStr()
{
m_Version = $"{m_ServerVesionFile.LatestVersion.AssetsVersion.Major}.{m_ServerVesionFile.LatestVersion.AssetsVersion.Minor}. {m_ServerVesionFile.LatestVersion.AssetsVersion.Revision}";
return m_Version;
}
/// <summary>
/// 检查当前服务器版本信息
/// </summary>
public async Task CheckServerVersion()
{
var versionFile = await Client.Instance.GetVersionInfo();//请求服务器获取最新的版本信息Json字符串
UpdateServerVersionFile(versionFile);//更新服务器VersionFile
CheckVersion();
}
#region 版本文件I/O
/// <summary>
/// 更新服务器版本文件
/// </summary>
/// <param name="_input">版本文件Json字符串</param>
public void UpdateServerVersionFile(DBVersionInfo _input)
{
ServerVesionFile = _input;
}
/// <summary>
/// 读取本地版本文件
/// </summary>
public void ReadLocalVersionFile()
{
var _outPut = PlayerPrefsMgr.GetStringWithoutSpecialKey("LocalVesionFile");//获取本地版本信息
if (_outPut == "")
{
//本地没有读取到对应数据
LocalVesionFile = Config.PackageInitialVersion; //使用包配置文件填写的初始版本号
return;
}
var info = JsonToVersionInfo(_outPut);//反序列化
LocalVesionFile = info;//写入到当前版本控制系统对应字段
}
/// <summary>
/// 写入本地版本文件
/// </summary>
public void WriteLocalVersionFile()
{
//如果不是当前最新版本则不写入版本文件
if (m_versionStatus != VersionStatus.Latest)
{
return;
}
LocalVesionFile = m_ServerVesionFile.LatestVersion;//写入到当前服务器最新版本号(暂时一起写入不区分各个版本号(Assets/Data/Client))
var _Input = VersionInfoToJson(m_LocalVesionFile); //先序列化当前的本地版本文件
PlayerPrefsMgr.SetStringWithoutSpecialKey("LocalVesionFile", _Input);//写入本地playerprefs(可以替换为项目对应的本地PlayerPrefs管理方法)
}
/// <summary>
/// 清空本地版本信息缓存
/// </summary>
public void ClearLocalVersionFile()
{
PlayerPrefsMgr.SetStringWithoutSpecialKey("LocalVesionFile", "");//写入本地playerprefs
}
/// <summary>
/// 序列化版本文件成Json字符串
/// </summary>
/// <param name="info">版本文件</param>
/// <returns></returns>
private string VersionInfoToJson(VersionInfo info)
{
try
{
string result = JsonConvert.SerializeObject(info);
return result;
}
catch (Exception e)
{
Debug.LogError($"[VersionManageSystem] Error: VersionInfoToJson Failed");
throw e;
}
}
/// <summary>
/// 反序列化Json到DBVersionInfo
/// </summary>
/// <param name="json">json字符串</param>
/// <returns></returns>
private VersionInfo JsonToVersionInfo(string json)
{
try
{
VersionInfo result = JsonConvert.DeserializeObject<VersionInfo>(json);
return result;
}
catch (Exception e)
{
Debug.LogError($"[VersionManageSystem] Error: JsonToVersionInfo Failed :{json}");
throw e;
}
}
/// <summary>
/// 反序列化Json到DBVersionInfo
/// </summary>
/// <param name="json">json字符串</param>
/// <returns></returns>
private DBVersionInfo JsonToDBVersionInfo(string json)
{
try
{
DBVersionInfo result = JsonConvert.DeserializeObject<DBVersionInfo>(json);
return result;
}
catch (Exception e)
{
Debug.LogError($"[VersionManageSystem] Error: JsonToDBVersionInfo Failed :{json}");
throw e;
}
}
#endregion
#region 校验检查版本号方法
/// <summary>
/// 检查当前版本状态
/// </summary>
/// <returns>当前版本状态</returns>
public VersionStatus CheckVersion()
{
//判断当前是否不低于最低换包限制版本号
if (!CheckClientAppVersion())
{
versionStatus = VersionStatus.NeedDownLoadNewApp; //需要换包
return m_versionStatus;
}
if (CheckLatestVersion())
{
versionStatus = VersionStatus.Latest; //最新的版本
}
else
{
//如果当前需要更新包,则在判断一下当前版本有没有达到最低进入游戏限制
versionStatus = CheckLoginAccessVersion() ? VersionStatus.AccessLogin : VersionStatus.UnAccessLogin;
}
return m_versionStatus;
}
/// <summary>
/// 检查当前版本号是否低于最低换包版本号限制
/// </summary>
/// <returns></returns>
public bool CheckClientAppVersion()
{
return CheckTargetVersion(m_LocalVesionFile,m_ServerVesionFile.UpdateMinVersion,Config.UpdateAppVersionInfo);
}
/// <summary>
/// 检查当前版本号是否低于最低可进入游戏限制
/// </summary>
/// <returns></returns>
public bool CheckLoginAccessVersion()
{
return CheckTargetVersion(m_LocalVesionFile, m_ServerVesionFile.LoginMinVersion, Config.LoginMinVersionInfo);
}
/// <summary>
/// 检查当前最新版本号
/// </summary>
/// <returns></returns>
public bool CheckLatestVersion()
{
return CheckTargetVersion(m_LocalVesionFile, m_ServerVesionFile.LatestVersion, Config.LatestVersionInfo);
}
/// <summary>
/// 检测指定类型版本号信息
/// </summary>
/// <param name="local">本地版本数据</param>
/// <param name="server">服务器版本数据</param>
/// <param name="diffFilter">版本对比筛选器</param>
/// <returns>返回是否大于当前版本号信息</returns>
private bool CheckTargetVersion(VersionInfo local, VersionInfo server, VersionDiffFilter diffFilter)
{
var result = true; //版本比对结果
//根据筛选器检查各类型版本号
if (diffFilter.Asset)
{
result = result && CheckSingleVersionIfo(local.AssetsVersion, server.AssetsVersion);
}
if (diffFilter.Data)
{
result = result && CheckSingleVersionIfo(local.DataVersion, server.DataVersion);
}
if (diffFilter.Client)
{
result = result && CheckSingleVersionIfo(local.ClientVersion, server.ClientVersion);
}
return result;
}
/// <summary>
/// 检测一条具体版本号信息
/// </summary>
/// <param name="local">本地版本数据</param>
/// <param name="server">服务器版本数据</param>
/// <returns></returns>
private bool CheckSingleVersionIfo(Version local, Version server)
{
//判断每一级版本域是否符合条件,如果对应的版本域号相等则在判断下一级版本号
//先判断Major总版本号
if (local.Major == server.Major)
{
//在判断次级版本号
if (local.Minor == server.Minor)
{
//最后在判断修订版本号
return local.Revision >= server.Revision;
}
else
{
return local.Minor > server.Minor;
}
}
else
{
return local.Major > server.Major;
}
}
#endregion
}
#region 服务器版本信息结构体定义
[Serializable]
/// <summary>
/// 当前所有类型版本信息
/// </summary>
public struct DBVersionInfo
{
/// <summary>
/// 换包最低版本号限制
/// </summary>
public VersionInfo UpdateMinVersion;
/// <summary>
/// 进入游戏版本号限制
/// </summary>
public VersionInfo LoginMinVersion;
/// <summary>
/// 最新版本号
/// </summary>
public VersionInfo LatestVersion;
public DBVersionInfo(VersionInfo updateMinVersion, VersionInfo loginMinVersion, VersionInfo latestVersion)
{
UpdateMinVersion = updateMinVersion;
LoginMinVersion = loginMinVersion;
LatestVersion = latestVersion;
}
}
[Serializable]
/// <summary>
/// 版本信息
/// </summary>
public struct VersionInfo
{
/// <summary>
/// 资源版本号
/// </summary>
public Version AssetsVersion;
/// <summary>
/// 数据表版本号
/// </summary>
public Version DataVersion;
/// <summary>
/// 客户端版本号(Lua脚本等)
/// </summary>
public Version ClientVersion;
public VersionInfo(Version assetsVersion, Version dataVersion, Version clientVersion)
{
AssetsVersion = assetsVersion;
DataVersion = dataVersion;
ClientVersion = clientVersion;
}
}
[Serializable]
/// <summary>
/// 版本号域定义
/// </summary>
public struct Version
{
public int Major;
public int Minor;
public int Revision;
public Version(int major, int minor, int revision)
{
Major = major;
Minor = minor;
Revision = revision;
}
}
#endregion
}
using System;
using System.Collections.Generic;
using UnityEngine;
namespace GuiltyVoid.basic.version
{
/// <summary>
/// 版本控制系统配置文件
/// </summary>
[CreateAssetMenu(fileName = "VersionManageSystemConfig.asset", menuName = "Config/VersionManageSystemConfig")]
public class VersionManageSystemConfig :ScriptableObject
{
/// <summary>
/// 是否换包版本对比筛选配置
/// </summary>
public VersionDiffFilter UpdateAppVersionInfo;
/// <summary>
/// 是否换包版本对比筛选配置
/// </summary>
public VersionDiffFilter LoginMinVersionInfo;
/// <summary>
/// 是否换包版本对比筛选配置
/// </summary>
public VersionDiffFilter LatestVersionInfo;
/// <summary>
/// 当前安装包的初始版本信息
/// </summary>
public VersionInfo PackageInitialVersion;
}
/// <summary>
/// 版本号信息对比筛选器
/// </summary>
[Serializable]
public struct VersionDiffFilter
{
/// <summary>
/// 资源文件
/// </summary>
public bool Asset;
/// <summary>
/// 数据表文件
/// </summary>
public bool Data;
/// <summary>
/// 客户端代码等文件
/// </summary>
public bool Client;
}
}