using System.Collections;
|
using System.Collections.Generic;
|
using UnityEngine;
|
using System;
|
using System.Text.RegularExpressions;
|
|
|
public class InGameDownLoad : SingletonMonobehaviour<InGameDownLoad>
|
{
|
public const int BYTE_PER_KILOBYTE = 1024;//b 转 kb
|
public const int BYTE_PER_MILLIONBYTE = 1048576;//b 转 mb
|
|
List<AssetVersion> assets = new List<AssetVersion>(); //所有资源
|
Dictionary<int, List<AssetVersion>> mapTasks = new Dictionary<int, List<AssetVersion>>();//地图专属的资源
|
|
public bool inGameDownLoadAllow = false; //是否可以下载
|
public bool downLoadGo = false; //是否加速下载
|
|
public float progress //下载进度
|
{
|
get
|
{
|
return Mathf.Clamp01((float)showDownLoadedSize / showTotalSize);
|
}
|
}
|
|
public bool isDone { get { return state == State.Completed; } } //是否全部下载完成
|
|
//窗口中显示的已下载大小
|
public long showDownLoadedSize { get { return DownloadMgr.Instance.DownloadedBytes - backGroundDownLoadSizeRecord; } }
|
public long showTotalSize { get { return totalSize - backGroundDownLoadSizeRecord; } }//窗口中显示的总大小
|
public int showTotalCount { get { return totalCount - downLoadedCountRecord; } }//窗口中显示的总数量
|
public int showOkCount { get { return okCount - downLoadedCountRecord; } }//窗口中显示的下载完成数量
|
|
long totalSize = 0; //资源总大小
|
int totalCount = 0;//资源总数量
|
int okCount = 0;//下载完成的数量
|
|
long backGroundDownLoadSizeRecord = 0;//后台偷偷已经下载到资源量
|
int downLoadedCountRecord = 0;//后台已经下载完成的资源包数量
|
|
public event Action<State> downLoadStateChangeEvent;
|
public event Action<Dominant> dominantDownLoadEvent;
|
|
Action onDownLoadOk;//资源全部下载完成回调
|
|
Dominant m_DominantState = Dominant.None;
|
public Dominant dominantState
|
{
|
get { return m_DominantState; }
|
private set
|
{
|
if (m_DominantState != value)
|
{
|
m_DominantState = value;
|
if (dominantDownLoadEvent != null)
|
{
|
dominantDownLoadEvent(m_DominantState);
|
}
|
}
|
}
|
}
|
|
State m_State = State.None;
|
public State state
|
{
|
get { return m_State; }
|
set
|
{
|
if (m_State != value)
|
{
|
m_State = value;
|
|
if (downLoadStateChangeEvent != null)
|
{
|
downLoadStateChangeEvent(m_State);
|
}
|
}
|
}
|
}
|
|
public List<Reward> rewards = new List<Reward>();
|
public bool hasReward { get; private set; }//是否有奖励
|
public string completeDownLoadAccount
|
{
|
get { return LocalSave.GetString("InGameDownLoadCompleteAccount"); }
|
set { LocalSave.SetString("InGameDownLoadCompleteAccount", value); }
|
}
|
|
public Redpoint downLoadRedpoint = new Redpoint(116);
|
|
private void Awake()
|
{
|
DownloadMgr.MaxDownLoadTask = GetMaxTask();
|
}
|
|
private void LateUpdate()
|
{
|
if (state == State.None || state == State.Award || state == State.Completed)
|
{
|
return;
|
}
|
|
netCheckTimer += Time.deltaTime;
|
|
if (InGameDownTestUtility.enable)
|
{
|
simulateWifi = InGameDownTestUtility.isWifi;
|
}
|
else
|
{
|
if (netCheckTimer > 3f)
|
{
|
netCheckTimer = 0f;
|
networkReachability = Application.internetReachability;
|
}
|
}
|
|
if (mapId != 0)
|
{
|
var progress = GetMapAssetDownLoadProgress(mapId);
|
if (progress > 0.9999f)
|
{
|
if (mapAssetDownLoadOk != null)
|
{
|
mapAssetDownLoadOk();
|
mapAssetDownLoadOk = null;
|
mapId = 0;
|
}
|
}
|
}
|
|
}
|
|
//开始分配任务
|
public void AssignTasks(List<AssetVersion> assets, Action _onDownLoadOk)
|
{
|
|
this.inGameDownLoadAllow = false;
|
this.assets = assets;
|
this.assets.Sort(this.AssetDownLoadPriorCompare);//所有任务根据优先级排序
|
onDownLoadOk = _onDownLoadOk;
|
|
totalCount = this.assets.Count;
|
okCount = 0;
|
totalSize = 0;
|
|
DownloadMgr.Instance.Prepare();
|
|
for (int i = 0; i < this.assets.Count; i++)
|
{
|
var assetVersion = this.assets[i];
|
totalSize += assetVersion.size;//统计资源总大小
|
//统计地图专属的资源 TODO YYL
|
// var mapId = PriorBundleConfig.GetAssetBelongToMap(assetVersion.GetAssetCategory(), AssetVersionUtility.DecodeFileName(assetVersion.fileName));
|
// if (mapId != 0)
|
// {
|
// if (!mapTasks.ContainsKey(mapId))
|
// {
|
// mapTasks[mapId] = new List<AssetVersion>();
|
// }
|
// mapTasks[mapId].Add(assetVersion);
|
// }
|
//添加下载任务
|
var remoteURL = StringUtility.Contact(VersionUtility.Instance.versionInfo.GetResourcesURL(VersionConfig.Get().branch), Language.fixPath, "/", assetVersion.relativePath);
|
var localURL = StringUtility.Contact(ResourcesPath.Instance.ExternalStorePath, assetVersion.relativePath);
|
DownloadMgr.Instance.AddTask(new DownloadTask(remoteURL, localURL, assetVersion));
|
}
|
|
state = State.None;
|
|
PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerLevelChange;
|
PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerLevelChange;
|
}
|
|
//任务根据优先级排序
|
private int AssetDownLoadPriorCompare(AssetVersion lhs, AssetVersion rhs)
|
{
|
var categoryA = lhs.GetAssetCategory();
|
var categoryB = rhs.GetAssetCategory();
|
|
// TODO YYL
|
// var priorA = PriorBundleConfig.GetAssetPrior(categoryA, AssetVersionUtility.DecodeFileName(lhs.fileName));
|
// var priorB = PriorBundleConfig.GetAssetPrior(categoryB, AssetVersionUtility.DecodeFileName(rhs.fileName));
|
|
// if (priorA != priorB)
|
// {
|
// return priorA < priorB ? -1 : 1;
|
// }
|
// else
|
{
|
var isManifestA = lhs.extersion == ".manifest";
|
var isManifestB = rhs.extersion == ".manifest";
|
|
if (!isManifestA && isManifestB)
|
{
|
return -1;
|
}
|
else if (isManifestA && !isManifestB)
|
{
|
return 1;
|
}
|
else
|
{
|
return 0;
|
}
|
}
|
}
|
|
public void TryDownLoad(Dominant _dominant)
|
{
|
if (!inGameDownLoadAllow)
|
{
|
return;
|
}
|
|
if (assets == null || assets.Count == 0 || isDone)
|
{
|
return;
|
}
|
|
if (_dominant < dominantState)
|
{
|
return;
|
}
|
|
switch (_dominant)
|
{
|
case Dominant.None:
|
if (InGameDownTestUtility.enable)
|
{
|
if (InGameDownTestUtility.isWifi)
|
{
|
StartDownLoad();
|
}
|
}
|
else
|
{
|
if (Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork)
|
{
|
StartDownLoad();
|
}
|
}
|
break;
|
case Dominant.Half:
|
if (dominantState == Dominant.None)
|
{
|
backGroundDownLoadSizeRecord = DownloadMgr.Instance.DownloadedBytes;
|
downLoadedCountRecord = okCount;
|
}
|
StartDownLoad();
|
dominantState = Dominant.Half;
|
break;
|
case Dominant.Whole:
|
if (dominantState == Dominant.None)
|
{
|
backGroundDownLoadSizeRecord = DownloadMgr.Instance.DownloadedBytes;
|
downLoadedCountRecord = okCount;
|
Pause();
|
state = State.Prepared;
|
}
|
else if (dominantState == Dominant.Half)
|
{
|
Pause();
|
state = State.Prepared;
|
}
|
dominantState = Dominant.Whole;
|
UIManager.Instance.OpenWindow<InGameDownLoadWin>();
|
// // WindowCenter.Instance.Open<InGameDownLoadWin>();
|
break;
|
}
|
}
|
|
//开始下载
|
public void StartDownLoad()
|
{
|
if (state == State.None || state == State.Prepared || state == State.Pause)
|
{
|
state = State.DownLoad;
|
DownloadMgr.Instance.Begin(OnFileDownLoadCompleted);
|
}
|
}
|
|
//暂停下载
|
public void Pause()
|
{
|
if (state == State.DownLoad)
|
{
|
DownloadMgr.Instance.Stop();
|
state = State.Pause;
|
}
|
}
|
|
//文件下载完成回调
|
private bool OnFileDownLoadCompleted(bool finished, DownloadTask task)
|
{
|
if (task.IsDone && task.obj is AssetVersion)
|
{
|
(task.obj as AssetVersion).localValid = true;
|
okCount++;
|
}
|
if (finished)
|
OnDownLoadFinished();
|
return true;//返回true表示如果下载失败,不重新排队,立即重试
|
}
|
|
//所有任务完成
|
private void OnDownLoadFinished()
|
{
|
PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerLevelChange;
|
|
UIManager.Instance.CloseWindow<InGameDownLoadWin>();
|
|
if (!hasReward)
|
{
|
if (dominantState == Dominant.None)
|
{
|
RequestDownLoadReward(false);
|
state = State.Completed;
|
}
|
else
|
{
|
completeDownLoadAccount = PlayerDatas.Instance.baseData.AccID;
|
state = State.Award;
|
}
|
}
|
else
|
{
|
state = State.Completed;
|
}
|
|
|
downLoadRedpoint.state = state == State.Award ? RedPointState.Simple : RedPointState.None;
|
|
if (onDownLoadOk != null)
|
{
|
onDownLoadOk();
|
onDownLoadOk = null;
|
}
|
}
|
|
public void ParseRewardConfig()
|
{
|
var rewardString = FuncConfigConfig.Get("DownReward").Numerical1;
|
var matches = Regex.Matches(rewardString, "(\\d+,\\d+,\\d+)");
|
for (int i = 0; i < matches.Count; i++)
|
{
|
rewards.Add(new Reward(matches[i].Value));
|
}
|
}
|
|
public void UpdateRewardInfo(HA319_tagMCPackDownloadRecord _package)
|
{
|
hasReward = _package.Record == 1;
|
|
if (AssetVersionUtility.unPriorAssetDownLoadDone)
|
{
|
state = !hasReward && completeDownLoadAccount == PlayerDatas.Instance.baseData.AccID ? State.Award : State.Completed;
|
}
|
|
downLoadRedpoint.state = state == State.Award ? RedPointState.Simple : RedPointState.None;
|
}
|
|
public void RequestDownLoadReward(bool _manual)
|
{
|
var send = new CA504_tagCMPlayerGetReward();
|
send.RewardType = 15;
|
send.DataEx = (byte)(_manual ? 0 : 1);
|
GameNetSystem.Instance.SendInfo(send);
|
}
|
|
public float GetMapAssetDownLoadProgress(int mapId)
|
{
|
if (!mapTasks.ContainsKey(mapId))
|
{
|
return 1f;
|
}
|
|
var tasks = mapTasks[mapId];
|
var total = tasks.Count;
|
if (total == 0)
|
{
|
return 1f;
|
}
|
|
var completeCount = 0;
|
foreach (var task in tasks)
|
{
|
if (task.localValid)
|
{
|
completeCount++;
|
}
|
}
|
|
return completeCount / (float)total;
|
}
|
|
int mapId = 0;
|
Action mapAssetDownLoadOk;
|
public void RegisterMapAssetDownLoadOk(int mapId, Action callBack)
|
{
|
var progress = GetMapAssetDownLoadProgress(mapId);
|
if (progress < 0.999f)
|
{
|
this.mapId = mapId;
|
mapAssetDownLoadOk = callBack;
|
}
|
}
|
|
public void UnRegisterMapAssetDownLoadOk()
|
{
|
this.mapId = 0;
|
mapAssetDownLoadOk = null;
|
}
|
|
Clock netSwitchClock;
|
NetworkReachability m_NetworkReachability = NetworkReachability.NotReachable;
|
NetworkReachability networkReachability
|
{
|
get { return m_NetworkReachability; }
|
set
|
{
|
if (m_NetworkReachability != value)
|
{
|
m_NetworkReachability = value;
|
|
if (dominantState != Dominant.Whole)
|
{
|
switch (m_NetworkReachability)
|
{
|
case NetworkReachability.ReachableViaCarrierDataNetwork:
|
Pause();
|
var endTime = DateTime.Now + new TimeSpan(TimeSpan.TicksPerSecond * 3);
|
if (netSwitchClock != null)
|
{
|
Clock.Stop(netSwitchClock);
|
}
|
|
netSwitchClock = Clock.AlarmAt(endTime, () =>
|
{
|
if (CheckDominantDownLoad())
|
{
|
TryDownLoad(Dominant.Whole);
|
}
|
});
|
break;
|
case NetworkReachability.ReachableViaLocalAreaNetwork:
|
TryDownLoad(Dominant.None);
|
break;
|
default:
|
break;
|
}
|
}
|
}
|
}
|
}
|
|
bool m_SimulateWifi = true;
|
public bool simulateWifi
|
{
|
get { return m_SimulateWifi; }
|
set
|
{
|
if (m_SimulateWifi != value)
|
{
|
m_SimulateWifi = value;
|
|
if (dominantState != Dominant.Whole)
|
{
|
if (m_SimulateWifi)
|
{
|
TryDownLoad(Dominant.None);
|
}
|
else
|
{
|
Pause();
|
var endTime = DateTime.Now + new TimeSpan(TimeSpan.TicksPerSecond * 10);
|
Clock.AlarmAt(endTime, () =>
|
{
|
if (CheckDominantDownLoad())
|
{
|
TryDownLoad(Dominant.Whole);
|
}
|
});
|
}
|
}
|
}
|
|
}
|
}
|
|
float netCheckTimer = 0f;
|
|
public bool CheckDominantDownLoad()
|
{
|
if (assets == null || assets.Count == 0 || isDone || dominantState == Dominant.Whole /*|| NewBieCenter.Instance.inGuiding*/)
|
{
|
return false;
|
}
|
|
if (GeneralDefine.inGameDownLoadLevelCheckPoints == null || GeneralDefine.inGameDownLoadLevelCheckPoints.Count == 0)
|
{
|
return false;
|
}
|
|
if (PlayerDatas.Instance.baseData.LV < GeneralDefine.inGameDownLoadLevelCheckPoints[0])
|
{
|
return false;
|
}
|
|
if (PlayerDatas.Instance.baseData.LV < GeneralDefine.inGameDownLoadHighLevel)
|
{
|
if (InGameDownTestUtility.enable)
|
{
|
if (InGameDownTestUtility.isWifi)
|
{
|
return false;
|
}
|
}
|
else
|
{
|
if (Application.internetReachability != NetworkReachability.ReachableViaCarrierDataNetwork)
|
{
|
return false;
|
}
|
}
|
}
|
|
|
if (!UIManager.Instance.IsOpened<MainWin>())
|
{
|
return false;
|
}
|
|
// if (WindowCenter.Instance.ExistAnyFullScreenOrMaskWin())
|
// {
|
// return false;
|
// }
|
|
return true;
|
}
|
|
public bool IsHighLevelPlayer()
|
{
|
if (GeneralDefine.inGameDownLoadLevelCheckPoints == null
|
|| GeneralDefine.inGameDownLoadLevelCheckPoints.Count == 0)
|
{
|
return false;
|
}
|
|
var level = PlayerDatas.Instance.baseData.LV;
|
return level > GeneralDefine.inGameDownLoadHighLevel;
|
}
|
|
//玩家升级
|
private void OnPlayerLevelChange(PlayerDataType refreshType)
|
{
|
switch (refreshType)
|
{
|
case PlayerDataType.LV:
|
var level = PlayerDatas.Instance.baseData.LV;
|
var count = GeneralDefine.inGameDownLoadLevelCheckPoints.Count;
|
var lastLevelCheckPoint = GeneralDefine.inGameDownLoadLevelCheckPoints[count - 1];
|
if (GeneralDefine.inGameDownLoadLevelCheckPoints.Contains(level) || IsHighLevelPlayer())
|
{
|
if (CheckDominantDownLoad())
|
{
|
TryDownLoad(Dominant.Whole);
|
}
|
}
|
break;
|
}
|
}
|
|
|
//获取最大下载任务数
|
public int GetMaxTask()
|
{
|
if (!LoginWin.firstOpenEnd)
|
return 20;
|
|
if (downLoadGo)
|
return 20;
|
|
switch (Application.platform)
|
{
|
case RuntimePlatform.Android:
|
if (DeviceUtility.cpu >= 4 && DeviceUtility.memory > 3.2f * 1024)
|
{
|
return 2;
|
}
|
else
|
{
|
return 1;
|
}
|
case RuntimePlatform.IPhonePlayer:
|
if (DeviceUtility.cpu > 1 && DeviceUtility.memory > 1.5f * 1024)
|
{
|
return 2;
|
}
|
else
|
{
|
return 1;
|
}
|
case RuntimePlatform.WindowsEditor:
|
return 2;
|
default:
|
return 1;
|
}
|
}
|
|
public struct Reward
|
{
|
public int id;
|
public int count;
|
public bool bind;
|
|
public Reward(string _input)
|
{
|
var matches = Regex.Matches(_input, "\\d+");
|
|
if (matches.Count > 0)
|
{
|
int.TryParse(matches[0].Value, out id);
|
}
|
else
|
{
|
id = 0;
|
}
|
|
if (matches.Count > 1)
|
{
|
int.TryParse(matches[1].Value, out count);
|
}
|
else
|
{
|
count = 0;
|
}
|
|
if (matches.Count > 2)
|
{
|
var temp = 0;
|
int.TryParse(matches[2].Value, out temp);
|
bind = temp == 1;
|
}
|
else
|
{
|
bind = false;
|
}
|
}
|
|
}
|
|
public enum State
|
{
|
None,
|
Prepared,
|
DownLoad,
|
Pause,
|
Award,
|
Completed,
|
}
|
|
public enum Dominant
|
{
|
None = 0,
|
Half = 1,
|
Whole = 2,
|
}
|
|
#region 登录下载界面 DownLoadWin
|
// 增加下载奖励 根据标识决定多次发放;注意不要与游戏内的完整下载混淆
|
// 后续改成appversion_new增加扩展信息返回下载标识,用于控制当前是否显示奖励,此处首包还未包含图片资源
|
|
public int downloadMark = 0;
|
|
public bool IsShowDownloadAward()
|
{
|
int downloadMark = 0;
|
int.TryParse(VersionUtility.Instance.versionInfo.ResourceAward, out downloadMark);
|
var mark = LocalSave.GetInt("downloadMark");
|
return downloadMark > mark;
|
|
}
|
|
//下载完毕成功登录游戏即可设置
|
public void SetDownloadMark()
|
{
|
LocalSave.SetInt("downloadMark", int.Parse(FuncConfigConfig.Get("DownReward").Numerical4));
|
}
|
|
#endregion
|
}
|