This commit is contained in:
1415ddfer 2024-03-07 22:50:28 +08:00
parent f686e2346c
commit dc4233d645
8 changed files with 5 additions and 597 deletions

View File

@ -11,7 +11,7 @@
<TextBlock Text="关&#13;于" Margin="20" FontSize="50" Foreground="OrangeRed"/>
<StackPanel>
<TextBlock x:Name="info" Text=" 铃依登陆器&#13;&#13;The best luancher&#13; Power by DDF" Margin="30,150,30,30" HorizontalAlignment="Center" Foreground="#2e4e7e" FontSize="16"/>
<TextBlock Text="My contact" HorizontalAlignment="Center" Foreground="#FF81EB78"/>
<TextBlock Text="Contact me" HorizontalAlignment="Center" Foreground="#FF81EB78"/>
<TextBlock HorizontalAlignment="Center">
<Hyperlink NavigateUri="https://github.com/1415ddfer/ZeroHelper" Click="Hyperlink_Click">
My GitHub

View File

@ -1,5 +1,4 @@
using Lierda.WPFHelper;
using System.Windows;
using System.Windows;
using Zerolauncher.Manager;
namespace Zerolauncher
@ -9,11 +8,8 @@ namespace Zerolauncher
/// </summary>
public partial class App : Application
{
LierdaCracker cracker = new LierdaCracker();
protected override void OnStartup(StartupEventArgs e)
{
cracker.Cracker(100);//垃圾回收间隔时间
base.OnStartup(e);
_ = UpDateManager.TakeQMessage();
DataStream.Load();

View File

@ -1,374 +0,0 @@
using System.Net;
using System.IO;
namespace Zerolauncher.Manager
{
public class DownloadManager
{
/// <summary>
/// 主线程
/// </summary>
private SynchronizationContext _mainThreadSynContext;
/// <summary>
/// 下载网址
/// </summary>
public string Url;
public event Action<Exception> OnError;
private static object errorlock = new object();
/// <summary>
/// 主要用于关闭线程
/// </summary>
private bool _isDownload = false;
public DownloadManager(string url)
{
// 主线程赋值
_mainThreadSynContext = SynchronizationContext.Current;
// 突破Http协议的并发连接数限制
ServicePointManager.DefaultConnectionLimit = 512;
Url = url;
}
/// <summary>
/// 查询文件大小
/// </summary>
/// <returns></returns>
public long GetFileSize()
{
HttpWebRequest request;
HttpWebResponse response;
try
{
request = (HttpWebRequest)WebRequest.CreateHttp(new Uri(Url));
request.Method = "HEAD";
response = (HttpWebResponse)request.GetResponse();
// 获得文件长度
long contentLength = response.ContentLength;
response.Close();
request.Abort();
return contentLength;
}
catch (Exception ex)
{
onError(ex);
// throw;
return -1;
}
}
/// <summary>
/// 异步查询文件大小
/// </summary>
/// <param name="onTrigger"></param>
public void GetFileSizeAsyn(Action<long> onTrigger = null)
{
ThreadStart threadStart = new ThreadStart(() =>
{
PostMainThreadAction<long>(onTrigger, GetFileSize());
});
Thread thread = new Thread(threadStart);
thread.Start();
}
/// <summary>
/// 多线程下载文件至本地
/// </summary>
/// <param name="threadCount">线程总数</param>
/// <param name="filePath">保存文件路径</param>
/// <param name="onDownloading">下载过程回调(已下载文件大小、总文件大小)</param>
/// <param name="onTrigger">下载完毕回调(下载文件数据)</param>
public void DownloadToFile(int threadCount, string filePath, Action<long, long> onDownloading = null, Action<byte[]> onTrigger = null)
{
_isDownload = true;
long csize = 0; //已下载大小
int ocnt = 0; //完成线程数
// 下载逻辑
GetFileSizeAsyn((size) =>
{
if (size == -1) return;
// 准备工作
var tempFilePaths = new string[threadCount];
var tempFileFileStreams = new FileStream[threadCount];
var dirPath = Path.GetDirectoryName(filePath);
var fileName = Path.GetFileName(filePath);
// 下载根目录不存在则创建
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
// 查看下载临时文件是否可以继续断点续传
var fileInfos = new DirectoryInfo(dirPath).GetFiles(fileName + "*.temp");
if (fileInfos.Length != threadCount)
{
// 下载临时文件数量不相同,则清理
foreach (var info in fileInfos)
{
info.Delete();
}
}
// 创建下载临时文件,并创建文件流
for (int i = 0; i < threadCount; i++)
{
tempFilePaths[i] = filePath + i + ".temp";
if (!File.Exists(tempFilePaths[i]))
{
File.Create(tempFilePaths[i]).Dispose();
}
tempFileFileStreams[i] = File.OpenWrite(tempFilePaths[i]);
tempFileFileStreams[i].Seek(tempFileFileStreams[i].Length, System.IO.SeekOrigin.Current);
csize += tempFileFileStreams[i].Length;
}
// 单线程下载过程回调函数
Action<int, long, byte[], byte[]> t_onDownloading = (index, rsize, rbytes, data) =>
{
csize += rsize;
tempFileFileStreams[index].Write(rbytes, 0, (int)rsize);
PostMainThreadAction<long, long>(onDownloading, csize, size);
};
// 单线程下载完毕回调函数
Action<int, byte[]> t_onTrigger = (index, data) =>
{
// 关闭文件流
tempFileFileStreams[index].Close();
ocnt++;
if (ocnt >= threadCount)
{
// 将临时文件转为下载文件
if (!File.Exists(filePath))
{
File.Create(filePath).Dispose();
}
else
{
File.WriteAllBytes(filePath, new byte[] { });
}
FileStream fs = File.OpenWrite(filePath);
fs.Seek(fs.Length, System.IO.SeekOrigin.Current);
foreach (var tempPath in tempFilePaths)
{
var tempData = File.ReadAllBytes(tempPath);
fs.Write(tempData, 0, tempData.Length);
File.Delete(tempPath);
}
fs.Close();
PostMainThreadAction<byte[]>(onTrigger, File.ReadAllBytes(filePath));
}
};
// 分割文件尺寸,多线程下载
long[] sizes = SplitFileSize(size, threadCount);
for (int i = 0; i < sizes.Length; i = i + 2)
{
long from = sizes[i];
long to = sizes[i + 1];
// 断点续传
from += tempFileFileStreams[i / 2].Length;
if (from >= to)
{
t_onTrigger(i / 2, null);
continue;
}
_threadDownload(i / 2, from, to, t_onDownloading, t_onTrigger);
}
});
}
/// <summary>
/// 多线程下载文件至内存
/// </summary>
/// <param name="threadCount">线程总数</param>
/// <param name="onDownloading">下载过程回调(已下载文件大小、总文件大小)</param>
/// <param name="onTrigger">下载完毕回调(下载文件数据)</param>
public void DownloadToMemory(int threadCount, Action<long, long> onDownloading = null, Action<byte[]> onTrigger = null)
{
_isDownload = true;
long csize = 0; // 已下载大小
int ocnt = 0; // 完成线程数
byte[] cdata; // 已下载数据
// 下载逻辑
GetFileSizeAsyn((size) =>
{
cdata = new byte[size];
// 单线程下载过程回调函数
Action<int, long, byte[], byte[]> t_onDownloading = (index, rsize, rbytes, data) =>
{
csize += rsize;
PostMainThreadAction<long, long>(onDownloading, csize, size);
};
// 单线程下载完毕回调函数
Action<int, byte[]> t_onTrigger = (index, data) =>
{
long dIndex = (long)Math.Ceiling((double)(size * index / threadCount));
Array.Copy(data, 0, cdata, dIndex, data.Length);
ocnt++;
if (ocnt >= threadCount)
{
PostMainThreadAction<byte[]>(onTrigger, cdata);
}
};
// 分割文件尺寸,多线程下载
long[] sizes = SplitFileSize(size, threadCount);
for (int i = 0; i < sizes.Length; i = i + 2)
{
long from = sizes[i];
long to = sizes[i + 1];
_threadDownload(i / 2, from, to, t_onDownloading, t_onTrigger);
}
});
}
/// <summary>
/// 单线程下载
/// </summary>
/// <param name="index">线程ID</param>
/// <param name="from">下载起始位置</param>
/// <param name="to">下载结束位置</param>
/// <param name="onDownloading">下载过程回调线程ID、单次下载数据大小、单次下载数据缓存区、已下载文件数据</param>
/// <param name="onTrigger">下载完毕回调线程ID、下载文件数据</param>
private void _threadDownload(int index, long from, long to, Action<int, long, byte[], byte[]> onDownloading = null, Action<int, byte[]> onTrigger = null)
{
Thread thread = new Thread(new ThreadStart(() =>
{
try
{
var request = (HttpWebRequest)WebRequest.Create(new Uri(Url));
request.AddRange(from, to);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream ns = response.GetResponseStream();
byte[] rbytes = new byte[8 * 1024];
int rSize = 0;
MemoryStream ms = new MemoryStream();
while (true)
{
if (!_isDownload) return;
rSize = ns.Read(rbytes, 0, rbytes.Length);
if (rSize <= 0) break;
ms.Write(rbytes, 0, rSize);
if (onDownloading != null) onDownloading(index, rSize, rbytes, ms.ToArray());
}
ns.Close();
response.Close();
request.Abort();
if (ms.Length == (to - from) + 1)
{
if (onTrigger != null) onTrigger(index, ms.ToArray());
}
else
{
lock (errorlock)
{
if (_isDownload)
{
onError(new Exception("文件大小校验不通过"));
}
}
}
}
catch (Exception ex)
{
onError(ex);
}
}));
thread.Start();
}
public void Close()
{
_isDownload = false;
}
/// <summary>
/// 分割文件大小
/// </summary>
/// <returns></returns>
private long[] SplitFileSize(long size, int count)
{
long[] result = new long[count * 2];
for (int i = 0; i < count; i++)
{
long from = (long)Math.Ceiling((double)(size * i / count));
long to = (long)Math.Ceiling((double)(size * (i + 1) / count)) - 1;
result[i * 2] = from;
result[i * 2 + 1] = to;
}
return result;
}
private void onError(Exception ex)
{
Close();
PostMainThreadAction<Exception>(OnError, ex);
}
/// <summary>
/// 通知主线程回调
/// </summary>
private void PostMainThreadAction(Action action)
{
_mainThreadSynContext.Post(new SendOrPostCallback((o) =>
{
Action e = (Action)o.GetType().GetProperty("action").GetValue(o);
if (e != null) e();
}), new { action = action });
}
private void PostMainThreadAction<T>(Action<T> action, T arg1)
{
_mainThreadSynContext.Post(new SendOrPostCallback((o) =>
{
Action<T> e = (Action<T>)o.GetType().GetProperty("action").GetValue(o);
T t1 = (T)o.GetType().GetProperty("arg1").GetValue(o);
if (e != null) e(t1);
}), new { action = action, arg1 = arg1 });
}
public void PostMainThreadAction<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
{
_mainThreadSynContext.Post(new SendOrPostCallback((o) =>
{
Action<T1, T2> e = (Action<T1, T2>)o.GetType().GetProperty("action").GetValue(o);
T1 t1 = (T1)o.GetType().GetProperty("arg1").GetValue(o);
T2 t2 = (T2)o.GetType().GetProperty("arg2").GetValue(o);
if (e != null) e(t1, t2);
}), new { action = action, arg1 = arg1, arg2 = arg2 });
}
public void PostMainThreadAction<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
{
_mainThreadSynContext.Post(new SendOrPostCallback((o) =>
{
Action<T1, T2, T3> e = (Action<T1, T2, T3>)o.GetType().GetProperty("action").GetValue(o);
T1 t1 = (T1)o.GetType().GetProperty("arg1").GetValue(o);
T2 t2 = (T2)o.GetType().GetProperty("arg2").GetValue(o);
T3 t3 = (T3)o.GetType().GetProperty("arg3").GetValue(o);
if (e != null) e(t1, t2, t3);
}), new { action = action, arg1 = arg1, arg2 = arg2, arg3 = arg3 });
}
public void PostMainThreadAction<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
_mainThreadSynContext.Post(new SendOrPostCallback((o) =>
{
Action<T1, T2, T3, T4> e = (Action<T1, T2, T3, T4>)o.GetType().GetProperty("action").GetValue(o);
T1 t1 = (T1)o.GetType().GetProperty("arg1").GetValue(o);
T2 t2 = (T2)o.GetType().GetProperty("arg2").GetValue(o);
T3 t3 = (T3)o.GetType().GetProperty("arg3").GetValue(o);
T4 t4 = (T4)o.GetType().GetProperty("arg4").GetValue(o);
if (e != null) e(t1, t2, t3, t4);
}), new { action = action, arg1 = arg1, arg2 = arg2, arg3 = arg3, arg4 = arg4 });
}
}
}

View File

@ -49,11 +49,7 @@ namespace Zerolauncher.Manager
public static bool CreateGame(int memberId)
{
var account = AccountManager.accountsList[memberId];
var key = AccToKey(account);
if (mGame.ContainsKey(key)) { return false; }
mGame[key] = new SingleGame(account);
return true;
return CreateGame(AccountManager.accountsList[memberId]);
}
public static int CheckGameState(Account account)
@ -210,7 +206,7 @@ namespace Zerolauncher.Manager
const string engine_file = @"ZeroEngine.exe";
public static Process CheckEngineSafe()
{
if (is_check && EngineManager.CheckEmpy())
if (!is_check && EngineManager.CheckEmpy())
{
string? now_bit;
using (SHA256 sha256 = SHA256.Create())

View File

@ -1,201 +0,0 @@
using System.Text;
namespace Zerolauncher.Manager
{
/// <summary>
/// 提供用于计算指定文件哈希值的方法
/// <example>例如计算文件的MD5值:
/// <code>
/// String hashMd5=HashHelper.ComputeMD5("MyFile.txt");
/// </code>
/// </example>
/// <example>例如计算文件的CRC32值:
/// <code>
/// String hashCrc32 = HashHelper.ComputeCRC32("MyFile.txt");
/// </code>
/// </example>
/// <example>例如计算文件的SHA1值:
/// <code>
/// String hashSha1 =HashHelper.ComputeSHA1("MyFile.txt");
/// </code>
/// </example>
/// </summary>
public sealed class HashHelper
{
/// <summary>
/// 计算指定文件的MD5值
/// </summary>
/// <param name="fileName">指定文件的完全限定名称</param>
/// <returns>返回值的字符串形式</returns>
public static String ComputeMD5(String fileName)
{
String hashMD5 = String.Empty;
//检查文件是否存在,如果文件存在则进行计算,否则返回空值
if (System.IO.File.Exists(fileName))
{
using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
//计算文件的MD5值
System.Security.Cryptography.MD5 calculator = System.Security.Cryptography.MD5.Create();
Byte[] buffer = calculator.ComputeHash(fs);
calculator.Clear();
//将字节数组转换成十六进制的字符串形式
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
{
stringBuilder.Append(buffer[i].ToString("x2"));
}
hashMD5 = stringBuilder.ToString();
}//关闭文件流
}//结束计算
return hashMD5;
}//ComputeMD5
/// <summary>
/// 计算指定文件的CRC32值
/// </summary>
/// <param name="fileName">指定文件的完全限定名称</param>
/// <returns>返回值的字符串形式</returns>
public static String ComputeCRC32(String fileName)
{
String hashCRC32 = String.Empty;
//检查文件是否存在,如果文件存在则进行计算,否则返回空值
if (System.IO.File.Exists(fileName))
{
using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
//计算文件的CSC32值
Crc32 calculator = new Crc32();
Byte[] buffer = calculator.ComputeHash(fs);
calculator.Clear();
//将字节数组转换成十六进制的字符串形式
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
{
stringBuilder.Append(buffer[i].ToString("x2"));
}
hashCRC32 = stringBuilder.ToString();
}//关闭文件流
}
return hashCRC32;
}//ComputeCRC32
/// <summary>
/// 计算指定文件的SHA1值
/// </summary>
/// <param name="fileName">指定文件的完全限定名称</param>
/// <returns>返回值的字符串形式</returns>
public static String ComputeSHA1(String fileName)
{
String hashSHA1 = String.Empty;
//检查文件是否存在,如果文件存在则进行计算,否则返回空值
if (System.IO.File.Exists(fileName))
{
using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
//计算文件的SHA1值
System.Security.Cryptography.SHA1 calculator = System.Security.Cryptography.SHA1.Create();
Byte[] buffer = calculator.ComputeHash(fs);
calculator.Clear();
//将字节数组转换成十六进制的字符串形式
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
{
stringBuilder.Append(buffer[i].ToString("x2"));
}
hashSHA1 = stringBuilder.ToString();
}//关闭文件流
}
return hashSHA1;
}//ComputeSHA1
}//end class: HashHelper
/// <summary>
/// 提供 CRC32 算法的实现
/// </summary>
public class Crc32 : System.Security.Cryptography.HashAlgorithm
{
public const UInt32 DefaultPolynomial = 0xedb88320;
public const UInt32 DefaultSeed = 0xffffffff;
private UInt32 hash;
private UInt32 seed;
private UInt32[] table;
private static UInt32[] defaultTable;
public Crc32()
{
table = InitializeTable(DefaultPolynomial);
seed = DefaultSeed;
Initialize();
}
public Crc32(UInt32 polynomial, UInt32 seed)
{
table = InitializeTable(polynomial);
this.seed = seed;
Initialize();
}
public override void Initialize()
{
hash = seed;
}
protected override void HashCore(byte[] buffer, int start, int length)
{
hash = CalculateHash(table, hash, buffer, start, length);
}
protected override byte[] HashFinal()
{
byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);
this.HashValue = hashBuffer;
return hashBuffer;
}
public static UInt32 Compute(byte[] buffer)
{
return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
}
public static UInt32 Compute(UInt32 seed, byte[] buffer)
{
return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
}
public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
{
return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
}
private static UInt32[] InitializeTable(UInt32 polynomial)
{
if (polynomial == DefaultPolynomial && defaultTable != null)
{
return defaultTable;
}
UInt32[] createTable = new UInt32[256];
for (int i = 0; i < 256; i++)
{
UInt32 entry = (UInt32)i;
for (int j = 0; j < 8; j++)
{
if ((entry & 1) == 1)
entry = (entry >> 1) ^ polynomial;
else
entry = entry >> 1;
}
createTable[i] = entry;
}
if (polynomial == DefaultPolynomial)
{
defaultTable = createTable;
}
return createTable;
}
private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
{
UInt32 crc = seed;
for (int i = start; i < size; i++)
{
unchecked
{
crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
}
}
return crc;
}
private byte[] UInt32ToBigEndianBytes(UInt32 x)
{
return new byte[] { (byte)((x >> 24) & 0xff), (byte)((x >> 16) & 0xff), (byte)((x >> 8) & 0xff), (byte)(x & 0xff) };
}
}//end class: Crc32
}

View File

@ -19,7 +19,7 @@ namespace Zerolauncher.Manager
try
{
client.Timeout = TimeSpan.FromMinutes(3);
response = await client.GetAsync($"https://sharechain.qq.com/13111bbd6ffbffa3057878431bef103e");
response = await client.GetAsync("https://sharechain.qq.com/037846c482eddc948612b0d0f8ed98d5"); // 初夏
}catch (Exception _ex)
{
EngineCacheSha.errorCode = 1;

View File

@ -1,8 +0,0 @@
namespace Zerolauncher.Manager
{
class VersionManager
{
public static int GetMainVer() { return 10001; }
}
}

View File

@ -37,7 +37,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Lierda.WPFHelper" Version="1.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>