diff --git a/XFP.Impact_Ultimate/XFP.Cora/App.config b/XFP.Impact_Ultimate/XFP.Cora/App.config
new file mode 100644
index 0000000..910fa6f
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/App.config
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/App.xaml b/XFP.Impact_Ultimate/XFP.Cora/App.xaml
new file mode 100644
index 0000000..0b7dc49
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/App.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/App.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/App.xaml.cs
new file mode 100644
index 0000000..31b8a60
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/App.xaml.cs
@@ -0,0 +1,9 @@
+namespace XFP.ICora
+{
+ ///
+ /// App.xaml 的交互逻辑
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/AboutUs.xaml b/XFP.Impact_Ultimate/XFP.Cora/Controls/AboutUs.xaml
new file mode 100644
index 0000000..582360b
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/AboutUs.xaml
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+
+
+
+
+
+ · 访问我们的官网(推荐!)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/AboutUs.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/AboutUs.xaml.cs
new file mode 100644
index 0000000..e62a242
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/AboutUs.xaml.cs
@@ -0,0 +1,69 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Controls
+{
+ ///
+ /// AboutUs.xaml 的交互逻辑
+ ///
+ public partial class AboutUs : UserControl
+ {
+ public AboutUs()
+ {
+ InitializeComponent();
+ }
+
+ private void GetICora_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://gitee.com/XFP-Group/Impact_Ultimate/");
+ }
+
+ private void GetICora_Github_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://github.com/GashByte/ICora");
+ }
+
+ private void ContentUs_Click(object sender, RoutedEventArgs e)
+ {
+ Growl.Info("加入群聊获取资讯!群聊QQ号已经被复制到粘贴板上咯");
+ Clipboard.SetDataObject("811979687");
+ }
+
+ private void PrivacyPolicy_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://gitee.com/MasterGashByte/impact_ultimate_issues/blob/master/PrivacyPolicy.md");
+ }
+
+ private void UserUseAgreement_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://gitee.com/MasterGashByte/impact_ultimate_issues/blob/master/UserUseAgreement.md");
+ }
+
+ private void FeedBackQ_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://gitee.com/MasterGashByte/impact_ultimate_issues/issues");
+ }
+
+ private void ICoraIndex_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://gashbyte.github.io/ICoraIndex/");
+ }
+
+ private void afadian_Click(object sender, RoutedEventArgs e)
+ {
+ Growl.Clear();
+ Growl.Success("唔噜!UwU!");
+ Process.Start("explorer.exe", "https://afdian.net/a/XFP-Group");
+ }
+
+ private void GithubLink_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://github.com/GashByte/ICora");
+ }
+
+ private void VisitWebsite_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", "https://gashbyte.github.io/ICoraIndex/");
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/AkebiPage.xaml b/XFP.Impact_Ultimate/XFP.Cora/Controls/AkebiPage.xaml
new file mode 100644
index 0000000..41cf0e0
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/AkebiPage.xaml
@@ -0,0 +1,551 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/AkebiPage.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/AkebiPage.xaml.cs
new file mode 100644
index 0000000..f92f2fd
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/AkebiPage.xaml.cs
@@ -0,0 +1,1300 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Controls
+{
+ ///
+ /// Binding DataList
+ ///
+ public class LocalDataList
+ {
+ #region Bindings
+
+ public string Name { get; set; }
+
+ #endregion
+ }
+
+ ///
+ /// AkebiPage.xaml 的交互逻辑
+ ///
+
+ public partial class AkebiPage
+ {
+ #region Initializtion
+ KeySetter key = new();
+ LogWriter log = new();
+ INIFiles ini = new();
+
+ public ObservableCollection UDataList { get; } = new ObservableCollection();
+ #endregion
+
+ #region define
+ private string CLPath = Environment.CurrentDirectory + "\\ICora\\CLibrary.dll";
+ private string AkebiPath = Environment.CurrentDirectory + "\\ICora";
+ private string UserData = Environment.CurrentDirectory + "\\UserData";
+ private string GenshinServiceDir = Environment.CurrentDirectory + "\\GenshinService";
+
+ private bool InAdd = false;
+ private bool InModify = false;
+ #endregion
+
+ #region Main Method
+
+ ///
+ /// 构建开始游戏页面
+ ///
+ public AkebiPage()
+ {
+ InitializeComponent();
+
+ #region 文件夹判断
+ if (!Directory.Exists(AkebiPath))
+ Directory.CreateDirectory(AkebiPath);
+ if (!Directory.Exists(UserData))
+ Directory.CreateDirectory(UserData);
+ #endregion
+ // 服务器选择的List
+ List GenshinService = new List
+ {
+ "官方服 | 天空岛",
+ "渠道服 | 世界树",
+ "国际服 | Global"
+ };
+
+ if (!Directory.Exists(AkebiPath))
+ {
+ Directory.CreateDirectory(AkebiPath);
+ }
+
+ UChooseService.ItemsSource = GenshinService;
+ UChooseAccount.ItemsSource = UDataList;
+
+ RefreshList();
+ #region 基础设置
+ try
+ {
+ #region 读取配置文件
+ UGenshinImpactPath.Text = key.gk("Genshin Impact Path") == string.Empty ? "没有找到你的原神" : key.gk("Genshin Impact Path");
+ UChooseDll.Text = key.gk("UChooseDll") == string.Empty ? "默认路径" : key.gk("UChooseDll");
+ if (UGenshinImpactPath.Text == string.Empty)
+ {
+ UGenshinImpactPath.Text = "没有找到你的原神路径";
+ }
+ if (UChooseDll.Text == string.Empty)
+ {
+ UChooseDll.Text = "默认路径";
+ }
+ UScreenWidth.Text = key.gk("Screen Width");
+ UScreenHeight.Text = key.gk("Screen Height");
+ UChooseAccount.SelectedItem = key.gk("Account");
+ UAccountChange.Text = UChooseAccount.Text;
+
+ if (key.gk("Start Game Model") == "注入DLL")
+ {
+ UGameStartModel.Text = "注入DLL";
+ UStartModel.Content = "注入DLL";
+ UChooseDllPath.IsEnabled = true;
+ UChooseDll.Opacity = 1;
+ }
+ else
+ {
+ UGameStartModel.Text = "默认模式";
+ UStartModel.Content = "默认模式";
+ UChooseDllPath.IsEnabled = false;
+ UChooseDll.Opacity = 0.5;
+ }
+
+ if (key.gk("Mult Start") == "True")
+ MultStart.Content = "已启用";
+ else
+ MultStart.Content = "启用";
+
+ if (key.gk("Is Full Screen") == "True")
+ UIsFullScreen.Content = "已启用";
+ else
+ UIsFullScreen.Content = "启用";
+
+ if (key.gk("Border less") == "True")
+ UBorderless.Content = "已启用";
+ else
+ UBorderless.Content = "启用";
+
+ if (key.gk("Check CLibrary") == "True")
+ CheckCL.Content = "已启用";
+ else
+ CheckCL.Content = "启用";
+ #endregion
+
+ #region 服务器判定
+ if (UGenshinImpactPath.Text != string.Empty)
+ {
+ if (File.Exists(UGenshinImpactPath.Text))
+ {
+ string GenshinName = Path.GetFileName(UGenshinImpactPath.Text);
+ if (GenshinName == "YuanShen.exe")
+ {
+ DirectoryInfo info = new DirectoryInfo(UGenshinImpactPath.Text);
+ string YuanShenDir = info.Parent.FullName;
+ string YuanShenChannel = ini.INIRead("General", "channel", YuanShenDir + "\\config.ini");
+ UGameService.Text = YuanShenChannel == "1" ? "当前服务器:官方服 | 天空岛"
+ : YuanShenChannel == "14" ? "当前服务器:渠道服 | 世界树"
+ : string.Empty;
+ }
+ else if (GenshinName == "GenshinImpact.exe")
+ {
+ UGameService.Text = "当前服务器:国际服 | Global";
+ }
+ else
+ {
+ UGameService.Text = "当前服务器:出错了捏?!";
+ }
+ }
+ }
+ else
+ {
+ UGameService.Text = "当前服务器:没有获取到当前服务器";
+ }
+
+ #region 选择判断
+ UChooseService.SelectedItem = UGameService.Text == "当前服务器:官方服 | 天空岛" ? "官方服 | 天空岛"
+ : UGameService.Text == "当前服务器:国际服 | Global" ? "国际服 | Global"
+ : UGameService.Text == "当前服务器:渠道服 | 世界树" ? "渠道服 | 世界树"
+ : UChooseService.SelectedItem = null;
+ #endregion
+ #endregion
+ }
+ catch { }
+ #endregion
+ }
+
+ #endregion
+
+ #region Normal Method
+
+ ///
+ /// 判断程序是否是以管理员身份运行。
+ ///
+ public bool IsRunAsAdmin()
+ {
+ WindowsIdentity id = WindowsIdentity.GetCurrent();
+ WindowsPrincipal principal = new WindowsPrincipal(id);
+ return principal.IsInRole(WindowsBuiltInRole.Administrator);
+ }
+
+ ///
+ /// 刷新List
+ ///
+ private void RefreshList()
+ {
+ UDataList.Clear();
+ DirectoryInfo root = new DirectoryInfo(UserData);
+ FileInfo[] files = root.GetFiles();
+ foreach (FileInfo file in files)
+ {
+ UDataList.Add(new LocalDataList()
+ {
+ Name = file.Name
+ });
+ }
+
+ if (UChooseAccount.Items.Count > 0)
+ {
+ DelAccount.IsEnabled = true;
+ ModifyAccount.IsEnabled = true;
+ splitButton.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ DelAccount.IsEnabled = false;
+ ModifyAccount.IsEnabled = false;
+ splitButton.Visibility = Visibility.Hidden;
+ }
+ }
+
+ ///
+ /// 切换账户
+ ///
+ private void Switch()
+ {
+ Thread.Sleep(100);
+ YSAccount acct = YSAccount.ReadFromDisk(UChooseAccount.Text);
+ acct.WriteToRegedit();
+
+ key.sk("Account", UChooseAccount.Text);
+ UAccountChange.Text = UChooseAccount.Text;
+
+ Growl.Clear();
+ Growl.Success($"切换成功 当前账户:{UChooseAccount.Text}");
+ }
+
+ ///
+ /// 启动游戏
+ ///
+ public void StartGame()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(UGenshinImpactPath.Text))
+ {
+ Growl.Clear();
+ Growl.Error("您的原神路径是空的");
+ }
+ else
+ {
+ if (YuanShenIsRunning() && MultStart.Content.ToString() == "启用")
+ {
+ Growl.Clear();
+ Growl.Error("原神已经启动 请关闭后再试");
+ return;
+ }
+ try
+ {
+ bool TokenRet = DllUtils.OpenProcessToken(DllUtils.GetCurrentProcess(), 0xF00FF, out IntPtr hToken);
+ var si = new DllUtils.STARTUPINFOEX();
+ si.StartupInfo.cb = Marshal.SizeOf(si);
+ if (hToken == IntPtr.Zero)
+ {
+ Growl.Clear();
+ Growl.Warning("提权失败 正常启动");
+ StartGameNormal();
+ return;
+ }
+ var pExporer = Process.GetProcessesByName("explorer")[0];
+ if (pExporer == null)
+ {
+ Growl.Clear();
+ Growl.Warning("Explorer未找到 正常启动");
+ StartGameNormal();
+ return;
+ }
+ IntPtr handle = DllUtils.OpenProcess(0xF0000 | 0x100000 | 0xFFFF, false, (uint)pExporer.Id);
+ var lpSize = IntPtr.Zero;
+ DllUtils.InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
+ si.lpAttributeList = Marshal.AllocHGlobal(lpSize);
+ DllUtils.InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, ref lpSize);
+ if (DllUtils.UpdateProcThreadAttribute(si.lpAttributeList, 0, 0x00020004, handle, IntPtr.Size, IntPtr.Zero, IntPtr.Zero))
+ {
+ Growl.Clear();
+ Growl.Error("更新线程失败");
+ }
+ DirectoryInfo path = new DirectoryInfo(UGenshinImpactPath.Text);
+ var pi = new DllUtils.PROCESS_INFORMATION();
+
+ string args = null;
+ if (key.gk("Is Full Screen") == "True")
+ {
+ args += new CommandLineBuilder()
+ .AppendIf("-screen-fullscreen", true)
+ .ToString();
+ }
+ if (key.gk("Border less") == "True")
+ {
+ args += new CommandLineBuilder()
+ .AppendIf("-popupwindow", true)
+ .ToString();
+ }
+ args += new CommandLineBuilder()
+ .Append("-screen-height", UScreenHeight.Text.ToString())
+ .Append("-screen-width", UScreenWidth.Text.ToString())
+ .ToString();
+ var result = DllUtils.CreateProcessAsUser(hToken, Path.Combine(UGenshinImpactPath.Text).ToString(),
+ RunParameters.Text == string.Empty ? args : RunParameters.Text, IntPtr.Zero, IntPtr.Zero, false, 0x00080000 | 0x00000004,
+ IntPtr.Zero, Path.Combine(path.Parent.Parent.FullName, "Genshin Impact Game").ToString(), ref si.StartupInfo, out pi);
+ if (!result)
+ {
+ Growl.Clear();
+ Growl.Warning("启动暂停线程失败 正常启动");
+ StartGameNormal();
+ return;
+ }
+ DllUtils.DeleteProcThreadAttributeList(si.lpAttributeList);
+ new Thread(() =>
+ {
+ InjectDll(pi.hProcess);
+ Thread.Sleep(2000);
+ DllUtils.ResumeThread(pi.hThread);
+ DllUtils.CloseHandle(pi.hProcess);
+ }).Start();
+ Growl.Clear();
+ Growl.Success("启动成功 祝你游玩愉快!\nDll注入暂时不支持统计游玩时间 我找不到方法统计它");
+ }
+ catch
+ {
+
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error("在启动发现了异常:" + ex.Message);
+ }
+ }
+
+ ///
+ /// 正常启动游戏
+ ///
+ private void StartGameNormal()
+ {
+ Stopwatch sw = new();
+ string args = "";
+ ProcessStartInfo startInfo = new();
+ startInfo.UseShellExecute = true;
+ startInfo.WorkingDirectory = Environment.CurrentDirectory;
+ startInfo.FileName = Path.Combine(UGenshinImpactPath.Text);
+ startInfo.Verb = "RunAs";
+ if (key.gk("Is Full Screen") == "False"
+ && key.gk("Border less") == "False")
+ {
+ args = new CommandLineBuilder()
+ .Append("-screen-height", UScreenHeight.Text.ToString())
+ .Append("-screen-width", UScreenWidth.Text.ToString())
+ .ToString();
+ startInfo.Arguments = RunParameters.Text + args;
+ }
+ else
+ {
+ if (key.gk("Is Full Screen") == "True")
+ {
+ args += new CommandLineBuilder()
+ .AppendIf("-screen-fullscreen", true)
+ .ToString();
+ }
+ if (key.gk("Border less") == "True")
+ {
+ args += new CommandLineBuilder()
+ .AppendIf("-popupwindow", true)
+ .ToString();
+ }
+ args += new CommandLineBuilder()
+ .Append("-screen-height", UScreenHeight.Text.ToString())
+ .Append("-screen-width", UScreenWidth.Text.ToString())
+ .ToString();
+ startInfo.Arguments = args;
+ }
+
+ new Thread(() =>
+ {
+ sw.Start();
+ Process GenshinProc = Process.Start(startInfo);
+
+ GenshinProc.EnableRaisingEvents = true;
+ GenshinProc.Exited += (sender, e) =>
+ {
+ sw.Stop();
+ TimeSpan ts = sw.Elapsed;
+ Growl.Clear();
+ Growl.Success($"游戏结束了 您游玩了: {ts.Hours}小时," +
+ $" {ts.Minutes}分钟, {ts.Seconds}秒\n希望它是一段美妙的路途");
+
+ };
+ }).Start();
+ }
+
+ ///
+ /// 使用Exe启动游戏
+ ///
+ private void StartGameFormExe()
+ {
+ Stopwatch sw = new();
+ ProcessStartInfo startInfo = new();
+ startInfo.UseShellExecute = true;
+ startInfo.WorkingDirectory = Environment.CurrentDirectory;
+ startInfo.FileName = Path.Combine(UChooseDll.Text);
+ startInfo.Verb = "runas";
+ new Thread(() =>
+ {
+ sw.Start();
+ Process GenshinProc = Process.Start(startInfo);
+
+ GenshinProc.EnableRaisingEvents = true;
+ GenshinProc.Exited += (sender, e) =>
+ {
+ sw.Stop();
+ TimeSpan ts = sw.Elapsed;
+ Growl.Clear();
+ Growl.Success($"游戏结束了 您游玩了: {ts.Hours}小时," +
+ $" {ts.Minutes}分钟, {ts.Seconds}秒\n希望它是一段美妙的路途");
+
+ };
+ }).Start();
+ }
+
+ ///
+ /// 判断原神是否启动
+ ///
+ /// True:已启动 False:未启动
+ private bool YuanShenIsRunning()
+ {
+ var pros = Process.GetProcessesByName("YuanShen");
+ if (pros.Any())
+ {
+ return true;
+ }
+ else
+ {
+ pros = Process.GetProcessesByName("GenshinImpact");
+ return pros.Any();
+ }
+ }
+
+ ///
+ /// DLL注入
+ ///
+ ///
+ ///
+ private bool InjectDll(IntPtr hProc)
+ {
+ IntPtr hKernel = DllUtils.GetModuleHandle("kernel32.dll");
+ if (hKernel == IntPtr.Zero)
+ {
+ MessageBox.Show("kernel32.dll模块地址寻找失败");
+ return false;
+ }
+ IntPtr pLoadLibrary = DllUtils.GetProcAddress(hKernel, "LoadLibraryA");
+ if (pLoadLibrary == IntPtr.Zero)
+ {
+ MessageBox.Show("LoadLibraryA地址获取失败");
+ return false;
+ }
+ IntPtr pDllPath = DllUtils.VirtualAllocEx(hProc, IntPtr.Zero,
+ (uint)((CLPath.Length + 1) * Marshal.SizeOf(typeof(char))), 0x1000 | 0x2000, 0x4);
+ if (pDllPath == IntPtr.Zero)
+ {
+ MessageBox.Show(string.Format("申请内存地址失败(VirtualArrocEx Failed!) : {0}", Marshal.GetLastWin32Error()));
+ return false;
+ }
+ bool writeResult = DllUtils.WriteProcessMemory(hProc, pDllPath,
+ Encoding.Default.GetBytes(CLPath), (uint)((CLPath.Length + 1) * Marshal.SizeOf(typeof(char))), out _);
+ if (!writeResult)
+ {
+ MessageBox.Show(string.Format("写进程内存失败(Wtire Process Memory Failed!) : {0}", DllUtils.GetLastError()));
+ return false;
+ }
+ IntPtr hThread = DllUtils.CreateRemoteThread(hProc, IntPtr.Zero, 0, pLoadLibrary, pDllPath, 0, IntPtr.Zero);
+ if (hThread == IntPtr.Zero)
+ {
+ MessageBox.Show(string.Format("创建远程线程失败(Create Remote Thread Failed!) : {0}", Marshal.GetLastWin32Error()));
+ DllUtils.VirtualFreeEx(hProc, pDllPath, 0, 0x8000);
+ return false;
+ }
+ if (DllUtils.WaitForSingleObject(hThread, 2000) == IntPtr.Zero)
+ {
+ DllUtils.VirtualFreeEx(hProc, pDllPath, 0, 0x8000);
+ }
+ DllUtils.CloseHandle(hThread);
+ return true;
+ }
+
+ ///
+ /// CL下载
+ ///
+ private void CLDownloader(bool UseCLDownloader)
+ {
+ if (UChooseDll.Text != "默认路径")
+ {
+ Growl.Clear();
+ Growl.Warning("暂时无法获取你的Dll信息");
+ return;
+ }
+ if (UseCLDownloader)
+ {
+ var localpath = Environment.CurrentDirectory;
+ if (File.Exists(localpath + "\\CLDownloader.exe")
+ && File.Exists(localpath + "\\CLDownloader.deps.json")
+ && File.Exists(localpath + "\\CLDownloader.dll")
+ && File.Exists(localpath + "\\CLDownloader.runtimeconfig.json"))
+ {
+ Process.Start(localpath + "\\CLDownloader.exe");
+ }
+ else
+ {
+ Growl.Error("您的ICora仿佛不完整 请前往群中获取完整的ICora");
+ log.ErrorLog("DetectionSystem: Impact_Ultimate is incomplete", -0, "您的Impact_Ultimate不是完整的 您可以前往群中获取完整的Impact_Ultiamte");
+ }
+ }
+ else
+ {
+ try
+ {
+ HttpWebRequest request = WebRequest.CreateHttp(
+ "https://gitee.com/MasterGashByte/download/releases/download/CLibrary/CLibrary.dll");
+ HttpWebResponse? response = request.GetResponse() as HttpWebResponse;
+ Stream responseStream = response.GetResponseStream();
+ Stream stream = new FileStream(CLPath, FileMode.Create);
+ byte[] bArr = new byte[1024];
+ int size = responseStream.Read(bArr, 0, bArr.Length);
+ long totalBytesRead = 0;
+ do
+ {
+ stream.Write(bArr, 0, size);
+ size = responseStream.Read(bArr, 0, bArr.Length);
+ } while (size > 0);
+ stream.Close();
+ responseStream.Close();
+
+ Growl.Success("下载成功 以及尝试为您开始游戏");
+
+ StartGame();
+ }
+ catch (Exception ex)
+ {
+ Growl.Error($"出现异常: {ex.Message}");
+ log.ErrorLog(ex.Message, -1);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Controls Method
+
+ ///
+ /// 选择游戏路径
+ ///
+ ///
+ ///
+ private void ChooseGamePath_Click(object sender, RoutedEventArgs e)
+ {
+ var openFileDialog = new Microsoft.Win32.OpenFileDialog()
+ {
+ // 文件后缀
+ Filter = "Exe Files (*.exe)|*.exe"
+ };
+ var result = openFileDialog.ShowDialog();
+ if (result == true)
+ {
+ UGenshinImpactPath.Text = openFileDialog.FileName;
+ key.sk("Genshin Impact Path", openFileDialog.FileName);
+ }
+ }
+
+ ///
+ /// 选择游戏启动模式
+ ///
+ ///
+ ///
+ private void UStartModel_Click(object sender, RoutedEventArgs e)
+ {
+ if (UStartModel.Content.ToString() == "默认模式")
+ {
+ UStartModel.Content = "注入DLL";
+ UChooseDllPath.IsEnabled = true;
+ UChooseDll.Opacity = 1;
+ }
+ else
+ {
+ UStartModel.Content = "默认模式";
+ UChooseDllPath.IsEnabled = false;
+ UChooseDll.Opacity = 0.5;
+ }
+ UGameStartModel.Text = UStartModel.Content.ToString();
+ key.sk("Start Game Model", UGameStartModel.Text);
+ }
+
+ ///
+ /// 账户选择逻辑
+ ///
+ ///
+ ///
+ private void ChooseAccount_Click(object sender, RoutedEventArgs e)
+ {
+ if (!InModify)
+ {
+ if (AccountName.Visibility == Visibility.Hidden)
+ {
+ InAdd = true;
+ AccountName.Visibility = Visibility.Visible;
+ Growl.Clear();
+ Growl.Info("输入完成后按下回车确定, ESC退出");
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+ ///
+ /// AccountName TextBox回车判断
+ ///
+ ///
+ ///
+ private void AccountName_KeyUp(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Escape)
+ {
+ AccountName.Visibility = Visibility.Hidden;
+ AccountName.Text = string.Empty;
+ InAdd = false;
+ return;
+ }
+ if (AccountName.Text.Length > 15)
+ {
+ Growl.Clear();
+ Growl.Warning("名称最高只能有15个字符哦");
+ AccountName.Text = AccountName.Text.Substring(0, AccountName.Text.Length - 1);
+ return;
+ }
+ if (AccountName.Text == string.Empty)
+ {
+ Growl.Clear();
+ Growl.Warning("请输入账户名称");
+ return;
+ }
+ if (e.Key == Key.Enter)
+ {
+ try
+ {
+ UDataList.Add(new LocalDataList()
+ {
+ Name = AccountName.Text
+ });
+
+ YSAccount acct = YSAccount.ReadFromRegedit(true);
+ acct.Name = AccountName.Text;
+ acct.WriteToDisk();
+
+ key.sk("Account", AccountName.Text);
+
+ UChooseAccount.ItemsSource = UDataList;
+
+ AccountName.Visibility = Visibility.Hidden;
+ AccountName.Text = string.Empty;
+ InAdd = false;
+
+ RefreshList();
+
+ Growl.Clear();
+ Growl.Success($"添加成功 账户{AccountName.Text}");
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error(ex.Message);
+ log.ErrorLog(ex.Message, -1);
+ }
+ }
+ }
+
+ ///
+ /// 赋值的异常处理
+ ///
+ ///
+ ///
+ private void UChooseAccount_DropDownClosed(object sender, EventArgs e)
+ {
+ if (UChooseAccount.Text != UAccountChange.Text)
+ {
+ Switch();
+ }
+ }
+
+ ///
+ /// 删除账户
+ ///
+ ///
+ ///
+ private void DelAccount_Click(object sender, RoutedEventArgs e)
+ {
+ if (MessageBox.Show("你确定要这么做?这是不可逆的操作", "防误触提醒", MessageBoxButton.YesNo, MessageBoxImage.Hand) == MessageBoxResult.Yes)
+ {
+ if (UChooseAccount.SelectedIndex > -1)
+ {
+ string name = UChooseAccount.Text;
+ YSAccount.DeleteFromDisk(name);
+
+ UAccountChange.Text = string.Empty;
+
+ key.sk("Accout", string.Empty);
+
+ Growl.Clear();
+ Growl.Success($"您跟此账户说拜拜了 账户: {name}");
+
+ RefreshList();
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Warning("您未选择某项");
+ return;
+ }
+ }
+ }
+
+ ///
+ /// 修改账户名称
+ ///
+ ///
+ ///
+ private void ModifyAccount_Click(object sender, RoutedEventArgs e)
+ {
+ if (!InAdd)
+ {
+ if (UChooseAccount.SelectedIndex > -1)
+ {
+ ModifAccountName.Visibility = Visibility.Visible;
+ Growl.Clear();
+ Growl.Info("输入完成后按下回车确定, ESC退出");
+ InModify = true;
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Warning("您未选择某项");
+ return;
+ }
+ }
+
+ }
+
+ ///
+ /// ModifyAccountName TextBox回车判断
+ ///
+ ///
+ ///
+ private void ModifAccountName_KeyUp(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Escape)
+ {
+ ModifAccountName.Text = string.Empty;
+ ModifAccountName.Visibility = Visibility.Hidden;
+ InModify = false;
+ return;
+ }
+ if (ModifAccountName.Text.Length > 15)
+ {
+ Growl.Clear();
+ Growl.Warning("名称最高只能有15个字符哦");
+ ModifAccountName.Text = ModifAccountName.Text.Substring(0, ModifAccountName.Text.Length - 1);
+ return;
+ }
+ if (ModifAccountName.Text == string.Empty)
+ {
+ Growl.Clear();
+ Growl.Warning("请输入账户名称");
+ return;
+ }
+ if (e.Key == Key.Enter)
+ {
+ try
+ {
+ File.Move(UserData + "\\" + UAccountChange.Text, UserData + "\\" + ModifAccountName.Text);
+ key.sk("Account", ModifAccountName.Text);
+ UAccountChange.Text = ModifAccountName.Text;
+
+ RefreshList();
+
+ ModifAccountName.Text = string.Empty;
+ ModifAccountName.Visibility = Visibility.Hidden;
+
+ Growl.Clear();
+ Growl.Success("修改成功!");
+ InModify = false;
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error(ex.Message);
+ log.ErrorLog(ex.Message, -1);
+ }
+ }
+ }
+
+ ///
+ /// 开始游戏的按钮
+ ///
+ ///
+ ///
+ private void StartGameButton_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (!File.Exists(UGenshinImpactPath.Text))
+ {
+ Growl.Clear();
+ Growl.Error("没有找到你的原神 已经帮你打开启动器修复!");
+
+ DirectoryInfo info = new DirectoryInfo(UGenshinImpactPath.Text);
+ var LauncherPath = info.Parent.Parent.FullName;
+ if (File.Exists(LauncherPath + "\\launcher.exe"))
+ {
+ Process.Start(LauncherPath + "\\launcher.exe");
+ return;
+ }
+ Growl.Error("没有找到你的启动器");
+ return;
+ }
+ if (UGameStartModel.Text == "默认模式")
+ {
+ StartGameNormal();
+ Growl.Clear();
+ Growl.Success("启动成功 祝你游玩愉快!");
+ }
+ else if (UGameStartModel.Text == "注入DLL")
+ {
+ if (!IsRunAsAdmin())
+ {
+ Growl.Clear();
+ Growl.Warning("提权失败 请以管理员模式启动ICora后重试\n游戏正常启动");
+ StartGameNormal();
+ return;
+ }
+ if (UGameService.Text == "国际服 | Global")
+ {
+ Growl.Clear();
+ Growl.Warning("由于支持方问题 ICora暂时不支持国际服Dll注入 望理解!\n游戏已正常启动");
+ StartGameNormal();
+ return;
+ }
+
+ string UPath = Environment.CurrentDirectory;
+ Regex regex = new Regex("[\u4e00-\u9fa5]+");
+ if (regex.IsMatch(UPath))
+ {
+ Growl.Clear();
+ Growl.Error($"我们发现了你的路径含有中文或非法字符 请你删除它后再试");
+ return;
+ }
+
+ if (UChooseDll.Text != "默认路径")
+ {
+ FileInfo UserChoosePath = new(UChooseDll.Text);
+ Regex r = new Regex("\\.(.*)$");
+ Match match = r.Match(UserChoosePath.Name);
+ if (match.Success)
+ {
+ string content = match.Groups[1].Value;
+ if (content == "exe"
+ || content == "lnk")
+ {
+ if (File.Exists(UChooseDll.Text))
+ {
+ StartGameFormExe();
+ Growl.Clear();
+ Growl.Success("Game Started! Happy Hacking!");
+ return;
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Error("没有找到你的文件");
+ return;
+ }
+ }
+ if (content == "dll")
+ {
+ if (File.Exists(UChooseDll.Text))
+ {
+ CLPath = UChooseDll.Text;
+ StartGame();
+ return;
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Error("没有找到你的文件");
+ return;
+ }
+ }
+ }
+ Growl.Clear();
+ Growl.Error("未知问题");
+ return;
+ }
+ try
+ {
+
+ if (File.Exists(CLPath))
+ {
+ if (CheckCL.Content == "启用")
+ {
+ StartGame();
+ return;
+ }
+ // CL大小校验
+ FileInfo fileInfo = new FileInfo(CLPath);
+ long localsize = fileInfo.Length;
+ HttpWebRequest request = (HttpWebRequest)
+ WebRequest.Create("https://gitee.com/MasterGashByte/download/releases/download/CLibrary/CLibrary.dll");
+ HttpWebResponse response = request.GetResponse() as HttpWebResponse;
+ if (localsize != response.ContentLength)
+ {
+ if (ZMessageBox.Show(
+ System.Windows.Window.GetWindow(this),
+ "您的Dll大小不正确 这也许是服务器返回了不正确的大小 是否要尝试启动?选择否则下载服务器中的Dll"
+ , "", MessageBoxButton.YesNoCancel, EnumPromptType.Error) == MessageBoxResult.Yes)
+ {
+ Growl.Clear();
+ Growl.Warning("如果启动失败(原神未启动)则是Dll不正确导致的\n您可以下载服务器中的Dll或者下载群中的Akebi 然后手动导入Dll\n" +
+ "您若需要手动导入Dll 需要将Dll放置到下面这个文件夹:\n" + AkebiPath);
+ StartGame();
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Info("正在下载\n什么?没有反应 下拉开始按钮 点击下载Clibrary");
+ File.Delete(CLPath);
+ CLDownloader(true);
+ }
+ }
+ else
+ {
+ StartGame();
+ }
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Error("您的CLibrary不存在 正在为您下载");
+ CLDownloader(true);
+ }
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Growl.Clear();
+ Growl.Warning("请以管理员模式打开ICora后再试");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error(ex.Message);
+ }
+ }
+
+ ///
+ /// 内置方法下载Clibrary
+ ///
+ ///
+ ///
+ private void DownloadClibrary_Click(object sender, RoutedEventArgs e)
+ {
+ if (MessageBox.Show("这也许会出现短暂的卡顿 确定要这么做?",
+ "", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
+ {
+ try
+ {
+ if (File.Exists(CLPath))
+ {
+ FileInfo fileInfo = new FileInfo(CLPath);
+ long localsize = fileInfo.Length;
+ HttpWebRequest request = WebRequest.CreateHttp(
+ "https://gitee.com/MasterGashByte/download/releases/download/CLibrary/CLibrary.dll");
+ HttpWebResponse? response = request.GetResponse() as HttpWebResponse;
+
+ if (localsize != response.ContentLength)
+ {
+ CLDownloader(false);
+ }
+ else
+ {
+ Growl.Success("您的CLibrary看起来很正常");
+ }
+ }
+ else
+ {
+ CLDownloader(false);
+ }
+ }
+ catch (Exception ex)
+ {
+ Growl.Error($"出现异常:{ex.Message}");
+ log.ErrorLog(ex.Message, -1);
+ }
+ }
+ }
+
+ ///
+ /// 服务器选择
+ ///
+ ///
+ ///
+ private void UChooseService_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (e.RemovedItems.Count > 0)
+ {
+ if ("当前服务器:" + UChooseService.SelectedItem == UGameService.Text)
+ {
+ return;
+ }
+ try
+ {
+ if (!Directory.Exists(GenshinServiceDir))
+ {
+ Growl.Clear();
+ Growl.Error("没有找到转服包资源 请前往群中连接下载\n下载后请保存至\n"
+ + Environment.CurrentDirectory + "\\GenshinService文件夹 \n已经为您打开");
+ Directory.CreateDirectory(GenshinServiceDir);
+ Process.Start("explorer.exe", Environment.CurrentDirectory + "\\GenshinService");
+ return;
+ }
+ #region 写入配置
+ DirectoryInfo info = new DirectoryInfo(UGenshinImpactPath.Text);
+ string YuanShenDir = info.Parent.FullName;
+ string configPath = YuanShenDir + "\\config.ini";
+ if (UChooseService.SelectedItem.ToString() == "官方服 | 天空岛")
+ {
+ if (MessageBox.Show("是否这么做?这样也许会导致ICora进入长时间的卡顿\n若出现无法打开原神 请去启动器校验文件完整性", ""
+ , MessageBoxButton.YesNo, MessageBoxImage.Stop) == MessageBoxResult.Yes)
+ {
+ if (UGameService.Text == "当前服务器:国际服 | Global")
+ {
+ if (File.Exists(Environment.CurrentDirectory + "\\GenshinService\\Initial_file_v3.4.0.zip"))
+ {
+ GameConverter game = new();
+ game.Converter();
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Error("没有找到游戏转服资源包 请前往下载");
+ return;
+ }
+ }
+
+ UGenshinImpactPath.Text = YuanShenDir + "\\YuanShen.exe";
+ ini.INIWrite("General", "channel", "1", configPath);
+ ini.INIWrite("General", "cps", "mihoyo", configPath);
+ }
+ }
+ if (UChooseService.SelectedItem.ToString() == "国际服 | Global")
+ {
+ if (MessageBox.Show("是否这么做?这样也许会导致ICora进入长时间的卡顿\n若出现无法打开原神 请去启动器校验文件完整性", ""
+ , MessageBoxButton.YesNo, MessageBoxImage.Stop) == MessageBoxResult.Yes)
+ {
+ if (File.Exists(Environment.CurrentDirectory + "\\GenshinService\\Replace_file_v3.4.0.zip"))
+ {
+ GameConverter game = new();
+ game.Converter();
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Error("没有找到游戏转服资源包 请前往下载");
+ return;
+ }
+
+ ini.INIWrite("General", "channel", "1", configPath);
+ ini.INIWrite("General", "cps", "mihoyo", configPath);
+ UGenshinImpactPath.Text = YuanShenDir + "\\GenshinImpact.exe";
+ }
+ }
+ if (UChooseService.SelectedItem.ToString() == "渠道服 | 世界树")
+ {
+ if (MessageBox.Show("是否这么做?这样也许会导致ICora进入长时间的卡顿\n若出现无法打开原神 请去启动器校验文件完整性", ""
+ , MessageBoxButton.YesNo, MessageBoxImage.Stop) == MessageBoxResult.Yes)
+ {
+ ini.INIWrite("General", "channel", "14", configPath);
+ ini.INIWrite("General", "cps", "bilibili", configPath);
+ UGenshinImpactPath.Text = YuanShenDir + "\\YuanShen.exe";
+ if (UGameService.Text == "当前服务器:国际服 | Global")
+ {
+ if (File.Exists(Environment.CurrentDirectory + "\\GenshinService\\Initial_file_v3.4.0.zip"))
+ {
+ GameConverter game = new();
+ game.Converter();
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Error("没有找到游戏转服资源包 请前往下载");
+ return;
+ }
+ }
+ Growl.Clear();
+ Growl.Success("转服成功 当前服务器:渠道服 | 世界树\n若出现无法进入 还是官方服的问题 请反馈");
+ }
+ }
+ UGameService.Text = "当前服务器:" + UChooseService.SelectedItem;
+ #endregion
+ }
+ catch (DirectoryNotFoundException)
+ {
+ Growl.Clear();
+ Growl.Warning("找不到游戏配置文件 config.ini");
+ }
+ catch (UnauthorizedAccessException)
+ {
+ Growl.Clear();
+ Growl.Warning("无法读取或保存配置文件 请以管理员模式重启ICora然后重试");
+ Growl.Info("服务器未切换 当前服务器:" + UGameService.Text);
+ }
+ }
+ }
+
+ ///
+ /// 选择Dll位置
+ ///
+ ///
+ ///
+ private void UChooseDllPath_Click(object sender, RoutedEventArgs e)
+ {
+ var openFileDialog = new Microsoft.Win32.OpenFileDialog()
+ {
+ // 文件后缀
+ Filter = "(*.exe or *.dll or *.lnk) | *.exe;*.dll;*.lnk"
+ };
+ var result = openFileDialog.ShowDialog();
+ if (result == true)
+ {
+ if (openFileDialog.FileName == CLPath)
+ {
+ UChooseDll.Text = "默认路径";
+ key.sk("UChooseDll", "默认路径");
+ return;
+ }
+ UChooseDll.Text = openFileDialog.FileName;
+ key.sk("UChooseDll", UChooseDll.Text);
+ }
+ }
+
+ #region 更多设置
+
+ private void MultStart_Click(object sender, RoutedEventArgs e)
+ {
+ if (MultStart.Content.ToString() == "启用")
+ {
+ MultStart.Content = "已启用";
+ key.sk("Mult Start", "True");
+ }
+ else
+ {
+ MultStart.Content = "启用";
+ key.sk("Mult Start", "False");
+ }
+ }
+
+ private bool _UIsFullScreen;
+ private void UIsFullScreen_Click(object sender, RoutedEventArgs e)
+ {
+ if (_UIsFullScreen == false)
+ {
+ UIsFullScreen.Content = "已启用";
+ key.sk("Is Full Screen", "True");
+ _UIsFullScreen = true;
+ }
+ else
+ {
+ UIsFullScreen.Content = "启用";
+ key.sk("Is Full Screen", "False");
+ _UIsFullScreen = false;
+ }
+ }
+
+ private bool _UBorderless;
+ private void UBorderless_Click(object sender, RoutedEventArgs e)
+ {
+ if (_UBorderless == false)
+ {
+ UBorderless.Content = "已启用";
+ key.sk("Border less", "True");
+ _UBorderless = true;
+ }
+ else
+ {
+ UBorderless.Content = "启用";
+ key.sk("Border less", "False");
+ _UBorderless = false;
+ }
+ }
+
+ private bool _UScreenWidthChanged;
+ private void UScreenWidth_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (_UScreenWidthChanged)
+ {
+ if (UScreenWidth.Text != string.Empty)
+ {
+ if (Regex.IsMatch(UScreenWidth.Text, @"^-?[1-9]\d*$|^0$"))
+ {
+ if (int.Parse(UScreenWidth.Text) < 10000)
+ {
+
+ key.sk("Screen Width", UScreenWidth.Text);
+ return;
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Warning("请输入正确的宽度");
+ UScreenWidth.Text = "1920";
+ return;
+ }
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Warning("请输入正确的宽度");
+ UScreenWidth.Text = string.Empty;
+ return;
+ }
+ }
+ else
+ {
+ return;
+ }
+ }
+ _UScreenWidthChanged = true;
+ }
+
+ private bool _UScreenHeightChanged;
+ private void UScreenHeight_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (_UScreenHeightChanged)
+ {
+ if (UScreenHeight.Text != string.Empty)
+ {
+ if (Regex.IsMatch(UScreenHeight.Text, @"^-?[1-9]\d*$|^0$"))
+ {
+ if (int.Parse(UScreenHeight.Text) < 10000)
+ {
+
+ key.sk("Screen Height", UScreenHeight.Text);
+ return;
+ }
+ else
+ {
+ Growl.Warning("请输入正确的宽度");
+ UScreenHeight.Text = "1080";
+ return;
+ }
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Warning("请输入正确的宽度");
+ UScreenHeight.Text = string.Empty;
+ return;
+ }
+ }
+ else
+ {
+ return;
+ }
+ }
+ _UScreenHeightChanged = true;
+ }
+
+ private bool _UCheckCL;
+ private void CheckCL_Click(object sender, RoutedEventArgs e)
+ {
+ if (_UCheckCL == false)
+ {
+ CheckCL.Content = "启用";
+ key.sk("Check CLibrary", "False");
+ }
+ else
+ {
+ CheckCL.Content = "已启用";
+ key.sk("Check CLibrary", "True");
+ }
+ }
+
+ #endregion
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/LoginFormMihoyo.xaml b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/LoginFormMihoyo.xaml
new file mode 100644
index 0000000..a7f26f3
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/LoginFormMihoyo.xaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/LoginFormMihoyo.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/LoginFormMihoyo.xaml.cs
new file mode 100644
index 0000000..083a504
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/LoginFormMihoyo.xaml.cs
@@ -0,0 +1,123 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+using System.Threading.Tasks;
+
+namespace XFP.ICora.Controls.Basic
+{
+ ///
+ /// LoginFormMihoyo.xaml 的交互逻辑
+ ///
+
+ public partial class LoginFormMihoyo : UserControl
+ {
+ DataProvider data = new();
+
+ public LoginFormMihoyo()
+ {
+ InitializeComponent();
+ Loaded += LoginFormMihoyo_Loaded;
+
+ Growl.Clear();
+ Growl.Info("由于存储方式的问题 目前只支持单次存储 所以目前只能保存一个米哈游账户 我们会想办法解决这个问题的!");
+
+ if (!Directory.Exists(data.HoyolabAccountData))
+ {
+ Directory.CreateDirectory(data.HoyolabAccountData);
+ }
+ }
+
+ private async void LoginFormMihoyo_Loaded(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ await _WebView2.EnsureCoreWebView2Async();
+ var manager = _WebView2.CoreWebView2.CookieManager;
+ var cookies = await manager.GetCookiesAsync("https://user.mihoyo.com/#/login/captcha");
+ foreach (var item in cookies)
+ {
+ manager.DeleteCookie(item);
+ }
+ _WebView2.CoreWebView2.Navigate("https://user.mihoyo.com/#/login/captcha");
+ }
+ catch (Exception ex)
+ {
+ Growl.Error($"初始化页面失败:{ex.Message}");
+ }
+ }
+
+ private async void Logined_Click(object sender, RoutedEventArgs e)
+ {
+ await FinishAndAddCookie().ConfigureAwait(false);
+ }
+
+ public async Task FinishAndAddCookie(string str = null, bool FormHoyolabAccount = false)
+ {
+ try
+ {
+ if (!FormHoyolabAccount)
+ {
+ var manager = _WebView2?.CoreWebView2.CookieManager;
+ var cookies = await manager.GetCookiesAsync("https://user.mihoyo.com/#/account/home");
+ str = string.Join(";", cookies.Select(x => $"{x.Name}={x.Value}"));
+ Growl.Success("正在验证Cookie");
+
+ if (str == string.Empty)
+ {
+ Growl.Clear();
+ Growl.Error("你的cookie为空 请重新验证");
+ return;
+ }
+ }
+
+ _WebView2.Source = new Uri("https://gashbyte.github.io/ICoraIndex");
+
+ var user = await new HoyolabClient().GetHoyolabUserInfoAsync(str);
+ var roles = await new HoyolabClient().GetGenshinRoleInfoListAsync(str);
+
+ HoyolabUserInfo hoyolabUserInfo = user;
+ GenshinRoleInfo genshinRoleInfo = roles.FirstOrDefault();
+
+ string userMaskId = user.Uid.ToString().Substring(0, 3)
+ + "***" + user.Uid.ToString().Substring(user.Uid.ToString().Length - 3);
+ string RoleMaskId = genshinRoleInfo.Uid.ToString().Substring(0, 3)
+ + "***" + genshinRoleInfo.Uid.ToString().Substring(genshinRoleInfo.Uid.ToString().Length - 3);
+
+ Growl.Clear();
+ Growl.Success($"载入成功!\n米游社通行证ID: {userMaskId}\n玩家Uid: {RoleMaskId}");
+
+ Properties.Settings.Default.UserCookie
+ = genshinRoleInfo.Cookie;
+ Properties.Settings.Default.LastUid
+ = user.Uid;
+ Properties.Settings.Default.Save();
+ Properties.Settings.Default.Upgrade();
+
+ if (FormHoyolabAccount)
+ {
+ new HoyolabAccount().InitializeUserInfo();
+ }
+ }
+ catch (Exception ex)
+ {
+ if (ex.Message == "Object reference not set to an instance of an object.")
+ {
+ Growl.Error("无法验证此Cookie 请重新登录");
+ /*
+ Properties.Settings.Default.UserCookie
+ = string.Empty;
+ Properties.Settings.Default.LastUid
+ = 0;
+ Properties.Settings.Default.Save();
+ Properties.Settings.Default.Upgrade();
+ */
+ _WebView2.Source = new Uri("https://user.mihoyo.com/#/login/captcha");
+ return;
+ }
+ Growl.Error(ex.Message);
+
+ _WebView2.Source = new Uri("https://user.mihoyo.com/#/login/captcha");
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/Settings.xaml b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/Settings.xaml
new file mode 100644
index 0000000..c3028f3
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/Settings.xaml
@@ -0,0 +1,286 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/Settings.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/Settings.xaml.cs
new file mode 100644
index 0000000..b04a430
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/Basic/Settings.xaml.cs
@@ -0,0 +1,104 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+using System.Management;
+
+namespace XFP.ICora.Controls.Basic
+{
+ ///
+ /// Settings.xaml 的交互逻辑
+ ///
+ public partial class Settings : UserControl
+ {
+ public Settings()
+ {
+ InitializeComponent();
+ FileInfo fi = new FileInfo(Environment.CurrentDirectory + "\\XFP.ICora.exe");
+ try
+ {
+ UserICoraID.Text = "ICoraID" + getMNum() + " 设备ID在用户绑定数据库数据时起到重要关键";
+ ICoraVersion.Text = new DataProvider().ModeVersion + " V " + new DataProvider().Version;
+ LastUpdate.Text = fi.LastWriteTime.ToString();
+ }
+ catch { }
+ }
+
+ private void FeedBackUs_Click(object sender, RoutedEventArgs e)
+ => Process.Start("explorer.exe", "https://gitee.com/MasterGashByte/impact_ultimate_issues/issues");
+
+ private void ReadUUA_Click(object sender, RoutedEventArgs e)
+ => Process.Start("explorer.exe", "https://gitee.com/MasterGashByte/impact_ultimate_issues/blob/master/UserUseAgreement.md");
+
+ private void ReadPP_Click(object sender, RoutedEventArgs e)
+ => Process.Start("explorer.exe", "https://gitee.com/MasterGashByte/impact_ultimate_issues/blob/master/PrivacyPolicy.md");
+
+ private void CheckVersion_Click(object sender, RoutedEventArgs e)
+ {
+ var LocalVersion = new GetFormUrl().Get("https://gitee.com/MasterGashByte/updates/raw/master/Checker/Version");
+ if (LocalVersion != new DataProvider().Version)
+ {
+ Growl.Clear();
+ Growl.Warning($"当前版本:{new DataProvider().Version}\n发行版本:{LocalVersion}\n请前往官网或QQ群聊获取最新版\n您也可以手动打开Updater.exe来自动下载最新版");
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Success($"当前版本:{new DataProvider().Version}\n发行版本:{LocalVersion}\n已经是最新版本啦!");
+ }
+ }
+
+ private void CheckICoraID_Click(object sender, RoutedEventArgs e)
+ {
+ MessageBox.Show($"您的设备ID{getMNum()}");
+ }
+
+ ///
+ /// 取得设备硬盘的卷标号
+ ///
+ ///
+ public string GetDiskVolumeSerialNumber()
+ {
+ ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");
+ disk.Get();
+ return disk.GetPropertyValue("VolumeSerialNumber").ToString();
+ }
+
+ ///
+ /// 获得CPU的序列号
+ ///
+ ///
+ public string getCpu()
+ {
+ string strCpu = null;
+ ManagementClass myCpu = new("win32_Processor");
+ ManagementObjectCollection myCpuConnection = myCpu.GetInstances();
+ foreach (ManagementObject myObject in myCpuConnection)
+ {
+ strCpu = myObject.Properties["Processorid"].Value.ToString();
+ break;
+ }
+ return strCpu;
+ }
+
+ ///
+ /// 生成机器码
+ ///
+ ///
+ public string getMNum()
+ {
+ string strNum = getCpu() + GetDiskVolumeSerialNumber();
+ string strMNum = strNum.Substring(0, 24);
+ return strMNum;
+ }
+
+ private void JoinDevPlan_Click(object sender, RoutedEventArgs e)
+ => Growl.Info("更多咨询请联系作者或访问主页加入QQ群聊\nHomePage : https://gashbyte.github.io/ICoraIndex");
+
+ private void CopyICoraID_Click(object sender, RoutedEventArgs e)
+ {
+ Clipboard.SetDataObject(getMNum());
+ Growl.Clear();
+ Growl.Success("复制成功");
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/Game/Utils/CommandLineBuilder.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/Game/Utils/CommandLineBuilder.cs
new file mode 100644
index 0000000..a01d26e
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/Game/Utils/CommandLineBuilder.cs
@@ -0,0 +1,48 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+using System.Text;
+
+namespace XFP.ICora.Controls.Game.Utils
+{
+ ///
+ /// Toke from Snap.Data.Utility
+ ///
+ public class CommandLineBuilder
+ {
+ private const char WhiteSpace = ' ';
+ private readonly Dictionary options = new();
+
+ public CommandLineBuilder AppendIf(string name, bool condition, object? value = null)
+ {
+ return condition ? Append(name, value) : this;
+ }
+
+ public CommandLineBuilder Append(string name, object? value = null)
+ {
+ options.Add(name, value?.ToString());
+ return this;
+ }
+
+ public string Build()
+ {
+ return ToString();
+ }
+
+ public override string ToString()
+ {
+ StringBuilder s = new();
+ foreach ((string key, string? value) in options)
+ {
+ s.Append(WhiteSpace);
+ s.Append(key);
+ if (!string.IsNullOrEmpty(value))
+ {
+ s.Append(WhiteSpace);
+ s.Append(value);
+ }
+ }
+ return s.ToString();
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/Game/Utils/GameConverter.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/Game/Utils/GameConverter.cs
new file mode 100644
index 0000000..0335eb0
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/Game/Utils/GameConverter.cs
@@ -0,0 +1,285 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+using ICSharpCode.SharpZipLib.Zip;
+using System.Text;
+using XFP.ICora.ICoraException;
+
+namespace XFP.ICora.Controls.Game.Utils
+{
+
+ public class GameConverter
+ {
+ KeySetter key = new();
+ LogWriter log = new();
+
+ #region 库文件
+ private string[] GlobalFiles = new string[]
+ {
+ "Audio_Chinese_pkg_version",
+ "GenshinImpact.exe",
+ "HoYoKProtect.sys",
+ "mhypbase.dll",
+ "pkg_version",
+ "UnityPlayer.dll",
+ "GenshinImpact_Data/app.info",
+ "GenshinImpact_Data/blueReporter.exe",
+ "GenshinImpact_Data/globalgamemanagers",
+ "GenshinImpact_Data/globalgamemanagers.assets",
+ "GenshinImpact_Data/globalgamemanagers.assets.resS",
+ "GenshinImpact_Data/upload_crash.exe",
+ "GenshinImpact_Data/Native/UserAssembly.dll",
+ "GenshinImpact_Data/Native/UserAssembly.exp",
+ "GenshinImpact_Data/Native/UserAssembly.lib",
+ "GenshinImpact_Data/Plugins/Astrolabe.dll",
+ "GenshinImpact_Data/Plugins/chrome_elf.dll",
+ "GenshinImpact_Data/Plugins/crashreport.exe",
+ "GenshinImpact_Data/Plugins/cri_mana_vpx.dll",
+ "GenshinImpact_Data/Plugins/cri_vip_unity_pc.dll",
+ "GenshinImpact_Data/Plugins/cri_ware_unity.dll",
+ "GenshinImpact_Data/Plugins/d3dcompiler_47.dll",
+ "GenshinImpact_Data/Plugins/hdiffz.dll",
+ "GenshinImpact_Data/Plugins/hpatchz.dll",
+ "GenshinImpact_Data/Plugins/kcp.dll",
+ "GenshinImpact_Data/Plugins/libEGL.dll",
+ "GenshinImpact_Data/Plugins/libGLESv2.dll",
+ "GenshinImpact_Data/Plugins/libUbiCustomEvent.dll",
+ "GenshinImpact_Data/Plugins/mailbox.dll",
+ "GenshinImpact_Data/Plugins/MiHoYoMTRSDK.dll",
+ "GenshinImpact_Data/Plugins/mihoyonet.dll",
+ "GenshinImpact_Data/Plugins/MiHoYoSDKUploader.dll",
+ "GenshinImpact_Data/Plugins/Mmoron.dll",
+ "GenshinImpact_Data/Plugins/MTBenchmark_Windows.dll",
+ "GenshinImpact_Data/Plugins/NamedPipeClient.dll",
+ "GenshinImpact_Data/Plugins/Rewired_DirectInput.dll",
+ "GenshinImpact_Data/Plugins/Telemetry.dll",
+ "GenshinImpact_Data/Plugins/UnityNativeChromaSDK.dll",
+ "GenshinImpact_Data/Plugins/UnityNativeChromaSDK3.dll",
+ "GenshinImpact_Data/Plugins/vk_swiftshader.dll",
+ "GenshinImpact_Data/Plugins/vulkan-1.dll",
+ "GenshinImpact_Data/Plugins/xlua.dll",
+ "GenshinImpact_Data/Plugins/ZFEmbedWeb.dll",
+ "GenshinImpact_Data/Plugins/ZFGameBrowser.exe",
+ "GenshinImpact_Data/Plugins/ZFProxyWeb.dll",
+ "GenshinImpact_Data/Plugins/zf_cef.dll",
+ "GenshinImpact_Data/StreamingAssets/20527480.blk",
+ "GenshinImpact_Data/Managed/Metadata/global-metadata.dat",
+ "GenshinImpact_Data/Native/Data/Metadata/global-metadata.dat",
+ };
+
+ private string[] ChineseFiles = new string[]
+ {
+ "Audio_Chinese_pkg_version",
+ "HoYoKProtect.sys",
+ "mhypbase.dll",
+ "pkg_version",
+ "UnityPlayer.dll",
+ "YuanShen.exe",
+ "YuanShen_Data/app.info",
+ "YuanShen_Data/blueReporter.exe",
+ "YuanShen_Data/globalgamemanagers",
+ "YuanShen_Data/globalgamemanagers.assets",
+ "YuanShen_Data/globalgamemanagers.assets.resS",
+ "YuanShen_Data/upload_crash.exe",
+ "YuanShen_Data/Native/UserAssembly.dll",
+ "YuanShen_Data/Native/UserAssembly.exp",
+ "YuanShen_Data/Native/UserAssembly.lib",
+ "YuanShen_Data/Plugins/Astrolabe.dll",
+ "YuanShen_Data/Plugins/chrome_elf.dll",
+ "YuanShen_Data/Plugins/crashreport.exe",
+ "YuanShen_Data/Plugins/cri_mana_vpx.dll",
+ "YuanShen_Data/Plugins/cri_vip_unity_pc.dll",
+ "YuanShen_Data/Plugins/cri_ware_unity.dll",
+ "YuanShen_Data/Plugins/d3dcompiler_47.dll",
+ "YuanShen_Data/Plugins/hdiffz.dll",
+ "YuanShen_Data/Plugins/hpatchz.dll",
+ "YuanShen_Data/Plugins/kcp.dll",
+ "YuanShen_Data/Plugins/libEGL.dll",
+ "YuanShen_Data/Plugins/libGLESv2.dll",
+ "YuanShen_Data/Plugins/libUbiCustomEvent.dll",
+ "YuanShen_Data/Plugins/mailbox.dll",
+ "YuanShen_Data/Plugins/MiHoYoMTRSDK.dll",
+ "YuanShen_Data/Plugins/mihoyonet.dll",
+ "YuanShen_Data/Plugins/MiHoYoSDKUploader.dll",
+ "YuanShen_Data/Plugins/Mmoron.dll",
+ "YuanShen_Data/Plugins/MTBenchmark_Windows.dll",
+ "YuanShen_Data/Plugins/NamedPipeClient.dll",
+ "YuanShen_Data/Plugins/Rewired_DirectInput.dll",
+ "YuanShen_Data/Plugins/Telemetry.dll",
+ "YuanShen_Data/Plugins/UnityNativeChromaSDK.dll",
+ "YuanShen_Data/Plugins/UnityNativeChromaSDK3.dll",
+ "YuanShen_Data/Plugins/vk_swiftshader.dll",
+ "YuanShen_Data/Plugins/vulkan-1.dll",
+ "YuanShen_Data/Plugins/xlua.dll",
+ "YuanShen_Data/Plugins/ZFEmbedWeb.dll",
+ "YuanShen_Data/Plugins/ZFGameBrowser.exe",
+ "YuanShen_Data/Plugins/ZFProxyWeb.dll",
+ "YuanShen_Data/Plugins/zf_cef.dll",
+ "YuanShen_Data/StreamingAssets/20527480.blk",
+ "YuanShen_Data/Managed/Metadata/global-metadata.dat",
+ "/YuanShen_Data/Native/Data/Metadata/global-metadata.dat",
+ };
+ #endregion
+
+ private string GenshinServiceDir = Environment.CurrentDirectory + "\\GenshinService";
+
+ public async void Converter()
+ {
+ DirectoryInfo info = new DirectoryInfo(key.gk("Genshin Impact Path"));
+ string GenshinDir = info.Parent.FullName;
+
+ if (!(!File.Exists(GenshinDir + "\\YuanShen.exe")
+ || !File.Exists(GenshinDir + "\\GenshinImpact.exe")))
+ {
+ new DirectoryNotFound("缺少原神文件夹中的核心文件");
+ }
+
+ if (File.Exists(GenshinDir + "\\YuanShen.exe"))
+ {
+ ConvertFilesAsync(IService.Global);
+ }
+ else if (File.Exists(GenshinDir + "\\GenshinImpact.exe"))
+ {
+ ConvertFilesAsync(IService.Chinese);
+ }
+ else
+ {
+ new DirectoryNotFound("缺少原神文件夹中的核心文件");
+ }
+ }
+
+ ///
+ /// 异步覆盖当前服务器
+ ///
+ ///
+ ///
+ public void ConvertFilesAsync(IService Service)
+ {
+ string GlobalFilePath = GenshinServiceDir + "\\Replace_file_v3.4.0.zip";
+ string CNFilePath = GenshinServiceDir + "\\Initial_file_v3.4.0.zip";
+
+ // decide the Serivce arguments
+ string GenshinMain = string.Empty;
+ string[] GenshinService = new string[] { string.Empty };
+ if (Service == IService.Chinese)
+ {
+ GenshinService = GlobalFiles;
+ }
+ else
+ {
+ GenshinService = ChineseFiles;
+ }
+ // Convet File By LoserSkidder
+ // Create the BackUp Directory
+
+ DirectoryInfo info = new DirectoryInfo(key.gk("Genshin Impact Path"));
+ string GenshinDir = info.Parent.FullName;
+
+ try
+ {
+ // Review the selections
+ string FilePath = GenshinService == ChineseFiles ? CNFilePath : GlobalFilePath;
+ if (FilePath == string.Empty)
+ {
+ // Exception
+ new UnKnownChoose("Un Knwon User Choose");
+ return;
+ }
+
+ // Check for duplicate files
+ StringBuilder stringbuilder = new StringBuilder();
+ foreach (var str in GenshinService)
+ {
+ stringbuilder.Append(str.ToString() + "\n");
+ }
+
+ using (ZipFile zip = new ZipFile(FilePath))
+ {
+ string list = string.Empty;
+ foreach (ZipEntry entry in zip)
+ {
+ list += entry.Name + "\n";
+ // check the File is Exists
+ if (!stringbuilder.ToString().Contains(entry.Name))
+ {
+ // Exception
+ new IncompleteFile().FileIsNotComplete(entry.Name);
+ return;
+ }
+
+ // Delete duplicate files
+
+ // Check the list is the Directory or not
+ string resultName = GenshinDir + "\\" + entry.Name;
+ // if list is not Directory
+
+ // If this file or directory is the content : return
+ if (!(resultName == GenshinDir + "\\YuanShen_Data/"
+ || resultName == GenshinDir + "\\GenShinImpact_Data/"))
+ {
+ // Delete the File
+ FileInfo Dinfo = new FileInfo(resultName);
+ if (Dinfo.Attributes != FileAttributes.Directory)
+ {
+ File.Delete(resultName);
+ }
+ }
+ }
+
+ // Convert the Genshin Files
+ try
+ {
+ // Modify the core directory name
+ if (Service == IService.Global)
+ {
+ Directory.Move(GenshinDir + "\\YuanShen_Data", GenshinDir + "\\GenshinImpact_Data");
+
+ // Paste the files in the package
+ new FastZip().ExtractZip(GlobalFilePath, GenshinDir, "");
+ Growl.Clear();
+ Growl.Success("转换成功!当前服务器:国际服 | Global\n国际服缺少了许多内容的支持");
+ key.sk("Genshin Impact Path", GenshinDir + @"\GenshinImpact.exe");
+ }
+ else
+ {
+ Directory.Move(GenshinDir + "\\GenshinImpact_Data", GenshinDir + "\\YuanShen_Data");
+
+ // Paste the files in the package
+ new FastZip().ExtractZip(CNFilePath, GenshinDir, "");
+ Growl.Clear();
+ Growl.Success("转换成功!当前服务器:官方服 | 天空岛\n如果需要切换世界树 请再次切换");
+ key.sk("Genshin Impact Path", GenshinDir + @"\YuanShen.exe");
+ }
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ Growl.Clear();
+ Growl.Error("未提权 请以管理员模式打开ICora后再试");
+ Growl.Error(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error(ex.Message);
+ }
+ }
+ }
+ catch (DirectoryNotFoundException dirnotfound)
+ {
+ Growl.Clear();
+ Growl.Error(dirnotfound.Message);
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error(ex.Message);
+ }
+ }
+ }
+
+ public enum IService
+ {
+ Global,
+ Chinese
+ }
+}
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/HomePage.xaml b/XFP.Impact_Ultimate/XFP.Cora/Controls/HomePage.xaml
new file mode 100644
index 0000000..9a3a756
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/HomePage.xaml
@@ -0,0 +1,338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/HomePage.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/HomePage.xaml.cs
new file mode 100644
index 0000000..ee51632
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/HomePage.xaml.cs
@@ -0,0 +1,351 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Controls
+{
+ ///
+ /// HomePage.xaml 的交互逻辑
+ ///
+
+ public partial class HomePage : UserControl
+ {
+ #region Initialze
+ DataProvider data = new();
+ DeveloperOption option = new();
+ LogWriter log = new();
+ KeySetter key = new();
+ #endregion
+
+ #region define
+ private bool IsGreedG = false;
+ private string OneTimeID;
+ private string GenerateId()
+ {
+ if (IsGreedG == false)
+ {
+ long i = 1;
+ foreach (byte b in Guid.NewGuid().ToByteArray())
+ {
+ i *= b + 1;
+ }
+ IsGreedG = true;
+ OneTimeID = string.Format("{0:x}", i - DateTime.Now.Ticks);
+ return OneTimeID;
+ }
+ else
+ {
+ return OneTimeID;
+ }
+ }
+ #endregion
+
+ #region MainMethod
+ public HomePage()
+ {
+ InitializeComponent();
+
+ try
+ {
+ var myReg = Registry.LocalMachine.OpenSubKey(
+ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", RegistryKeyPermissionCheck.ReadWriteSubTree,
+ RegistryRights.FullControl);
+ if (myReg.GetValue("XFP.Impact_Ultiamte").ToString() != string.Empty)
+ {
+ AutoStart.Content = "已启用";
+ }
+ }
+ catch { }
+ }
+ #endregion
+
+ #region Method
+ ///
+ /// 启用开发者按钮
+ ///
+ ///
+ ///
+ private void DeveloperOptions_Click(object sender, RoutedEventArgs e)
+ {
+ if (data.ModeVersion != ModuleVersion.DevelopmentEdition)
+ {
+ MessageBox.Show("您的版本不是开发者版本");
+ return;
+ }
+ else
+ {
+ option.UseDeveloperOptions = true;
+ DeveloperOptions.Content = "已启用";
+ }
+ }
+
+ ///
+ /// 开机自启动按钮
+ ///
+ ///
+ ///
+ private void AutoStart_Click(object sender, RoutedEventArgs e)
+ {
+ if (AutoStart.Content.ToString() != "已启用")
+ {
+ AutoStart.Content = "已启用";
+ AdminAutoStart();
+ }
+ else
+ {
+ AutoStart.Content = "启用";
+ CancelAdminAutoStart();
+ }
+ }
+
+ ///
+ /// 用于创建开机自启动的方法
+ ///
+ private void AdminAutoStart()
+ {
+ var starupPath = GetType().Assembly.Location;
+ try
+ {
+ var fileName = Environment.CurrentDirectory + $"\\XFP.ICora.exe";
+ var shortFileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
+ var myReg = Registry.LocalMachine.OpenSubKey(
+ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", RegistryKeyPermissionCheck.ReadWriteSubTree,
+ RegistryRights.FullControl);
+ if (myReg == null)
+ {
+ myReg = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
+ }
+ if (myReg != null && myReg.GetValue(shortFileName) != null)
+ {
+ myReg.DeleteValue(shortFileName);
+ myReg.SetValue(shortFileName, fileName);
+ }
+ else if (myReg != null && myReg.GetValue(shortFileName) == null)
+ {
+ myReg.SetValue(shortFileName, fileName);
+ }
+ }
+ catch
+ {
+ return;
+ }
+ }
+
+ ///
+ /// 用于取消开机自启动的方法
+ ///
+ private void CancelAdminAutoStart()
+ {
+ var starupPath = GetType().Assembly.Location;
+ try
+ {
+ var fileName = starupPath;
+ var shortFileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
+ var myReg = Registry.LocalMachine.OpenSubKey(
+ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", RegistryKeyPermissionCheck.ReadWriteSubTree,
+ RegistryRights.FullControl);
+ if (myReg == null)
+ {
+ myReg = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
+ }
+ if (myReg != null && myReg.GetValue(shortFileName) != null)
+ {
+ myReg.DeleteValue(shortFileName);
+ }
+ else if (myReg != null && myReg.GetValue(shortFileName) == null)
+ {
+ return;
+ }
+ }
+ catch
+ {
+ return;
+ }
+ }
+
+ ///
+ /// 反馈按钮
+ ///
+ ///
+ ///
+ private void FeedBack_Click(object sender, RoutedEventArgs e)
+ => Process.Start("explorer.exe", "https://gitee.com/MasterGashByte/impact_ultimate_issues/issues");
+
+ ///
+ /// 清除所有日志按钮
+ ///
+ ///
+ ///
+ private void ClearData_Click(object sender, RoutedEventArgs e)
+ {
+ if (HandyControl.Controls.MessageBox.Show
+ ("您确定要这么做?", "防误触提示",
+ MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
+ {
+ File.Delete(data.DataLog);
+ File.Delete(data.ErrorLog);
+ File.Delete(data.TempLog);
+ File.Delete(data.SettingsData);
+ Growl.Clear();
+ Growl.Success("清除成功");
+ }
+ }
+
+ ///
+ /// 卸载ICora按钮
+ ///
+ ///
+ ///
+ private void UnInstall_Click(object sender, RoutedEventArgs e)
+ {
+ if (HandyControl.Controls.MessageBox.Show
+ ("您确定要这么做?", "防误触提示",
+ MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
+ {
+ if (File.Exists(Environment.CurrentDirectory + "\\XFP.UnInstaller.exe")
+ || File.Exists(Environment.CurrentDirectory + "\\XFP.UnInstaller.dll")
+ || File.Exists(Environment.CurrentDirectory + "\\XFP.UnInstaller.deps.json")
+ || File.Exists(Environment.CurrentDirectory + "\\XFP.UnInstaller.runtimeconfig.json"))
+ {
+ Process.Start("explorer.exe", Environment.CurrentDirectory + "\\XFP.UnInstaller.exe");
+ Environment.Exit(0);
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Error("您的ICora仿佛不齐全 请前往群中重新下载");
+ log.ErrorLog("DetectionSystem: ICora is incomplete", -0, "您的ICora不是完整的 您可以前往群中获取完整的Impact_Ultiamte");
+ }
+ }
+ }
+
+ ///
+ /// 打开日志目录
+ ///
+ ///
+ ///
+ private void OpenDataDir_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", Environment.CurrentDirectory + "\\DataBase");
+ }
+
+ ///
+ /// 打开用户账户数据
+ ///
+ ///
+ ///
+ private void OpenUserDataDir_Click(object sender, RoutedEventArgs e)
+ {
+ Process.Start("explorer.exe", Environment.CurrentDirectory + "\\UserData");
+ }
+
+ ///
+ /// 清除WebView的Cookie
+ ///
+ ///
+ ///
+ private void ClearWebCookie_Click(object sender, RoutedEventArgs e)
+ {
+ Growl.Clear();
+ Growl.Warning("接下来会进行很多次的删除操作\n如果出现闪退是因为线程卡死了");
+ if (Directory.Exists(Environment.CurrentDirectory + "\\XFP.ICora.exe.WebView2"))
+ {
+ new Thread(() =>
+ {
+ try
+ {
+ ClearWebView2(Environment.CurrentDirectory + "\\XFP.ICora.exe.WebView2");
+ }
+ catch
+ {
+ ClearWebView2(Environment.CurrentDirectory + "\\XFP.ICora.exe.WebView2");
+ }
+ Directory.Delete(Environment.CurrentDirectory + "\\XFP.ICora.exe.WebView2");
+ Growl.Clear();
+ Growl.Success("清理完成");
+ }).Start();
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Success("WebView 仿佛没有留下任何数据");
+ }
+ }
+
+ private void ClearWebView2(string path)
+ {
+ try
+ {
+ DirectoryInfo info = new(path);
+ var filesinfo = info.GetFileSystemInfos();
+ foreach (var file in filesinfo)
+ {
+ if (file is DirectoryInfo)
+ {
+ ClearWebView2(file.FullName);
+ Directory.Delete(file.FullName);
+ }
+ else
+ {
+ File.Delete(file.FullName);
+ }
+ }
+ }
+ catch { return; }
+ }
+
+ ///
+ /// 查看版本日志
+ ///
+ ///
+ ///
+ private void CheckVersionData_Click(object sender, RoutedEventArgs e)
+ => HandyControl.Controls.MessageBox.Show(
+ "当前版本:" + data.Version + "\n版本类型:" + data.ModeVersion + "\n数据验证密钥:" + GenerateId() + "\n" +
+ "数据库连接状态: " + IsCanConnect() + "\n\nCopyright(C) XFP Group 2022-2023"
+ , "ICora V" + data.Version,
+ MessageBoxButton.YesNo, MessageBoxImage.Information);
+
+ ///
+ /// 加入QQ群聊
+ ///
+ ///
+ ///
+ private void JoinQQGroup_Click(object sender, RoutedEventArgs e)
+ {
+ Growl.Clear();
+ Growl.Info("请手动添加QQ群:\n一群:811979687\n二群:590566763\n劳烦你了 其实本来是有自动跳转的\n不过qq的连接实在是打不开 所以手动添加一下吧\nQQ群已经复制到粘贴板咯");
+ Clipboard.SetDataObject("一群: 811979687 | 二群: 590566763");
+ }
+
+ ///
+ /// 通讯判断
+ ///
+ ///
+ ///
+ private static string IsCanConnect()
+ {
+ string url = "https://gashbyte.github.io/ICoraIndex";
+ HttpWebRequest req = null;
+ HttpWebResponse res = null;
+ string ReturnStr = "连接成功";
+ try
+ {
+ req = (HttpWebRequest)WebRequest.Create(url);
+ res = (HttpWebResponse)req.GetResponse();
+ }
+ catch (Exception)
+ {
+ ReturnStr = "连接失败";
+ }
+ finally
+ {
+ if (res != null)
+ {
+ res.Close();
+ }
+ }
+ return ReturnStr;
+ }
+ #endregion
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/HoyolabAccount.xaml b/XFP.Impact_Ultimate/XFP.Cora/Controls/HoyolabAccount.xaml
new file mode 100644
index 0000000..735d036
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/HoyolabAccount.xaml
@@ -0,0 +1,1044 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/HoyolabAccount.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/HoyolabAccount.xaml.cs
new file mode 100644
index 0000000..d7c192c
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/HoyolabAccount.xaml.cs
@@ -0,0 +1,513 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+using GalaSoft.MvvmLight.Messaging;
+using HandyControl.Properties.Langs;
+using System.Windows.Media;
+
+namespace XFP.ICora.Controls
+{
+ public class HoyolabUid
+ {
+ public string Uid { get; set; }
+ }
+
+ ///
+ /// HoyolabAccount.xaml 的交互逻辑
+ ///
+
+ public partial class HoyolabAccount
+ {
+ public HoyolabUserInfo? HoyolabUserInfo;
+ public GenshinRoleInfo? GenshinRoleInfo;
+
+ public string UserCookie = Properties.Settings.Default.UserCookie;
+ DataProvider data = new();
+
+ public ObservableCollection HoyolabLists { get; } = new ObservableCollection();
+
+ public HoyolabAccount()
+ {
+ InitializeComponent();
+
+ UHeaderImage.Source = new BitmapImage(new Uri("https://th.bing.com/th/id/R.3a6f44192394c3b9e5b68ed21d2e1795?rik=ZEfzfyiGXR1yKw&pid=ImgRaw&r=0"));
+ GetAreaImage();
+
+ if (UserCookie != string.Empty)
+ {
+ InitializeUserInfo();
+ HoyolabLoadingBorder.Visibility = Visibility.Visible;
+ DoubleAnimation daV = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(0.6)));
+ HoyolabLoadingBorder.BeginAnimation(OpacityProperty, daV);
+ }
+ else
+ {
+ Initialized();
+ }
+
+ UChooseAccount.ItemsSource = HoyolabLists;
+ }
+
+ #region Normal Method
+
+ ///
+ /// 载入用户数据
+ ///
+ public async void InitializeUserInfo()
+ {
+ try
+ {
+ var user = await new HoyolabClient().GetHoyolabUserInfoAsync(UserCookie);
+ var role = await new HoyolabClient().GetGenshinRoleInfoListAsync(UserCookie);
+ GenshinRoleInfo? genshinRoleInfo = role.FirstOrDefault();
+
+ UHeaderImage.Source = new BitmapImage(new Uri(user.AvatarUrl));
+ UserHoyolabName.Text = $"你好! {user.Nickname}";
+ string RoleMaskId = genshinRoleInfo.Uid.ToString().Substring(0, 3)
+ + "***" + genshinRoleInfo.Uid.ToString().Substring(genshinRoleInfo.Uid.ToString().Length - 3);
+ UserHoyolabUid.Text = $"Uid {RoleMaskId}";
+ UserGenshinServer.Text = $"您在 {genshinRoleInfo.RegionName} ";
+ UserGenshinLevel.Text = $"您 {genshinRoleInfo.Level} 级了";
+ HeadFrame.Source = new BitmapImage(new Uri(user.Pendant));
+ Intr.Text = $"简介:{user.Introduce}";
+ UHoyolabAccount.Text = $"嗨!别来无恙啊!{user.Nickname} 最近生活是否如意?";
+ InputCookie.IsEnabled = false;
+
+ Properties.Settings.Default.UserCookie = genshinRoleInfo.Cookie;
+ Properties.Settings.Default.Save();
+ Properties.Settings.Default.Upgrade();
+
+ GetDailyNotesAsync();
+
+ HoyolabLists.Clear();
+ HoyolabLists.Add(new HoyolabUid()
+ {
+ Uid = RoleMaskId
+ });
+
+ GetGameRecordByInitialze(genshinRoleInfo, RoleMaskId);
+
+ try
+ {
+ var SginInfo = await new HoyolabClient().GetSignInInfoAsync(genshinRoleInfo);
+ if (SginInfo.IsSub)
+ {
+ Growl.Clear();
+ Growl.Info("旅行者今天还没有签到哦~ 已经帮你签到了哦~");
+ await new HoyolabClient().SignInAsync(genshinRoleInfo);
+ }
+ }
+ catch (Exception ex)
+ {
+ Growl.Error($"在签到时 {ex.Message}");
+ }
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ if (ex.Message == "Object reference not set to an instance of an object.")
+ {
+ Growl.Clear();
+ Growl.Error("米游社凭证过期 正在尝试刷新");
+ /*
+ Properties.Settings.Default.UserCookie = string.Empty;
+ Properties.Settings.Default.Save();
+ Properties.Settings.Default.Upgrade();
+ */
+ await new LoginFormMihoyo().FinishAndAddCookie(UserCookie, true);
+ Initialized();
+ return;
+ }
+ if (ex.Message == "The format of value '' is invalid.")
+ {
+ Growl.Clear();
+ Growl.Error("没有找到有效的Cookie");
+ return;
+ }
+ Growl.Error($"在请求数据时出错:{ex.Message}");
+ Initialized();
+ }
+ }
+
+ ///
+ /// 获取玩家当前Uid的所有战绩
+ ///
+ private async void GetGameRecordByInitialze(GenshinRoleInfo info, string uid)
+ {
+ try
+ {
+ var roleGameRecord = await new HoyolabClient().GetGameRecordAsync(info);
+ Days.Text = $"{roleGameRecord.PlayerStat.ActiveDayNumber}天";
+ Achievements.Text = $"{roleGameRecord.PlayerStat.AchievementNumber}个";
+ RolesCount.Text = $"{roleGameRecord.PlayerStat.AvatarNumber}个";
+ TPPoints.Text = $"{roleGameRecord.PlayerStat.WayPointNumber}个";
+ AOcuil.Text = $"{roleGameRecord.PlayerStat.AnemoculusNumber}";
+ GOcuil.Text = $"{roleGameRecord.PlayerStat.GeoculusNumber}";
+ EOcuil.Text = $"{roleGameRecord.PlayerStat.ElectroculusNumber}";
+ DOcuil.Text = $"{roleGameRecord.PlayerStat.DendroculusNumber}";
+ Domain.Text = $"{roleGameRecord.PlayerStat.DomainNumber}个";
+ SpiralAbyss.Text = $"{roleGameRecord.PlayerStat.SpiralAbyss}";
+ Luxurious.Text = $"{roleGameRecord.PlayerStat.LuxuriousChestNumber}";
+ Precious.Text = $"{roleGameRecord.PlayerStat.PreciousChestNumber}";
+ Exquisite.Text = $"{roleGameRecord.PlayerStat.ExquisiteChestNumber}";
+ Common.Text = $"{roleGameRecord.PlayerStat.CommonChestNumber}";
+ Remarkable.Text = $"{roleGameRecord.PlayerStat.MagicChestNumber}";
+
+ MondE.Text = $"{roleGameRecord.WorldExplorations[7].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[7].ExplorationPercentage.ToString().Length - 1, ".")}%";
+ LiyueE.Text = $"{roleGameRecord.WorldExplorations[6].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[6].ExplorationPercentage.ToString().Length - 1, ".")}%";
+ DragonspineE.Text = $"{roleGameRecord.WorldExplorations[5].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[5].ExplorationPercentage.ToString().Length - 1, ".")}%";
+ DaoqiE.Text = $"{roleGameRecord.WorldExplorations[4].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[4].ExplorationPercentage.ToString().Length - 1, ".")}%";
+ EnkanomiyaE.Text = $"{roleGameRecord.WorldExplorations[3].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[3].ExplorationPercentage.ToString().Length - 1, ".")}%";
+ ChasmE.Text = $"{roleGameRecord.WorldExplorations[2].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[2].ExplorationPercentage.ToString().Length - 1, ".")}%";
+ Chasm_UndergroundE.Text = $"{roleGameRecord.WorldExplorations[1].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[1].ExplorationPercentage.ToString().Length - 1, ".")}%";
+ XumiE.Text = $"{roleGameRecord.WorldExplorations[0].ExplorationPercentage.ToString().
+ Insert(roleGameRecord.WorldExplorations[0].ExplorationPercentage.ToString().Length - 1, ".")}%";
+
+ Initialized(uid);
+
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error($"在获取用户战绩时出错 {ex.Message}");
+ }
+ }
+
+ ///
+ /// 获取图标
+ ///
+ public async void GetAreaImage()
+ {
+ try
+ {
+ MondeIcon.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Mengde.png"));
+ LiyueIcon.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Liyue.png"));
+ DaoqiIcon.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Daoqi.png"));
+ XumiIcon.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Xumi.png"));
+ Dragonspine.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Dragonspine.png"));
+ Enkanomiya.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_Enkanomiya.png"));
+ Chasm.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_ChasmsMaw.png"));
+ Chasm_Underground.Source = new BitmapImage(new Uri("https://upload-bbs.mihoyo.com/game_record/genshin/city_icon/UI_ChapterIcon_ChasmsMaw.png"));
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error($"在获取图片时出错 {ex.Message}");
+ }
+ }
+
+ ///
+ /// 实时便签
+ ///
+ ///
+ ///
+ public async void GetDailyNotesAsync()
+ {
+ try
+ {
+ var users = await new HoyolabClient().GetHoyolabUserInfoAsync(UserCookie);
+ var roles = await new HoyolabClient().GetGenshinRoleInfoListAsync(UserCookie);
+ foreach (var role in roles)
+ {
+ try
+ {
+ var dailynote = await new HoyolabClient().GetDailyNoteAsync(role);
+ var travelnote = await new HoyolabClient().GetTravelNotesSummaryAsync(role);
+
+ try
+ {
+ AvatarSideIconI.Source = new BitmapImage(new Uri(dailynote.Expeditions[0].AvatarSideIcon));
+ AvatarSideIconII.Source = new BitmapImage(new Uri(dailynote.Expeditions[1].AvatarSideIcon));
+ AvatarSideIconIII.Source = new BitmapImage(new Uri(dailynote.Expeditions[2].AvatarSideIcon));
+ AvatarSideIconIV.Source = new BitmapImage(new Uri(dailynote.Expeditions[3].AvatarSideIcon));
+ AvatarSideIconV.Source = new BitmapImage(new Uri(dailynote.Expeditions[4].AvatarSideIcon));
+
+ int FinishedCount = 0;
+
+ if (dailynote.Expeditions[0].Status == "Ongoing")
+ {
+ RemainedTimeI.Text = dailynote.Expeditions[0].RemainedTime.ToString();
+ FinishedCount += 1;
+ }
+ else
+ {
+ RemainedTimeI.Text = "已完成";
+ }
+
+ if (dailynote.Expeditions[1].Status == "Ongoing")
+ {
+ RemainedTimeII.Text = dailynote.Expeditions[1].RemainedTime.ToString();
+ FinishedCount += 1;
+ }
+ else
+ {
+ RemainedTimeII.Text = "已完成";
+ }
+
+ if (dailynote.Expeditions[2].Status == "Ongoing")
+ {
+ RemainedTimeIII.Text = dailynote.Expeditions[2].RemainedTime.ToString();
+ FinishedCount += 1;
+ }
+ else
+ {
+ RemainedTimeIII.Text = "已完成";
+ }
+
+ if (dailynote.Expeditions[3].Status == "Ongoing")
+ {
+ RemainedTimeIV.Text = dailynote.Expeditions[3].RemainedTime.ToString();
+ FinishedCount += 1;
+ }
+ else
+ {
+ RemainedTimeIV.Text = "已完成";
+ }
+
+ if (dailynote.Expeditions[4].Status == "Ongoing")
+ {
+ RemainedTimeV.Text = dailynote.Expeditions[4].RemainedTime.ToString();
+ FinishedCount += 1;
+ }
+ else
+ {
+ RemainedTimeV.Text = "已完成";
+ }
+ if (FinishedCount != dailynote.MaxExpeditionNumber)
+ {
+ ExpeditionsStatus.Text = $"派遣完成度({FinishedCount}/{dailynote.MaxExpeditionNumber})";
+ }
+ else
+ {
+ Growl.SuccessGlobal("派遣已完成 快点领取奖励吧!");
+ }
+
+ ResinCurrent.Text = $"{dailynote.CurrentResin}/{dailynote.MaxResin}";
+ if (dailynote.CurrentResin == dailynote.MaxResin)
+ {
+ Growl.SuccessGlobal("体力回复满了 快点使用吧!");
+ }
+ HomeCoinCurrent.Text = $"{dailynote.CurrentHomeCoin}/{dailynote.MaxHomeCoin}";
+ if (dailynote.CurrentHomeCoin == dailynote.MaxHomeCoin)
+ {
+ Growl.SuccessGlobal("洞天宝钱满了 快点领取吧!");
+ }
+ DailyTaskCurrent.Text = $"{dailynote.FinishedTaskNumber}/4";
+ ResinDiscountCurrent.Text = $"{dailynote.ResinDiscountLimitedNumber}/3";
+ if (dailynote.Transformer.RecoveryTime.Day != 0)
+ {
+ TransformerCurrent.Text = $"还有 {dailynote.Transformer.RecoveryTime.Day} 天";
+ }
+ else
+ {
+ TransformerCurrent.Text = $"已冷却";
+ Growl.SuccessGlobal("参量质变仪已冷却 快点使用吧!");
+ }
+ CurrentPrimogems.Text = travelnote.MonthData.LastPrimogems.ToString();
+ CurrentMora.Text = travelnote.DayData.LastMora.ToString();
+ }
+ catch { }
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Warning("在获取实时数据时 " + ex.Message + " 请前往手机端米游社手动刷新实时便签");
+ PaimonEmo.Visibility = Visibility.Visible;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error("在获取实时数据时 " + ex.Message);
+ }
+ }
+
+ ///
+ /// 加载结束动画
+ ///
+ ///
+ public new void Initialized(string Uid = "未添加(选择)账户")
+ {
+ DoubleAnimation daV = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromSeconds(1.3)));
+ HoyolabLoadingBorder.BeginAnimation(OpacityProperty, daV);
+ daV.Completed += (sender, e) => { /*Skip Animation*/ };
+ HoyolabLoadingBorder.IsHitTestVisible = false;
+
+ UChooseHoyolabAccount.Text = "当前账户:" + Uid;
+
+ Growl.Success("刷新成功!");
+ }
+
+
+ #endregion
+
+ #region Control Method
+
+ private void UChooseAccount_DropDownClosed(object sender, EventArgs e)
+ {
+ if (UChooseAccount.SelectedIndex > -1)
+ {
+ UChooseHoyolabAccount.Text = "当前账户:" + UChooseAccount.Text;
+ }
+ if (UChooseAccount.Text == string.Empty)
+ {
+ UChooseHoyolabAccount.Text = "当前账户:未添加(选择)账户";
+ }
+ }
+
+ ///
+ /// 重新请求内容
+ ///
+ ///
+ ///
+ private void RefreshAccountList_Click(object sender, RoutedEventArgs e)
+ {
+ RefreshAll();
+ }
+
+ private async void RefreshAll()
+ {
+ try
+ {
+ DoubleAnimation daV = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(0.6)));
+ HoyolabLoadingBorder.BeginAnimation(OpacityProperty, daV);
+ await new LoginFormMihoyo().FinishAndAddCookie(UserCookie, true);
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error($"{ex.Message}");
+ Initialized();
+ }
+ }
+
+ ///
+ /// 复制Cookie
+ ///
+ ///
+ ///
+ private void CopyCookie_Click(object sender, RoutedEventArgs e)
+ {
+ if (!(UChooseAccount.SelectedIndex > -1))
+ {
+ Growl.Clear();
+ Growl.Warning("您没有选择一个账户");
+ return;
+ }
+ if (Properties.Settings.Default.UserCookie == string.Empty)
+ {
+ Growl.Clear();
+ Growl.Warning($"{UChooseAccount.SelectedItem} 账户的Cookie已失效或不存在 请重新登录");
+ return;
+ }
+ Clipboard.SetDataObject(Properties.Settings.Default.UserCookie);
+ Growl.Clear();
+ Growl.Success("复制成功!");
+ }
+
+ ///
+ /// 删除此账户
+ ///
+ ///
+ ///
+ private void DelHoyolabAcc_Click(object sender, RoutedEventArgs e)
+ {
+ if (!(UChooseAccount.SelectedIndex > -1))
+ {
+ Growl.Clear();
+ Growl.Warning("您没有选择一个账户");
+ return;
+ }
+ if (ZMessageBox.Show(Window.GetWindow(this),
+ "您确定要这么做?\n这是不可逆的操作", "", MessageBoxButton.YesNo, EnumPromptType.Warn) == MessageBoxResult.Yes)
+ {
+ Properties.Settings.Default.UserCookie = string.Empty;
+ Properties.Settings.Default.Save();
+ Properties.Settings.Default.Upgrade();
+ Growl.Clear();
+ Growl.Success("删除成功!\n请重新刷新");
+ InputCookie.IsEnabled = true;
+ UChooseHoyolabAccount.Text = "当前账户:未添加(选择)账户";
+
+ new MainWindow().ControlPanel = new HomePage();
+ }
+ }
+
+ ///
+ /// 手动输入Cookie按钮
+ ///
+ ///
+ ///
+ private void InputCookie_Click(object sender, RoutedEventArgs e)
+ {
+ InputUCookie.Visibility = Visibility.Visible;
+ InputUserCookie.Visibility = Visibility.Visible;
+ Growl.Clear();
+ Growl.Info("请输入带有cookie_token_v2的Cookie\n按下ESC退出输入 回车键确定");
+ }
+
+ ///
+ /// 按键检测
+ ///
+ ///
+ ///
+ private void InputUserCookie_KeyUp(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Escape)
+ {
+ InputUCookie.Visibility = Visibility.Hidden;
+ InputUserCookie.Visibility = Visibility.Hidden;
+ InputUserCookie.Text = string.Empty;
+ return;
+ }
+ if (e.Key == Key.Enter)
+ {
+ InputUCookie.Visibility = Visibility.Hidden;
+ InputUserCookie.Visibility = Visibility.Hidden;
+ if (InputUserCookie.Text != string.Empty)
+ {
+ Properties.Settings.Default.UserCookie = InputUserCookie.Text;
+ Properties.Settings.Default.Save();
+ Properties.Settings.Default.Upgrade();
+ InputUserCookie.Text = string.Empty;
+ Growl.Clear();
+ Growl.Success("正在验证Cookie");
+ new LoginFormMihoyo().FinishAndAddCookie(Properties.Settings.Default.UserCookie, true);
+ return;
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Warning("您没有输入Cookie\n按下ESC退出输入");
+ InputUCookie.Visibility = Visibility.Hidden;
+ InputUserCookie.Visibility = Visibility.Hidden;
+ InputUserCookie.Text = string.Empty;
+ return;
+ }
+ }
+ }
+
+ public record GameRecordItem
+ {
+ public GameRecordItem(string description, string value)
+ {
+ Description = description;
+ Value = value;
+ }
+
+ public string Description { get; set; }
+
+ public string Value { get; set; }
+ }
+
+ #endregion
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/NonClientAreaContent.xaml b/XFP.Impact_Ultimate/XFP.Cora/Controls/NonClientAreaContent.xaml
new file mode 100644
index 0000000..7372a5d
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/NonClientAreaContent.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Controls/NonClientAreaContent.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/Controls/NonClientAreaContent.xaml.cs
new file mode 100644
index 0000000..245b4d3
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Controls/NonClientAreaContent.xaml.cs
@@ -0,0 +1,17 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Controls
+{
+ ///
+ /// NonClientAreaContent.xaml 的交互逻辑
+ ///
+ public partial class NonClientAreaContent
+ {
+ public NonClientAreaContent()
+ {
+ InitializeComponent();
+ Icon.Source = new BitmapImage(new Uri("https://img.icons8.com/nolan/512/genshin-impact-logo.png"));
+ }
+ }
+}
diff --git "a/XFP.Impact_Ultimate/XFP.Cora/GashByte-\351\200\217\346\230\216.ico" "b/XFP.Impact_Ultimate/XFP.Cora/GashByte-\351\200\217\346\230\216.ico"
new file mode 100644
index 0000000..c37783f
Binary files /dev/null and "b/XFP.Impact_Ultimate/XFP.Cora/GashByte-\351\200\217\346\230\216.ico" differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/GlobalUsing.cs b/XFP.Impact_Ultimate/XFP.Cora/GlobalUsing.cs
new file mode 100644
index 0000000..1eff241
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/GlobalUsing.cs
@@ -0,0 +1,39 @@
+// ---------------- global using ---------------- //
+global using HandyControl.Controls;
+global using Microsoft.Win32;
+global using System;
+global using System.Collections.Generic;
+global using System.Collections.ObjectModel;
+global using System.Diagnostics;
+global using System.IO;
+global using System.Linq;
+global using System.Net;
+global using System.Security.AccessControl;
+global using System.Text.Json;
+global using System.Text.Json.Serialization;
+global using System.Threading;
+global using System.Windows;
+global using System.Windows.Controls;
+global using System.Windows.Input;
+global using System.Windows.Media.Animation;
+global using System.Windows.Media.Imaging;
+global using UI;
+global using XFP.ICora.Controls;
+global using XFP.ICora.Controls.Basic;
+global using XFP.ICora.Hoyolab;
+global using XFP.ICora.Hoyolab.Account;
+global using XFP.ICora.Hoyolab.Core;
+global using XFP.ICora.Model;
+global using XFP.ICora.Utils;
+global using XFP.ICora.Utils.Base;
+global using XFP.ICora.Utils.Log;
+global using XFP.ICora.Utils.Model;
+global using System.Runtime.InteropServices;
+global using System.Text;
+global using System.Text.RegularExpressions;
+global using XFP.ICora.Controls.Game.Utils;
+global using XFP.ICora.Utils.Model.Files;
+global using System.Security.Principal;
+// ---------------- global using as ---------------- //
+global using MessageBox = System.Windows.MessageBox;
+global using Window = System.Windows.Window;
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/GenshinRoleInfo.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/GenshinRoleInfo.cs
new file mode 100644
index 0000000..bc8c38a
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/GenshinRoleInfo.cs
@@ -0,0 +1,43 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class GenshinRoleInfo
+ {
+ [JsonPropertyName("game_biz")]
+ public string GameBiz { get; set; }
+
+
+ [JsonPropertyName("region"), JsonConverter(typeof(JsonStringEnumConverter))]
+ public Core.RegionType Region { get; set; }
+
+
+ [JsonPropertyName("game_uid"), JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
+ public int Uid { get; set; }
+
+
+ [JsonPropertyName("nickname")]
+ public string Nickname { get; set; }
+
+
+ [JsonPropertyName("level")]
+ public int Level { get; set; }
+
+
+ [JsonPropertyName("is_chosen")]
+ public bool IsChosen { get; set; }
+
+
+ [JsonPropertyName("region_name")]
+ public string? RegionName { get; set; }
+
+
+ [JsonPropertyName("is_official")]
+ public bool IsOfficial { get; set; }
+
+
+ [JsonIgnore]
+ public string? Cookie { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/GenshinRoleInfoWrapper.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/GenshinRoleInfoWrapper.cs
new file mode 100644
index 0000000..b000377
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/GenshinRoleInfoWrapper.cs
@@ -0,0 +1,11 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class GenshinRoleInfoWrapper
+ {
+ [JsonPropertyName("list")]
+ public List? List { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/HoyolabUserInfo.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/HoyolabUserInfo.cs
new file mode 100644
index 0000000..db39685
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/HoyolabUserInfo.cs
@@ -0,0 +1,56 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class HoyolabUserInfo
+ {
+ ///
+ /// 通行证 ID
+ ///
+ [JsonPropertyName("uid"), JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)]
+ public int Uid { get; set; }
+
+ ///
+ /// 昵称
+ ///
+ [JsonPropertyName("nickname")]
+ public string? Nickname { get; set; }
+
+ ///
+ /// 介绍
+ ///
+ [JsonPropertyName("introduce")]
+ public string? Introduce { get; set; }
+
+ ///
+ /// 头像 ID
+ ///
+ [JsonPropertyName("avatar")]
+ public string? Avatar { get; set; }
+
+ ///
+ /// 性别 0/1/2
+ ///
+ [JsonPropertyName("gender")]
+ public int Gender { get; set; }
+
+ ///
+ /// 头像
+ ///
+ [JsonPropertyName("avatar_url")]
+ public string? AvatarUrl { get; set; }
+
+ ///
+ /// 头像框
+ ///
+ [JsonPropertyName("pendant")]
+ public string? Pendant { get; set; }
+
+ ///
+ /// 与此账号相关联的 Cookie
+ ///
+ [JsonIgnore]
+ public string? Cookie { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/HoyolabUserInfoWrapper.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/HoyolabUserInfoWrapper.cs
new file mode 100644
index 0000000..4b380b0
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/HoyolabUserInfoWrapper.cs
@@ -0,0 +1,11 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class HoyolabUserInfoWrapper
+ {
+ [JsonPropertyName("user_info")]
+ public HoyolabUserInfo HoyolabUserInfo { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/IWrapper.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/IWrapper.cs
new file mode 100644
index 0000000..45f6b79
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/IWrapper.cs
@@ -0,0 +1,61 @@
+using Newtonsoft.Json;
+
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class IWrapper
+ {
+ ///
+ /// 用户Uid
+ ///
+ [JsonProperty("Uid")]
+ public string Uid { get; set; }
+
+ ///
+ /// 用户名称
+ ///
+ [JsonProperty("Name")]
+ public string NickName { get; set; }
+
+ ///
+ /// 用户等级
+ ///
+ [JsonProperty("Level")]
+ public string Level { get; set; }
+
+ ///
+ /// 用户Cookie
+ ///
+ [JsonProperty("Cookie")]
+ public string Cookie { get; set; }
+
+ ///
+ /// GameBiz
+ ///
+ [JsonProperty("GameBiz")]
+ public string GameBiz { get; set; }
+
+ ///
+ /// IsChosen
+ ///
+ [JsonProperty("IsChosen")]
+ public string IsChosen { get; set; }
+
+ ///
+ /// IsOfficial
+ ///
+ [JsonProperty("IsOfficial")]
+ public string IsOfficial { get; set; }
+
+ ///
+ /// 服务器名称
+ ///
+ [JsonProperty("RegionName")]
+ public string RegionName { get; set; }
+
+ ///
+ /// 服务器
+ ///
+ [JsonProperty("Region")]
+ public string Region { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignInInfo.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignInInfo.cs
new file mode 100644
index 0000000..f9d7650
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignInInfo.cs
@@ -0,0 +1,39 @@
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class SignInInfo
+ {
+ ///
+ /// 累积签到天数
+ ///
+ [JsonPropertyName("total_sign_day")]
+ public int TotalSignDays { get; set; }
+
+ ///
+ /// 今天是...
+ ///
+ [JsonPropertyName("today"), JsonConverter(typeof(SignTodayJsonConverter))]
+ public DateTime Today { get; set; }
+
+ ///
+ /// 今日是否已签到
+ ///
+ [JsonPropertyName("is_sign")]
+ public bool IsSign { get; set; }
+
+
+ [JsonPropertyName("is_sub")]
+ public bool IsSub { get; set; }
+
+
+ [JsonPropertyName("first_bind")]
+ public bool FirstBind { get; set; }
+
+
+ [JsonPropertyName("month_first")]
+ public bool IsFirstDayOfMonth { get; set; }
+
+
+ [JsonPropertyName("sign_cnt_missed")]
+ public int MissedCount { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignInRisk.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignInRisk.cs
new file mode 100644
index 0000000..e7caee0
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignInRisk.cs
@@ -0,0 +1,20 @@
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class SignInRisk
+ {
+ [JsonPropertyName("code")]
+ public string Code { get; set; }
+
+ [JsonPropertyName("risk_code")]
+ public int RiskCode { get; set; }
+
+ [JsonPropertyName("gt")]
+ public string GT { get; set; }
+
+ [JsonPropertyName("challenge")]
+ public string Challenge { get; set; }
+
+ [JsonPropertyName("success")]
+ public int Success { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignTodayJsonConverter.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignTodayJsonConverter.cs
new file mode 100644
index 0000000..5de7701
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Account/SignTodayJsonConverter.cs
@@ -0,0 +1,23 @@
+namespace XFP.ICora.Hoyolab.Account
+{
+ public class SignTodayJsonConverter : JsonConverter
+ {
+ public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var str = reader.GetString();
+ if (DateTime.TryParse(str, out var date))
+ {
+ return date;
+ }
+ else
+ {
+ return DateTime.Now;
+ }
+ }
+
+ public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Avatar/AvatarInfo.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Avatar/AvatarInfo.cs
new file mode 100644
index 0000000..e1f3f98
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Avatar/AvatarInfo.cs
@@ -0,0 +1,58 @@
+namespace XFP.ICora.Hoyolab.Avatar
+{
+ public class AvatarInfo
+ {
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ ///
+ /// 名称
+ ///
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+ ///
+ /// 元素类型
+ ///
+ [JsonPropertyName("element"), JsonConverter(typeof(JsonStringEnumConverter))]
+ public Core.ElementType Element { get; set; }
+
+ ///
+ /// 半身肖像
+ ///
+ ///
+ [JsonPropertyName("image")]
+ public string Image { get; set; }
+
+ ///
+ /// 半身肖像(带有卡片边框)
+ ///
+ ///
+ [JsonPropertyName("card_image")]
+ public string CardImage { get; set; }
+
+ ///
+ /// 好感度
+ ///
+ [JsonPropertyName("fetter")]
+ public int Fetter { get; set; }
+
+ ///
+ /// 等级
+ ///
+ [JsonPropertyName("level")]
+ public int Level { get; set; }
+
+ ///
+ /// 稀有度
+ ///
+ [JsonPropertyName("rarity")]
+ public int Rarity { get; set; }
+
+ ///
+ /// 已激活名座数
+ ///
+ [JsonPropertyName("actived_constellation_num")]
+ public int ActivedConstellationNumber { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Core/ElementType.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Core/ElementType.cs
new file mode 100644
index 0000000..255e85e
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Core/ElementType.cs
@@ -0,0 +1,56 @@
+namespace XFP.ICora.Hoyolab.Core
+{
+ public enum ElementType
+ {
+ ///
+ /// 未知
+ ///
+ None = 0,
+
+ ///
+ /// 物理
+ ///
+ Physics = 1,
+
+ ///
+ /// 火
+ ///
+ Pyro = 2,
+ Fire = 2,
+
+ ///
+ /// 水
+ ///
+ Hydro = 4,
+ Water = 4,
+
+ ///
+ /// 风
+ ///
+ Anemo = 8,
+ Wind = 8,
+
+ ///
+ /// 雷
+ ///
+ Electro = 16,
+
+ ///
+ /// 草
+ ///
+ Dendro = 32,
+ Grass = 32,
+
+ ///
+ /// 冰
+ ///
+ Cryo = 64,
+ Ice = 64,
+
+ ///
+ /// 岩
+ ///
+ Geo = 128,
+ Rock = 128,
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Core/RegionType.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Core/RegionType.cs
new file mode 100644
index 0000000..5054d58
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/Core/RegionType.cs
@@ -0,0 +1,19 @@
+namespace XFP.ICora.Hoyolab.Core
+{
+ public enum RegionType
+ {
+ None = 0,
+
+ cn_gf01 = 1,
+
+ cn_qd01 = 5,
+
+ os_usa = 6,
+
+ os_euro = 7,
+
+ os_asia = 8,
+
+ os_cht = 9,
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/DailyNoteInfo.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/DailyNoteInfo.cs
new file mode 100644
index 0000000..9f6fed4
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/DailyNoteInfo.cs
@@ -0,0 +1,140 @@
+namespace XFP.ICora.Hoyolab.DailyNote
+{
+ public class DailyNoteInfo
+ {
+ [JsonIgnore]
+ public int Id { get; set; }
+
+ [JsonIgnore]
+ public int Uid { get; set; }
+
+ [JsonIgnore]
+ public string Nickname { get; set; }
+
+ ///
+ /// 获取实时便笺时的时间
+ ///
+ [JsonIgnore]
+ public DateTimeOffset NowTime { get; init; } = DateTimeOffset.Now;
+
+ ///
+ /// 当前树脂
+ ///
+ [JsonPropertyName("current_resin")]
+ public int CurrentResin { get; set; }
+
+ ///
+ /// 最大树脂
+ ///
+ [JsonPropertyName("max_resin")]
+ public int MaxResin { get; set; }
+
+ ///
+ /// 树脂剩余恢复时间
+ ///
+ [JsonPropertyName("resin_recovery_time"), JsonConverter(typeof(RecoveryTimeJsonConverter))]
+ public TimeSpan ResinRecoveryTime { get; set; }
+
+ ///
+ /// 树脂是否恢复满
+ ///
+ [JsonIgnore]
+ public bool IsResinFull => ResinRecoveryTime == TimeSpan.Zero;
+
+ ///
+ /// 树脂恢复满的时刻
+ ///
+ [JsonIgnore]
+ public DateTimeOffset ResinFullTime => NowTime + ResinRecoveryTime;
+
+ ///
+ /// 委托完成数
+ ///
+ [JsonPropertyName("finished_task_num")]
+ public int FinishedTaskNumber { get; set; }
+
+ ///
+ /// 委托总数
+ ///
+ [JsonPropertyName("total_task_num")]
+ public int TotalTaskNumber { get; set; }
+
+ ///
+ /// 4次委托额外奖励是否领取
+ ///
+ [JsonPropertyName("is_extra_task_reward_received")]
+ public bool IsExtraTaskRewardReceived { get; set; }
+
+ ///
+ /// 剩余周本树脂减半次数
+ ///
+ [JsonPropertyName("remain_resin_discount_num")]
+ public int RemainResinDiscountNumber { get; set; }
+
+ ///
+ /// 周本树脂减半总次数
+ ///
+ [JsonPropertyName("resin_discount_num_limit")]
+ public int ResinDiscountLimitedNumber { get; set; }
+
+ ///
+ /// 当前派遣数
+ ///
+ [JsonPropertyName("current_expedition_num")]
+ public int CurrentExpeditionNumber { get; set; }
+
+ ///
+ /// 已完成派遣数
+ ///
+ [JsonIgnore]
+ public int FinishedExpeditionNumber => Expeditions?.Count(x => x.IsFinished) ?? 0;
+
+ ///
+ /// 最大派遣数
+ ///
+ [JsonPropertyName("max_expedition_num")]
+ public int MaxExpeditionNumber { get; set; }
+
+ ///
+ /// 探索派遣
+ ///
+ [JsonPropertyName("expeditions")]
+ public List Expeditions { get; set; }
+
+ ///
+ /// 当前洞天宝钱
+ ///
+ [JsonPropertyName("current_home_coin")]
+ public int CurrentHomeCoin { get; set; }
+
+ ///
+ /// 最大洞天宝钱
+ ///
+ [JsonPropertyName("max_home_coin")]
+ public int MaxHomeCoin { get; set; }
+
+ ///
+ /// 洞天宝钱剩余恢复时间
+ ///
+ [JsonPropertyName("home_coin_recovery_time"), JsonConverter(typeof(RecoveryTimeJsonConverter))]
+ public TimeSpan HomeCoinRecoveryTime { get; set; }
+
+ ///
+ /// 参量质变仪
+ ///
+ [JsonPropertyName("transformer")]
+ public Transformer Transformer { get; set; }
+
+ ///
+ /// 洞天宝钱是否已满
+ ///
+ [JsonIgnore]
+ public bool IsHomeCoinFull => HomeCoinRecoveryTime == TimeSpan.Zero;
+
+ ///
+ /// 洞天宝钱攒满时刻
+ ///
+ [JsonIgnore]
+ public DateTimeOffset HomeCoinFullTime => NowTime + HomeCoinRecoveryTime;
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/Expedition.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/Expedition.cs
new file mode 100644
index 0000000..8e33f15
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/Expedition.cs
@@ -0,0 +1,38 @@
+namespace XFP.ICora.Hoyolab.DailyNote
+{
+ public class Expedition
+ {
+ ///
+ /// 角色侧面图
+ ///
+ [JsonPropertyName("avatar_side_icon")]
+ public string AvatarSideIcon { get; set; }
+
+ ///
+ /// 状态 Ongoing:派遣中 Finished:已完成
+ ///
+ [JsonPropertyName("status")]
+ public string Status { get; set; }
+
+ [JsonIgnore]
+ public DateTimeOffset NowTime { get; init; } = DateTimeOffset.Now;
+
+ ///
+ /// 剩余时间
+ ///
+ [JsonPropertyName("remained_time"), JsonConverter(typeof(RecoveryTimeJsonConverter))]
+ public TimeSpan RemainedTime { get; set; }
+
+ ///
+ /// 探索派遣是否完成
+ ///
+ [JsonIgnore]
+ public bool IsFinished => RemainedTime == TimeSpan.Zero;
+
+ ///
+ /// 完成时刻
+ ///
+ [JsonIgnore]
+ public DateTimeOffset FinishedTime => NowTime + RemainedTime;
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/RecoveryTimeJsonConverter.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/RecoveryTimeJsonConverter.cs
new file mode 100644
index 0000000..972f704
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/RecoveryTimeJsonConverter.cs
@@ -0,0 +1,23 @@
+namespace XFP.ICora.Hoyolab.DailyNote
+{
+ public class RecoveryTimeJsonConverter : JsonConverter
+ {
+ public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var secondStr = reader.GetString();
+ if (int.TryParse(secondStr, out var second))
+ {
+ return TimeSpan.FromSeconds(second);
+ }
+ else
+ {
+ return TimeSpan.Zero;
+ }
+ }
+
+ public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.TotalSeconds.ToString());
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/Transformer.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/Transformer.cs
new file mode 100644
index 0000000..a83515f
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/Transformer.cs
@@ -0,0 +1,23 @@
+namespace XFP.ICora.Hoyolab.DailyNote
+{
+ public class Transformer
+ {
+ ///
+ /// 是否获得
+ ///
+ [JsonPropertyName("obtained")]
+ public bool Obtained { get; set; }
+
+ ///
+ /// 剩余时间
+ ///
+ [JsonPropertyName("recovery_time")]
+ public TransformerRecoveryTime RecoveryTime { get; set; }
+
+ ///
+ /// Wiki url
+ ///
+ [JsonPropertyName("wiki")]
+ public string Wiki { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/TransformerRecoveryTime.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/TransformerRecoveryTime.cs
new file mode 100644
index 0000000..2cf173c
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DailyNote/TransformerRecoveryTime.cs
@@ -0,0 +1,23 @@
+namespace XFP.ICora.Hoyolab.DailyNote
+{
+ public class TransformerRecoveryTime
+ {
+ [JsonPropertyName("Day")]
+ public int Day { get; set; }
+
+ [JsonPropertyName("Hour")]
+ public int Hour { get; set; }
+
+ [JsonPropertyName("Minute")]
+ public int Minute { get; set; }
+
+ [JsonPropertyName("Second")]
+ public int Second { get; set; }
+
+ ///
+ /// 是否可再次使用
+ ///
+ [JsonPropertyName("reached")]
+ public bool Reached { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DynamicSecret.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DynamicSecret.cs
new file mode 100644
index 0000000..f07638c
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/DynamicSecret.cs
@@ -0,0 +1,61 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+using System.Security.Cryptography;
+using System.Text;
+
+namespace XFP.ICora.Hoyolab
+{
+ public abstract class DynamicSecret
+ {
+ private static readonly string ApiSalt = "N50pqm7FSy2AkFz2B3TqtuZMJ5TOl3Ep";
+
+ private static readonly string ApiSalt2 = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs";
+
+
+ public static string CreateSecret()
+ {
+ var t = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+ string r = GetRandomString(t);
+ var bytes = MD5.HashData(Encoding.UTF8.GetBytes($"salt={ApiSalt}&t={t}&r={r}"));
+ var check = Convert.ToHexString(bytes).ToLower();
+ return $"{t},{r},{check}";
+ }
+
+ public static string CreateSecret2(string url, object? postBody = null)
+ {
+ int t = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+ string r = Random.Shared.Next(100000, 200000).ToString();
+ string b = postBody is null ? "" : JsonSerializer.Serialize(postBody);
+ string q = "";
+ string[] urls = url.Split('?');
+ if (urls.Length == 2)
+ {
+ string[] queryParams = urls[1].Split('&').OrderBy(x => x).ToArray();
+ q = string.Join("&", queryParams);
+ }
+ var bytes = MD5.HashData(Encoding.UTF8.GetBytes($"salt={ApiSalt2}&t={t}&r={r}&b={b}&q={q}"));
+ var check = Convert.ToHexString(bytes).ToLower();
+ string result = $"{t},{r},{check}";
+ return result;
+ }
+
+
+ private static string GetRandomString(int timestamp)
+ {
+ var sb = new StringBuilder(6);
+ var random = new Random((int)timestamp);
+ for (int i = 0; i < 6; i++)
+ {
+ int v8 = random.Next(0, 32768) % 26;
+ int v9 = 87;
+ if (v8 < 10)
+ {
+ v9 = 48;
+ }
+ _ = sb.Append((char)(v8 + v9));
+ }
+ return sb.ToString();
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/GameRecordSummary.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/GameRecordSummary.cs
new file mode 100644
index 0000000..6ed0d6c
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/GameRecordSummary.cs
@@ -0,0 +1,31 @@
+using XFP.ICora.Hoyolab.Avatar;
+
+namespace XFP.ICora.Hoyolab.GameRecord
+{
+ public class GameRecordSummary
+ {
+ ///
+ /// 角色信息
+ ///
+ [JsonPropertyName("avatars")]
+ public List AvatarInfos { get; set; }
+
+ ///
+ /// 冒险统计
+ ///
+ [JsonPropertyName("stats")]
+ public PlayerRiskStats PlayerStat { get; set; }
+
+ ///
+ /// 世界探索
+ ///
+ [JsonPropertyName("world_explorations")]
+ public List WorldExplorations { get; set; }
+
+ ///
+ /// 尘歌壶
+ ///
+ [JsonPropertyName("homes")]
+ public List PotHomes { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/PlayerRiskStats.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/PlayerRiskStats.cs
new file mode 100644
index 0000000..e627b2e
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/PlayerRiskStats.cs
@@ -0,0 +1,112 @@
+using System.ComponentModel;
+
+namespace XFP.ICora.Hoyolab.GameRecord
+{
+ public class PlayerRiskStats
+ {
+ ///
+ /// 活跃天数
+ ///
+ [JsonPropertyName("active_day_number")]
+ [Description("活跃天数")]
+ public int ActiveDayNumber { get; set; }
+
+ ///
+ /// 成就达成数
+ ///
+ [JsonPropertyName("achievement_number")]
+ [Description("成就达成数")]
+ public int AchievementNumber { get; set; }
+
+ ///
+ /// 获得角色数
+ ///
+ [JsonPropertyName("avatar_number")]
+ [Description("获得角色数")]
+ public int AvatarNumber { get; set; }
+
+ ///
+ /// 解锁传送点
+ ///
+ [JsonPropertyName("way_point_number")]
+ [Description("解锁传送点")]
+ public int WayPointNumber { get; set; }
+
+ ///
+ /// 风神瞳
+ ///
+ [JsonPropertyName("anemoculus_number")]
+ [Description("风神瞳")]
+ public int AnemoculusNumber { get; set; }
+
+ ///
+ /// 岩神瞳
+ ///
+ [JsonPropertyName("geoculus_number")]
+ [Description("岩神瞳")]
+ public int GeoculusNumber { get; set; }
+
+ ///
+ /// 雷神瞳
+ ///
+ [JsonPropertyName("electroculus_number")]
+ [Description("雷神瞳")]
+ public int ElectroculusNumber { get; set; }
+
+ ///
+ /// 草神瞳
+ ///
+ [JsonPropertyName("dendroculus_number")]
+ [Description("草神瞳")]
+ public int DendroculusNumber { get; set; }
+
+ ///
+ /// 解锁秘境
+ ///
+ [JsonPropertyName("domain_number")]
+ [Description("解锁秘境")]
+ public int DomainNumber { get; set; }
+
+ ///
+ /// 深境螺旋
+ ///
+ [JsonPropertyName("spiral_abyss")]
+ [Description("深境螺旋")]
+ public string SpiralAbyss { get; set; }
+
+ ///
+ /// 华丽宝箱
+ ///
+ [JsonPropertyName("luxurious_chest_number")]
+ [Description("华丽宝箱")]
+ public int LuxuriousChestNumber { get; set; }
+
+ ///
+ /// 珍贵宝箱
+ ///
+ [JsonPropertyName("precious_chest_number")]
+ [Description("珍贵宝箱")]
+ public int PreciousChestNumber { get; set; }
+
+ ///
+ /// 精致宝箱
+ ///
+ [JsonPropertyName("exquisite_chest_number")]
+ [Description("精致宝箱")]
+ public int ExquisiteChestNumber { get; set; }
+
+ ///
+ /// 普通宝箱
+ ///
+ [JsonPropertyName("common_chest_number")]
+ [Description("普通宝箱")]
+ public int CommonChestNumber { get; set; }
+
+ ///
+ /// 奇馈宝箱
+ ///
+ [JsonPropertyName("magic_chest_number")]
+ [Description("奇馈宝箱")]
+ public int MagicChestNumber { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/PotHome.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/PotHome.cs
new file mode 100644
index 0000000..a6ca787
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/PotHome.cs
@@ -0,0 +1,55 @@
+namespace XFP.ICora.Hoyolab.GameRecord
+{
+ public class PotHome
+ {
+ ///
+ /// 信任等阶
+ ///
+ [JsonPropertyName("level")]
+ public int Level { get; set; }
+
+ ///
+ /// 历史访客数
+ ///
+ [JsonPropertyName("visit_num")]
+ public int VisitNumber { get; set; }
+
+ ///
+ /// 最高洞天仙力
+ ///
+ [JsonPropertyName("comfort_num")]
+ public int ComfortNumber { get; set; }
+
+ ///
+ /// 摆设数
+ ///
+ [JsonPropertyName("item_num")]
+ public int ItemNumber { get; set; }
+
+ ///
+ /// 洞天名称
+ ///
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+ ///
+ /// 洞天图片
+ ///
+ ///
+ [JsonPropertyName("icon")]
+ public string Icon { get; set; }
+
+ ///
+ /// 仙力等级名称
+ ///
+ [JsonPropertyName("comfort_level_name")]
+ public string ComfortLevelName { get; set; }
+
+ ///
+ /// 仙力等级图标
+ ///
+ ///
+ [JsonPropertyName("comfort_level_icon")]
+ public string ComfortLevelIcon { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExploration.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExploration.cs
new file mode 100644
index 0000000..3c0d31d
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExploration.cs
@@ -0,0 +1,74 @@
+namespace XFP.ICora.Hoyolab.GameRecord
+{
+ public class WorldExploration
+ {
+ [JsonPropertyName("id")]
+ public int Id { get; set; }
+
+ ///
+ /// 地区名称
+ ///
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+ ///
+ /// 探索等级
+ ///
+ [JsonPropertyName("level")]
+ public int Level { get; set; }
+
+ ///
+ /// 探索度,满值 1000
+ ///
+ [JsonPropertyName("exploration_percentage")]
+ public int ExplorationPercentage { get; set; }
+
+ ///
+ /// 地区卡片背景图
+ ///
+ ///
+ [JsonPropertyName("background_image")]
+ public string BackgroundImage { get; set; }
+
+ ///
+ /// 地区封面背景图
+ ///
+ ///
+ [JsonPropertyName("cover")]
+ public string Cover { get; set; }
+
+ ///
+ /// 地区图标(白色)
+ ///
+ ///
+ [JsonPropertyName("icon")]
+ public string Icon { get; set; }
+
+ ///
+ /// 地区图标(黑色)
+ ///
+ ///
+ [JsonPropertyName("inner_icon")]
+ public string InnerIcon { get; set; }
+
+ ///
+ /// 米游社地图
+ ///
+ ///
+ [JsonPropertyName("map_url")]
+ public string MapUrl { get; set; }
+
+
+ ///
+ /// 地区探索奖励类型(声望,贡品)
+ ///
+ [JsonPropertyName("type"), JsonConverter(typeof(JsonStringEnumConverter))]
+ public WorldExplorationRewardType Type { get; set; }
+
+ ///
+ /// 地区贡品等级
+ ///
+ [JsonPropertyName("offerings")]
+ public List Offerings { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExplorationOffering.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExplorationOffering.cs
new file mode 100644
index 0000000..09febe0
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExplorationOffering.cs
@@ -0,0 +1,17 @@
+namespace XFP.ICora.Hoyolab.GameRecord
+{
+ public class WorldExplorationOffering
+ {
+ [JsonPropertyName("name")]
+ public string Name { get; set; }
+
+
+ [JsonPropertyName("level")]
+ public int Level { get; set; }
+
+
+ [JsonPropertyName("icon")]
+ public string Icon { get; set; }
+ }
+}
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExplorationRewardType.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExplorationRewardType.cs
new file mode 100644
index 0000000..b1e26b1
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/GameRecord/WorldExplorationRewardType.cs
@@ -0,0 +1,15 @@
+namespace XFP.ICora.Hoyolab.GameRecord
+{
+ public enum WorldExplorationRewardType
+ {
+ ///
+ /// 声望
+ ///
+ Reputation,
+
+ ///
+ /// 贡品
+ ///
+ Offering,
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/HoyolabBaseWrapper.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/HoyolabBaseWrapper.cs
new file mode 100644
index 0000000..3eb6f8d
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/HoyolabBaseWrapper.cs
@@ -0,0 +1,17 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Hoyolab
+{
+ public class HoyolabBaseWrapper where T : class
+ {
+ [JsonPropertyName("returncode")]
+ public int ReturnCode { get; set; }
+
+ [JsonPropertyName("message")]
+ public string? Message { get; set; }
+
+ [JsonPropertyName("data")]
+ public T Data { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/HoyolabClient.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/HoyolabClient.cs
new file mode 100644
index 0000000..5caf4c4
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/HoyolabClient.cs
@@ -0,0 +1,236 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+using System.Net.Http;
+using System.Net.Http.Json;
+using System.Threading.Tasks;
+using XFP.ICora.Hoyolab.DailyNote;
+using XFP.ICora.Hoyolab.GameRecord;
+using XFP.ICora.Hoyolab.TravelNotes;
+using XFP.ICora.ICoraException;
+
+namespace XFP.ICora.Hoyolab
+{
+ public class HoyolabClient
+ {
+ #region Header
+ private const string Accept = "Accept";
+ private const string Cookie = "Cookie";
+ private const string UserAgent = "User-Agent";
+ private const string X_Reuqest_With = "X-Requested-With";
+ private const string DS = "DS";
+ private const string Referer = "Referer";
+ private const string Application_Json = "application/json";
+ private const string com_mihoyo_hyperion = "com.mihoyo.hyperion";
+ private const string x_rpc_app_version = "x-rpc-app_version";
+ private const string x_rpc_device_id = "x-rpc-device_id";
+ private const string x_rpc_client_type = "x-rpc-client_type";
+ private const string UAContent = $"Mozilla/5.0 miHoYoBBS/{AppVersion}";
+ private const string AppVersion = "2.35.2";
+ private static readonly string DeviceId = Guid.NewGuid().ToString("D");
+ #endregion
+
+ private readonly HttpClient httpClient;
+
+ ///
+ /// 构造一个新的hoyolabclient
+ ///
+ ///
+ public HoyolabClient(HttpClient? httpClient = null)
+ {
+ this.httpClient = httpClient ?? new(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.All });
+ }
+
+ private async Task CommonSendAsync(
+ HttpRequestMessage request,
+ CancellationToken? cancellationToken = null) where T : class
+ {
+ request.Headers.Add(Accept, Application_Json);
+ request.Headers.Add(UserAgent, UAContent);
+ var response = await httpClient.SendAsync(request, cancellationToken ?? CancellationToken.None);
+ response.EnsureSuccessStatusCode();
+ var content = await response.Content.ReadAsStringAsync();
+ var responseData = JsonSerializer.Deserialize>(content);
+ if (responseData is null)
+ {
+ Growl.Clear();
+ Growl.Error("Can not parse the response body. (-1)");
+ }
+ if (responseData.ReturnCode != 0)
+ {
+ Growl.Clear();
+ Growl.Error($"Ex: {responseData.Message} ({responseData.ReturnCode})");
+ }
+ return responseData.Data;
+ }
+
+ ///
+ /// 更新米游社数据
+ ///
+ ///
+ public async Task UpdateAllAccountsAsync()
+ {
+ try
+ {
+ await GetHoyolabUserInfoAsync(Properties.Settings.Default.UserCookie!);
+ await GetGenshinRoleInfoListAsync(Properties.Settings.Default.UserCookie!);
+ }
+ catch (Exception ex)
+ {
+ Growl.Clear();
+ Growl.Error($"in update user account\n{ex.Message} (-2)");
+ }
+ }
+
+ public async Task SignInAsync(GenshinRoleInfo role, bool skipCheckWhetherHaveSignedIn = false, CancellationToken? cancellationToken = null)
+ {
+ if (!skipCheckWhetherHaveSignedIn)
+ {
+ var signInfo = await GetSignInInfoAsync(role, cancellationToken);
+ if (signInfo.IsSign)
+ {
+ return false;
+ }
+ }
+ var obj = new { act_id = "e202009291139501", region = role.Region.ToString(), uid = role.Uid.ToString() };
+ var request = new HttpRequestMessage(HttpMethod.Post, "https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign");
+ request.Headers.Add(Cookie, role.Cookie);
+ request.Headers.Add(DS, DynamicSecret.CreateSecret());
+ request.Headers.Add(x_rpc_app_version, AppVersion);
+ request.Headers.Add(x_rpc_device_id, DeviceId);
+ request.Headers.Add(x_rpc_client_type, "5");
+ request.Headers.Add(X_Reuqest_With, com_mihoyo_hyperion);
+ request.Headers.Add(Referer, "https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true&act_id=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon");
+ request.Content = JsonContent.Create(obj);
+ var risk = await CommonSendAsync(request, cancellationToken);
+ if (risk is null or { RiskCode: 0, Success: 0 })
+ {
+ return true;
+ }
+ else
+ {
+ Growl.Clear();
+ Growl.Warning($"账户 {role.Nickname} 受到风控限制 请手动签到");
+ return false;
+ }
+ }
+
+ ///
+ /// 实时便笺
+ ///
+ ///
+ ///
+ ///
+ public async Task GetDailyNoteAsync(GenshinRoleInfo role, CancellationToken? cancellationToken = null)
+ {
+ var url = $"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/dailyNote?server={role.Region}&role_id={role.Uid}";
+ var request = new HttpRequestMessage(HttpMethod.Get, url);
+ request.Headers.Add(Cookie, role.Cookie);
+ request.Headers.Add(DS, DynamicSecret.CreateSecret2(url));
+ request.Headers.Add(Referer, "https://webstatic.mihoyo.com/app/community-game-records/?game_id=2&utm_source=bbs&utm_medium=mys&utm_campaign=box");
+ request.Headers.Add(x_rpc_app_version, AppVersion);
+ request.Headers.Add(x_rpc_client_type, "5");
+ request.Headers.Add(X_Reuqest_With, com_mihoyo_hyperion);
+ var data = await CommonSendAsync(request);
+ data.Uid = role.Uid;
+ data.Nickname = role.Nickname;
+ return data;
+ }
+
+ ///
+ /// 旅行札记总览
+ ///
+ ///
+ /// 0 当前月
+ ///
+ ///
+ public async Task GetTravelNotesSummaryAsync(GenshinRoleInfo role, int month = 0, CancellationToken? cancellationToken = null)
+ {
+ var url = $"https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo?month={month}&bind_uid={role.Uid}&bind_region={role.Region}&bbs_presentation_style=fullscreen&bbs_auth_required=true&utm_source=bbs&utm_medium=mys&utm_campaign=icon";
+ var request = new HttpRequestMessage(HttpMethod.Get, url);
+ request.Headers.Add(Cookie, role.Cookie);
+ request.Headers.Add(Referer, "https://webstatic.mihoyo.com/ys/event/e20200709ysjournal/index.html?bbs_presentation_style=fullscreen&bbs_auth_required=true&utm_source=bbs&utm_medium=mys&utm_campaign=icon");
+ request.Headers.Add(X_Reuqest_With, com_mihoyo_hyperion);
+ return await CommonSendAsync(request);
+ }
+
+ ///
+ /// 账号的签到信息
+ ///
+ ///
+ ///
+ public async Task GetSignInInfoAsync(GenshinRoleInfo role, CancellationToken? cancellationToken = null)
+ {
+ var request = new HttpRequestMessage(HttpMethod.Get, $"https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?act_id=e202009291139501®ion={role.Region}&uid={role.Uid}");
+ request.Headers.Add(Cookie, role.Cookie);
+ request.Headers.Add(x_rpc_device_id, DeviceId);
+ request.Headers.Add(X_Reuqest_With, com_mihoyo_hyperion);
+ request.Headers.Add(Referer, "https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true&act_id=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon");
+ return await CommonSendAsync(request, cancellationToken);
+ }
+
+ ///
+ /// 米游社账号信息
+ ///
+ ///
+ public async Task GetHoyolabUserInfoAsync(string cookie, CancellationToken? cancellationToken = null)
+ {
+ if (string.IsNullOrWhiteSpace(cookie))
+ {
+ new ContentEmptyException().ContentIsEmpty(cookie, -1);
+ }
+ var request = new HttpRequestMessage(HttpMethod.Get, "https://bbs-api.mihoyo.com/user/wapi/getUserFullInfo?gids=2");
+ request.Headers.Add(Cookie, cookie);
+ request.Headers.Add(Referer, "https://bbs.mihoyo.com/");
+ request.Headers.Add(DS, DynamicSecret.CreateSecret());
+ request.Headers.Add(x_rpc_app_version, AppVersion);
+ request.Headers.Add(x_rpc_device_id, DeviceId);
+ request.Headers.Add(x_rpc_client_type, "5");
+ var data = await CommonSendAsync(request, cancellationToken);
+ data.HoyolabUserInfo.Cookie = cookie;
+ return data.HoyolabUserInfo;
+ }
+
+ ///
+ /// 获取原神账号信息
+ ///
+ ///
+ public async Task> GetGenshinRoleInfoListAsync(string cookie, CancellationToken? cancellationToken = null)
+ {
+ if (string.IsNullOrWhiteSpace(cookie))
+ {
+ new ContentEmptyException().ContentIsEmpty(cookie, -1);
+ }
+ var url = "https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hk4e_cn";
+ var request = new HttpRequestMessage(HttpMethod.Get, url);
+ request.Headers.Add(Cookie, cookie);
+ request.Headers.Add(DS, DynamicSecret.CreateSecret2(url));
+ request.Headers.Add(X_Reuqest_With, com_mihoyo_hyperion);
+ request.Headers.Add(x_rpc_app_version, AppVersion);
+ request.Headers.Add(x_rpc_client_type, "5");
+ request.Headers.Add(Referer, "https://webstatic.mihoyo.com/app/community-game-records/?game_id=2&utm_source=bbs&utm_medium=mys&utm_campaign=box");
+ var data = await CommonSendAsync(request, cancellationToken);
+ data.List?.ForEach(x => x.Cookie = cookie);
+ return data.List ?? new List();
+ }
+
+ ///
+ /// 获取用户战绩
+ ///
+ ///
+ ///
+ ///
+ public async Task GetGameRecordAsync(GenshinRoleInfo role, CancellationToken? cancellationToken = null)
+ {
+ var url = $"https://api-takumi-record.mihoyo.com/game_record/app/genshin/api/index?server={role.Region}&role_id={role.Uid}";
+ var request = new HttpRequestMessage(HttpMethod.Get, url);
+ request.Headers.Add(Cookie, role.Cookie);
+ request.Headers.Add(DS, DynamicSecret.CreateSecret2(url));
+ request.Headers.Add(Referer, "https://webstatic.mihoyo.com/app/community-game-records/?game_id=2&utm_source=bbs&utm_medium=mys&utm_campaign=box");
+ request.Headers.Add(x_rpc_app_version, AppVersion);
+ request.Headers.Add(x_rpc_client_type, "5");
+ request.Headers.Add(X_Reuqest_With, com_mihoyo_hyperion);
+ return await CommonSendAsync(request);
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesBase.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesBase.cs
new file mode 100644
index 0000000..b0feb61
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesBase.cs
@@ -0,0 +1,46 @@
+namespace XFP.ICora.Hoyolab.TravelNotes
+{
+ public class TravelNotesBase
+ {
+ [JsonPropertyName("uid")]
+ public int Uid { get; set; }
+
+
+ [JsonPropertyName("region"), JsonConverter(typeof(JsonStringEnumConverter))]
+ public RegionType Region { get; set; }
+
+ ///
+ /// 米游社 ID
+ ///
+ [JsonPropertyName("account_id")]
+ public int AccountId { get; set; }
+
+
+ [JsonPropertyName("nickname")]
+ public string Nickname { get; set; }
+
+ ///
+ /// 当前日期
+ ///
+ [JsonPropertyName("date"), JsonConverter(typeof(TravelNotesDateJsonConverter))]
+ public DateTime Date { get; set; }
+
+ ///
+ /// 当前月
+ ///
+ [JsonPropertyName("month")]
+ public int CurrentMonth { get; set; }
+
+ ///
+ /// 可查询月份
+ ///
+ [JsonPropertyName("optional_month")]
+ public List OptionalMonth { get; set; }
+
+ ///
+ /// 获取的数据所在的月份
+ ///
+ [JsonPropertyName("data_month")]
+ public int DataMonth { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesDateJsonConverter.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesDateJsonConverter.cs
new file mode 100644
index 0000000..42e7387
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesDateJsonConverter.cs
@@ -0,0 +1,15 @@
+namespace XFP.ICora.Hoyolab.TravelNotes
+{
+ public class TravelNotesDateJsonConverter : JsonConverter
+ {
+ public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return DateTime.Parse(reader.GetString()!);
+ }
+
+ public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesDayData.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesDayData.cs
new file mode 100644
index 0000000..bf3a2b9
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesDayData.cs
@@ -0,0 +1,20 @@
+namespace XFP.ICora.Hoyolab.TravelNotes
+{
+ public class TravelNotesDayData
+ {
+ [JsonPropertyName("current_primogems")]
+ public int CurrentPrimogems { get; set; }
+
+
+ [JsonPropertyName("current_mora")]
+ public int CurrentMora { get; set; }
+
+
+ [JsonPropertyName("last_primogems")]
+ public int LastPrimogems { get; set; }
+
+
+ [JsonPropertyName("last_mora")]
+ public int LastMora { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesMonthData.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesMonthData.cs
new file mode 100644
index 0000000..d7d9da5
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesMonthData.cs
@@ -0,0 +1,60 @@
+namespace XFP.ICora.Hoyolab.TravelNotes
+{
+ public class TravelNotesMonthData
+ {
+ public int Uid { get; set; }
+
+ public int Year { get; set; }
+
+ public int Month { get; set; }
+
+
+ ///
+ /// 查询月原石数
+ ///
+ [JsonPropertyName("current_primogems")]
+ public int CurrentPrimogems { get; set; }
+
+ ///
+ /// 查询月摩拉数
+ ///
+ [JsonPropertyName("current_mora")]
+ public int CurrentMora { get; set; }
+
+ ///
+ /// 查询月上一月原石数
+ ///
+ [JsonPropertyName("last_primogems")]
+ public int LastPrimogems { get; set; }
+
+ ///
+ /// 查询月上一月摩拉数
+ ///
+ [JsonPropertyName("last_mora")]
+ public int LastMora { get; set; }
+
+ ///
+ /// 不知道什么意思
+ ///
+ [JsonPropertyName("current_primogems_level")]
+ public int CurrentPrimogemsLevel { get; set; }
+
+ ///
+ /// 相比于上一月原石的增长率,单位为百分数
+ ///
+ [JsonPropertyName("primogems_rate")]
+ public int PrimogemsChangeRate { get; set; }
+
+ ///
+ /// 相比于上一月摩拉的增长率,单位为百分数
+ ///
+ [JsonPropertyName("mora_rate")]
+ public int MoraChangeRate { get; set; }
+
+ ///
+ /// 原石获取来源分组统计
+ ///
+ [JsonPropertyName("group_by")]
+ public List PrimogemsGroupBy { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesPrimogemsMonthGroupStats.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesPrimogemsMonthGroupStats.cs
new file mode 100644
index 0000000..5f7d608
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesPrimogemsMonthGroupStats.cs
@@ -0,0 +1,30 @@
+namespace XFP.ICora.Hoyolab.TravelNotes
+{
+ public class TravelNotesPrimogemsMonthGroupStats
+ {
+ [JsonIgnore]
+ public int Id { get; set; }
+
+ public int Uid { get; set; }
+
+ public int Year { get; set; }
+
+ public int Month { get; set; }
+
+
+ [JsonPropertyName("action_id")]
+ public int ActionId { get; set; }
+
+
+ [JsonPropertyName("action")]
+ public string? ActionName { get; set; }
+
+
+ [JsonPropertyName("num")]
+ public int Number { get; set; }
+
+
+ [JsonPropertyName("percent")]
+ public int Percent { get; set; }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesSummary.cs b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesSummary.cs
new file mode 100644
index 0000000..d9efb15
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Hoyolab/TravelNotes/TravelNotesSummary.cs
@@ -0,0 +1,43 @@
+namespace XFP.ICora.Hoyolab.TravelNotes
+{
+ public class TravelNotesSummary : TravelNotesBase, IJsonOnDeserialized
+ {
+ ///
+ /// 查询月份的上个月
+ ///
+ [JsonPropertyName("data_last_month")]
+ public int DataLastMonth { get; set; }
+
+ ///
+ /// 今日数据,查询月份不是当前月时,数据内容均为0
+ ///
+ [JsonPropertyName("day_data")]
+ public TravelNotesDayData DayData { get; set; }
+
+ ///
+ /// 查询月数据
+ ///
+ [JsonPropertyName("month_data")]
+ public TravelNotesMonthData MonthData { get; set; }
+
+ ///
+ /// 不知道是什么
+ ///
+ [JsonPropertyName("lantern")]
+ public bool Lantern { get; set; }
+
+ public void OnDeserialized()
+ {
+ var year = DataMonth > Date.Month ? Date.Year - 1 : Date.Year;
+ MonthData.Uid = Uid;
+ MonthData.Year = year;
+ MonthData.Month = DataMonth;
+ foreach (var item in MonthData.PrimogemsGroupBy)
+ {
+ item.Uid = Uid;
+ item.Year = year;
+ item.Month = DataMonth;
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/ICoraException/ContentEmptyException.cs b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/ContentEmptyException.cs
new file mode 100644
index 0000000..17a0072
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/ContentEmptyException.cs
@@ -0,0 +1,24 @@
+//Copyright(C) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT Licensed.
+
+namespace XFP.ICora.ICoraException
+{
+ public class ContentEmptyException
+ {
+ private int ReturnCode { get; set; }
+
+ public void ContentIsEmpty(string content, int returnCode)
+ {
+ returnCode = ReturnCode;
+ Growl.Clear();
+ Growl.Error($"Throw Exception : The content is empty || {content}\n Return Code{returnCode}");
+ }
+
+ public void UserInfoIsEmpty(string content, int returnCode)
+ {
+ returnCode = ReturnCode;
+ Growl.Clear();
+ Growl.Error($"Throw Exception : The User info is empty || {content}\n Return Code{returnCode}");
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/ICoraException/DirectoryNotFound.cs b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/DirectoryNotFound.cs
new file mode 100644
index 0000000..b875d96
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/DirectoryNotFound.cs
@@ -0,0 +1,32 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.ICoraException
+{
+ public class DirectoryNotFound
+ {
+ ///
+ /// File directory not found
+ ///
+ /// Directory name that does not exist
+ public DirectoryNotFound(string DirectoryName)
+ {
+ Growl.Error("Throw Exception: Directory Not Found\n Directory Name:" + DirectoryName);
+ }
+
+ ///
+ /// File directory not found
+ /// Create directory selectively
+ ///
+ /// Directory name that does not exist
+ /// Selectively create the current directory
+ public DirectoryNotFound(string DirectoryName, bool CreateDirectory)
+ {
+ Growl.Warning("Throw Exception: Directory Not Found\n Directory Name:" + DirectoryName);
+ if (CreateDirectory == true)
+ {
+ Directory.CreateDirectory(DirectoryName);
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/ICoraException/HoyolabException.cs b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/HoyolabException.cs
new file mode 100644
index 0000000..cffc060
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/HoyolabException.cs
@@ -0,0 +1,12 @@
+namespace XFP.ICora.ICoraException
+{
+ public class HoyolabException : Exception
+ {
+ public int ReturnCode { get; init; }
+
+ public HoyolabException(int returnCode, string message) : base($"{message}({returnCode})")
+ {
+ ReturnCode = returnCode;
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/ICoraException/IncompleteFile.cs b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/IncompleteFile.cs
new file mode 100644
index 0000000..63b104f
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/IncompleteFile.cs
@@ -0,0 +1,47 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.ICoraException
+{
+ public class IncompleteFile
+ {
+ LogWriter log = new();
+
+ ///
+ /// Incomplete file
+ ///
+ /// File Name
+ public void FileIsNotComplete(string FileName)
+ {
+ Growl.Error("Throw Exception: File Is Not Found\n File Name:" + FileName);
+ log.ErrorLog("Throw Exception: File Is Not Found\n File Name:" + FileName, -10);
+ }
+
+ ///
+ /// Target File Not Found
+ ///
+ /// Target File
+ public void FileNotFound(string TargetFile)
+ {
+ Growl.Error("Throw Exception: Target File Not Found\n Target File Name:" + TargetFile);
+ log.ErrorLog("Throw Exception: Target File Not Found\n Target File Name:" + TargetFile, -10);
+ }
+
+ ///
+ /// Target File Not Found
+ /// Create directory selectively
+ ///
+ /// Target File
+ /// Selectively create the current directory
+ public void FileNotFound(string TargetFile, bool CreateTargetFile)
+ {
+ Growl.Warning("Throw Exception: Target File Not Found\n Target File Name:" + TargetFile);
+ log.ErrorLog("Throw Exception: Target File Not Found\n Target File Name:" + TargetFile, -10);
+ if (CreateTargetFile == true)
+ {
+ File.Create(TargetFile);
+ log.TempLog("Create File" + TargetFile);
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/ICoraException/UnKnownChoose.cs b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/UnKnownChoose.cs
new file mode 100644
index 0000000..4307838
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/ICoraException/UnKnownChoose.cs
@@ -0,0 +1,20 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.ICoraException
+{
+ public class UnKnownChoose
+ {
+ LogWriter log = new();
+
+ ///
+ /// Unknown user selection
+ ///
+ ///
+ public UnKnownChoose(string UserChoose)
+ {
+ Growl.Error("Throw Exception Un Known Choose : " + UserChoose);
+ log.ErrorLog("Throw Exception Un Known Choose : " + UserChoose, -10);
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/MainWindow.xaml b/XFP.Impact_Ultimate/XFP.Cora/MainWindow.xaml
new file mode 100644
index 0000000..f5b5b72
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/MainWindow.xaml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/MainWindow.xaml.cs b/XFP.Impact_Ultimate/XFP.Cora/MainWindow.xaml.cs
new file mode 100644
index 0000000..578bb37
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/MainWindow.xaml.cs
@@ -0,0 +1,323 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora
+{
+ ///
+ /// MainWindow.xaml 的交互逻辑
+ ///
+ public partial class MainWindow
+ {
+ #region initialization
+
+ DataProvider data = new();
+ LogWriter log = new();
+ GetFormUrl GetFormUrl = new GetFormUrl();
+ Notifiaction notifiaction = new();
+
+ #endregion
+
+ RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software", true).CreateSubKey("Impact_Ultimate");
+
+ private ObservableCollection _MenuList;
+ public ObservableCollection MenuList
+ {
+ get { return _MenuList; }
+ set { _MenuList = value; }
+ }
+
+ private ObservableCollection _settingsMenu;
+ public ObservableCollection settingsMenu
+ {
+ get { return _settingsMenu; }
+ set { _settingsMenu = value; }
+ }
+
+ public MainWindow() => Initialization();
+
+ private void Initialization()
+ {
+ if (key.GetValue("UserAgree") == null)
+ {
+ if (HandyControl.Controls.MessageBox.Show("你好旅行者!欢迎来到ICora\nICora是一款免费使用的原神工具箱 如果您是付费买来的 您已经被骗了\n由于ICora内置Dll注入的模块 所以可能会遭受到一定程度的倒卖 如果您是免费使用的 不妨查看一下下面的内容\nICora提供服务的QQ群:\n\t原神交流一群 811979687 || 原神交流二群 590566763\nICora用户隐私协议:https://gitee.com/MasterGashByte/impact_ultimate_issues/blob/master/PrivacyPolicy.md\nICora用户使用协议:https://gitee.com/MasterGashByte/impact_ultimate_issues/blob/master/UserUseAgreement.md\n点击 [是] 则代表同意以上条款并继续使用ICora\n\t\t(此弹窗不会弹出第二次)", "欢迎你 旅行者!", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+ {
+ Environment.Exit(0);
+ }
+ else
+ {
+ key.SetValue("UserAgree", "True");
+ }
+ }
+
+ InitializeComponent();
+
+ // 初始化数据
+ new DataProvider();
+ new DataProvider().Initialize();
+
+ // 窗口居中
+ WindowStartupLocation = WindowStartupLocation.CenterScreen;
+
+ // 用于绘制标题栏
+ NonClientAreaContent = new NonClientAreaContent();
+
+ // 实例化
+ MenuList = new ObservableCollection();
+ settingsMenu = new ObservableCollection();
+
+ #region BackGround
+ // 通过笔刷进行绘制背景图片 后期用户可以自定义背景图片
+ //if (File.Exists(Environment.CurrentDirectory + "\\bg\\BackGround.png"))
+ //{
+ // ImageBrush b = new ImageBrush();
+ // b.ImageSource = new BitmapImage(new Uri(Environment.CurrentDirectory + "\\bg\\BackGround.png"));
+ // b.Stretch = Stretch.Fill;
+ // Background = b;
+ //}
+ #endregion
+
+ #region Basic
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "主页",
+ GroupName = ControlType.基础功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "开始游戏",
+ GroupName = ControlType.基础功能.ToString(),
+ });
+ #endregion
+
+ #region Form
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "祈愿记录",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "角色练度",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "螺旋深渊",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "养成计划",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "成就管理",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "活动公告",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "图鉴管理",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "过场动画",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "游戏公告",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "米哈游账户",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "自定义便签",
+ GroupName = ControlType.更多功能.ToString(),
+ });
+
+ #endregion
+
+ #region View
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "关于我们",
+ GroupName = ControlType.关于.ToString(),
+ });
+ MenuList.Add(new MenuInfo()
+ {
+ Name = "友商论坛",
+ GroupName = ControlType.关于.ToString(),
+ });
+ #endregion
+
+ #region other
+ settingsMenu.Add(new MenuInfo()
+ {
+ Name = "设置",
+ });
+ settingsMenu.Add(new MenuInfo()
+ {
+ Name = "登录",
+ });
+ #endregion
+
+ menu.ItemsSource = MenuList;
+ SettingsMenu.ItemsSource = settingsMenu;
+
+ ControlPanel.Content = new HomePage();
+
+ menu.SelectionChanged += menu_SelectionChanged;
+ SettingsMenu.SelectionChanged += SettingsMenu_SelectionChanged;
+
+ Growl.SuccessGlobal("岁月不居 时节如流 我们再一次迎来了新的一年\n我代表XFP全体团员 在此祝您\n兔年大吉!心想事成!万事如意!财源广进!四季平安!");
+
+ new Thread(() =>
+ {
+ bool _Info = false;
+ var _ServerVesion = string.Empty;
+ while (true)
+ {
+ var ServerVesion =
+ GetFormUrl.Get("https://gitee.com/MasterGashByte/updates/raw/master/Checker/Version");
+ var version = new DataProvider().Version;
+ if (version != ServerVesion)
+ {
+ var MustUpdate =
+ GetFormUrl.Get("https://gitee.com/MasterGashByte/updates/raw/master/Checker/MustUpdate");
+ if (MustUpdate == "true")
+ {
+ MessageBox.Show("这是一个必须更新的版本 正在打开 [更新助手]");
+
+ var localpath = Environment.CurrentDirectory;
+ if (File.Exists(localpath + "\\Updater.exe")
+ && File.Exists(localpath + "\\Updater.deps.json")
+ && File.Exists(localpath + "\\Updater.dll")
+ && File.Exists(localpath + "\\Updater.runtimeconfig.json"))
+ {
+ Process.Start(localpath + "\\Updater.exe");
+ }
+ else
+ {
+ MessageBox.Show("您的ICora仿佛不齐全 请前往群中重新下载");
+ log.ErrorLog("DetectionSystem: ICora is incomplete", -0, "您的ICora不是完整的 您可以前往群中获取完整的ICora");
+ }
+
+ Environment.Exit(0);
+ }
+
+
+ if (_ServerVesion != ServerVesion)
+ {
+ if (!_Info)
+ {
+ Growl.InfoGlobal($"ICora找到新版本啦!\n发现新版本啦,快去更新吧~(版本号:{ServerVesion})");
+ _ServerVesion = ServerVesion;
+ _Info = true;
+ }
+ }
+ _Info = false;
+ }
+ Thread.Sleep(1800000);
+ }
+ }).Start();
+ }
+
+ private void SettingsMenu_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (SettingsMenu.SelectedItem != null)
+ {
+ menu.SelectedItem = null;
+ MenuInfo info = SettingsMenu.SelectedItem as MenuInfo;
+ switch (info.Name)
+ {
+ case "设置":
+ ControlPanel.Content = new Controls.Basic.Settings();
+ break;
+ case "登录":
+ ControlPanel.Content = new Controls.Basic.LoginFormMihoyo();
+ break;
+ }
+ }
+ }
+
+ private void menu_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (menu.SelectedItem != null)
+ {
+ SettingsMenu.SelectedItem = null;
+ MenuInfo info = menu.SelectedItem as MenuInfo;
+ switch (info.Name)
+ {
+ case "主页":
+ ControlPanel.Content = new HomePage();
+ break;
+ case "开始游戏":
+ ControlPanel.Content = new AkebiPage();
+ break;
+ case "友商论坛":
+ Growl.Clear();
+ Growl.Success("正在访问 [入梦论坛] !");
+ Process.Start("explorer.exe", "https://www.rmlt.xyz/");
+ break;
+ case "关于我们":
+ ControlPanel.Content = new AboutUs();
+ break;
+ case "祈愿记录":
+ Growl.Clear();
+ Growl.Warning("此按钮将在下一个版本开放~我们已经编写完成咯!");
+ break;
+ case "米哈游账户":
+ ControlPanel.Content = new HoyolabAccount();
+ break;
+ default:
+ ControlPanel.Content = new HomePage();
+ Growl.Clear();
+ Growl.Warning("暂未开发\n请期待下个版本");
+ break;
+ }
+ }
+ }
+
+ protected override void OnClosed(EventArgs e)
+ {
+ Environment.Exit(0);
+ base.OnClosed(e);
+ }
+
+ private void UpdateButton_Click(object sender, RoutedEventArgs e)
+ {
+ var localpath = Environment.CurrentDirectory;
+ if (File.Exists(localpath + "\\Updater.exe")
+ && File.Exists(localpath + "\\Updater.deps.json")
+ && File.Exists(localpath + "\\Updater.dll")
+ && File.Exists(localpath + "\\Updater.runtimeconfig.json"))
+ {
+ Process.Start("explorer.exe", localpath + "\\Updater.exe");
+ Environment.Exit(0);
+ }
+ else
+ {
+ Growl.Error("您的ICora仿佛不完整");
+ log.ErrorLog("DetectionSystem: Impact_Ultimate is incomplete", -0, "您的Impact_Ultimate不是完整的 您可以前往群中获取完整的Impact_Ultiamte");
+ }
+ }
+ }
+
+ public enum ControlType
+ {
+ 基础功能,
+ 更多功能,
+ 关于,
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Properties/AssemblyInfo.cs b/XFP.Impact_Ultimate/XFP.Cora/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..375bad7
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("Impact_Ultimate")]
+[assembly: AssemblyDescription("由XFP团队全体开发的多功能的原神启动器")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("XFP-Group")]
+[assembly: AssemblyProduct("XFP.ICora")]
+[assembly: AssemblyCopyright("Copyright © 2022 . GashByte")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+//若要开始生成可本地化的应用程序,请设置
+//.csproj 文件中的 CultureYouAreCodingWith
+//例如,如果您在源文件中使用的是美国英语,
+//使用的是美国英语,请将 设置为 en-US。 然后取消
+//对以下 NeutralResourceLanguage 特性的注释。 更新
+//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //主题特定资源词典所处位置
+ //(未在页面中找到资源时使用,
+ //或应用程序资源字典中找到时使用)
+ ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
+ //(未在页面中找到资源时使用,
+ //、应用程序或任何主题专用资源字典中找到时使用)
+)]
+
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.0.1.0")]
+[assembly: AssemblyFileVersion("0.0.1.0")]
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Properties/Resources.Designer.cs b/XFP.Impact_Ultimate/XFP.Cora/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..74914c3
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本: 4.0.30319.42000
+//
+// 对此文件的更改可能导致不正确的行为,如果
+// 重新生成代码,则所做更改将丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace XFP.ICora.Properties
+{
+
+
+ ///
+ /// 强类型资源类,用于查找本地化字符串等。
+ ///
+ // 此类是由 StronglyTypedResourceBuilder
+ // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+ // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+ // (以 /str 作为命令选项),或重新生成 VS 项目。
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// 返回此类使用的缓存 ResourceManager 实例。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XFP.ICora.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 重写当前线程的 CurrentUICulture 属性,对
+ /// 使用此强类型资源类的所有资源查找执行重写。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Properties/Resources.resx b/XFP.Impact_Ultimate/XFP.Cora/Properties/Resources.resx
new file mode 100644
index 0000000..9161e46
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Properties/Resources.resx
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\DailyTask.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Domain.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\HomeCoin.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Mora.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\PaimonEmotion.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Primogems.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Resin.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\ResinFull.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Transformer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Properties/Settings.Designer.cs b/XFP.Impact_Ultimate/XFP.Cora/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..9d4d850
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Properties/Settings.Designer.cs
@@ -0,0 +1,50 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本:4.0.30319.42000
+//
+// 对此文件的更改可能会导致不正确的行为,并且如果
+// 重新生成代码,这些更改将会丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace XFP.ICora.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string UserCookie {
+ get {
+ return ((string)(this["UserCookie"]));
+ }
+ set {
+ this["UserCookie"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("0")]
+ public int LastUid {
+ get {
+ return ((int)(this["LastUid"]));
+ }
+ set {
+ this["LastUid"] = value;
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Properties/Settings.settings b/XFP.Impact_Ultimate/XFP.Cora/Properties/Settings.settings
new file mode 100644
index 0000000..41d6e6f
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Properties/Settings.settings
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+ 0
+
+
+
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/DailyTask.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/DailyTask.png
new file mode 100644
index 0000000..074a3f1
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/DailyTask.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/Domain.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/Domain.png
new file mode 100644
index 0000000..24f06b9
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/Domain.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/HomeCoin.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/HomeCoin.png
new file mode 100644
index 0000000..4c62158
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/HomeCoin.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/Mora.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/Mora.png
new file mode 100644
index 0000000..119986d
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/Mora.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/PaimonEmotion.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/PaimonEmotion.png
new file mode 100644
index 0000000..5de36b2
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/PaimonEmotion.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/Primogems.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/Primogems.png
new file mode 100644
index 0000000..20eb573
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/Primogems.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/Resin.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/Resin.png
new file mode 100644
index 0000000..ce3e342
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/Resin.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/ResinFull.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/ResinFull.png
new file mode 100644
index 0000000..992f575
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/ResinFull.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Resources/Transformer.png b/XFP.Impact_Ultimate/XFP.Cora/Resources/Transformer.png
new file mode 100644
index 0000000..5e8b054
Binary files /dev/null and b/XFP.Impact_Ultimate/XFP.Cora/Resources/Transformer.png differ
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Service/HoyolabService.cs b/XFP.Impact_Ultimate/XFP.Cora/Service/HoyolabService.cs
new file mode 100644
index 0000000..aceaa52
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Service/HoyolabService.cs
@@ -0,0 +1,29 @@
+//Copyright (c) XFP Group and Contributors. All rights resvered.
+//Licensed under the MIT License.
+
+using System.Threading.Tasks;
+
+namespace XFP.ICora.Hoyolab.Service
+{
+ public class HoyolabService
+ {
+ private HoyolabClient hoyolabClient;
+
+ public HoyolabService(HoyolabClient hoyolabClient)
+ {
+ this.hoyolabClient = hoyolabClient;
+ }
+
+ public async Task GetHoyolabUserInfoAsync(string cookie)
+ {
+ var user = await hoyolabClient.GetHoyolabUserInfoAsync(cookie);
+ return user;
+ }
+
+ public async Task> GetGenshinRoleInfoListAsync(string cookie)
+ {
+ var roles = await hoyolabClient.GetGenshinRoleInfoListAsync(cookie);
+ return roles;
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/Base/ModuleVersion.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Base/ModuleVersion.cs
new file mode 100644
index 0000000..b25f4db
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Base/ModuleVersion.cs
@@ -0,0 +1,28 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Utils.Base
+{
+ public enum ModuleVersion
+ {
+ ///
+ /// 无版本
+ ///
+ None = 0,
+
+ ///
+ /// 基础版本 ICora正常发布的用户版本
+ ///
+ BasicEdition = 1,
+
+ ///
+ /// Beta版本 打钱获取QWQ
+ ///
+ BetaEdition = 2,
+
+ ///
+ /// 开发者版本 就你小子也想有开发者版本?
+ ///
+ DevelopmentEdition = 3,
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/DataProvider.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/DataProvider.cs
new file mode 100644
index 0000000..c3f36ca
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/DataProvider.cs
@@ -0,0 +1,115 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Utils
+{
+ public class DataProvider
+ {
+ KeySetter key = new();
+
+ #region definition
+ #region public:
+ public string Version => "1.3.10";
+ public string DataBasePath = Environment.CurrentDirectory + "\\DataBase";
+ public string DataLog = Environment.CurrentDirectory + "\\DataBase\\DataLog.log";
+ public string TempLog = Environment.CurrentDirectory + "\\DataBase\\TempLog.log";
+ public string ErrorLog = Environment.CurrentDirectory + "\\DataBase\\ErrorLog.log";
+ public string SettingsData = Environment.CurrentDirectory + "\\DataBase\\Settings.log";
+ public ModuleVersion ModeVersion = ModuleVersion.DevelopmentEdition;
+ public string HoyolabAccountData = Environment.CurrentDirectory + "\\DataBase\\HoyolabAccountData";
+ public string EncryptKey = "ICORAHASX41HBL42KVGO992MLLAS6DJ0";
+ #endregion
+
+ #region private:
+ private bool IsFristCreateFile = false;
+ #endregion
+ #endregion
+
+ public DataProvider()
+ {
+ #region 初始化载入文件
+ if (!Directory.Exists(DataBasePath))
+ Directory.CreateDirectory(DataBasePath);
+ if (!File.Exists(DataLog))
+ {
+ File.Create(DataLog);
+ IsFristCreateFile = true;
+ key.sk("Initialized", "False");
+ }
+ if (!File.Exists(TempLog))
+ {
+ File.Create(TempLog);
+ IsFristCreateFile = true;
+ key.sk("Initialized", "False");
+ }
+ if (!File.Exists(ErrorLog))
+ {
+ File.Create(ErrorLog);
+ IsFristCreateFile = true;
+ key.sk("Initialized", "False");
+ }
+ if (!File.Exists(SettingsData))
+ {
+ File.Create(SettingsData);
+ IsFristCreateFile = true;
+ key.sk("Initialized", "False");
+ }
+ #endregion
+ Initialize();
+ }
+
+ public void Initialize()
+ {
+ #region 基础数据写入
+ if (IsFristCreateFile == true
+ || key.gk("Initialized") == string.Empty
+ || key.gk("Initialized") == "False")
+ {
+ try
+ {
+ #region DataLog Basic Log
+ using (StreamWriter sw = new StreamWriter(DataLog, false))
+ {
+ sw.WriteLine("#this file will save some user basic log");
+ sw.WriteLine("#If you deleted it, it means you will lose some data");
+ sw.WriteLine();
+ sw.WriteLine("UserModuleVersion=" + ModuleVersion.BasicEdition.ToString());
+ sw.WriteLine("UserVersion=" + Version);
+ sw.WriteLine("_Initialized=true");
+ }
+ #endregion
+
+ #region TempLog
+ using (StreamWriter sw = new StreamWriter(TempLog, true))
+ {
+ sw.WriteLine("#this file will save some user temp log");
+ sw.WriteLine("#If you delete it any time If you want to clean up the space");
+ sw.WriteLine();
+ }
+ #endregion
+
+ #region ErrorLog
+ using (StreamWriter sw = new StreamWriter(ErrorLog, true))
+ {
+ sw.WriteLine("#this file will save some user error log");
+ sw.WriteLine("#It will store all problems If you encounter any problems you can send it to the administrator for repair");
+ sw.WriteLine();
+ }
+ #endregion
+
+ #region SettingsLog
+ using (StreamWriter sw = new StreamWriter(SettingsData, true))
+ {
+ sw.WriteLine("#this file will save some user settings");
+ sw.WriteLine("#If you delete it, it means you will lose some of your own settings");
+ }
+ #endregion
+
+ key.sk("Initialized", "True");
+ }
+ catch { return; }
+ }
+ #endregion
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/DllUtils.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/DllUtils.cs
new file mode 100644
index 0000000..348d82d
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/DllUtils.cs
@@ -0,0 +1,94 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+using System.Runtime.InteropServices;
+
+namespace XFP.ICora.Utils
+{
+ public class DllUtils
+ {
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct STARTUPINFO
+ {
+ public int cb;
+ public string lpReserved;
+ public string lpDesktop;
+ public string lpTitle;
+ public int dwX;
+ public int dwY;
+ public int dwXSize;
+ public int dwYSize;
+ public int dwXCountChars;
+ public int dwYCountChars;
+ public int dwFillAttribute;
+ public int dwFlags;
+ public int wShowWindow;
+ public int cbReserved2;
+ public IntPtr lpReserved2;
+ public IntPtr hStdInput;
+ public IntPtr hStdOutput;
+ public IntPtr hStdError;
+ }
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct STARTUPINFOEX
+ {
+ public STARTUPINFO StartupInfo;
+ public IntPtr lpAttributeList;
+ }
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct PROCESS_INFORMATION
+ {
+ public IntPtr hProcess;
+ public IntPtr hThread;
+ public uint dwProcessId;
+ public uint dwThreadId;
+ }
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr GetModuleHandle(string lpModuleName);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern uint ResumeThread(IntPtr hThread);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr WaitForSingleObject(IntPtr hProcess, uint dwMilliseconds);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern bool CloseHandle(IntPtr handle);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern uint GetLastError();
+ [DllImport("kernel32.dll", SetLastError = true)]
+ public static extern IntPtr GetCurrentProcess();
+ [DllImport("advapi32.dll")]
+ public static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, uint dwAttributeCount, uint dwFlags, ref IntPtr lpSize);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool DeleteProcThreadAttributeList(IntPtr lpAttributeList);
+ [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
+ public static extern bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandle, uint dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
+
+ internal static bool WriteProcessMemory(IntPtr hProc, IntPtr pDllPath, char[] chars, uint v, out int _)
+ {
+ throw new NotImplementedException();
+ }
+
+ internal static bool WriteProcessMemory(IntPtr hProc, IntPtr pDllPath, object value, uint v, out int _)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/GetFormUrl.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/GetFormUrl.cs
new file mode 100644
index 0000000..837d3f6
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/GetFormUrl.cs
@@ -0,0 +1,35 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Utils
+{
+ public class GetFormUrl
+ {
+ public string Get(string url)
+ {
+ try
+ {
+ string strBuff = "";
+ int byteRead = 0;
+ char[] cbuffer = new char[256];
+ HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
+ HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse();
+ Stream respStream = httpResp.GetResponseStream();
+ StreamReader respStreamReader = new StreamReader(respStream, System.Text.Encoding.UTF8);
+ byteRead = respStreamReader.Read(cbuffer, 0, 256);
+ while (byteRead != 0)
+ {
+ string strResp = new string(cbuffer, 0, byteRead);
+ strBuff = strBuff + strResp;
+ byteRead = respStreamReader.Read(cbuffer, 0, 256);
+ }
+ respStream.Close();
+ return strBuff;
+ }
+ catch (Exception ex)
+ {
+ return ex.Message;
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/KeySetter.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/KeySetter.cs
new file mode 100644
index 0000000..40c7067
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/KeySetter.cs
@@ -0,0 +1,20 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Utils
+{
+ public class KeySetter
+ {
+ RegistryKey key = Registry.CurrentUser.OpenSubKey("Software", true).CreateSubKey("Impact_Ultimate");
+
+ public void sk(string name, string value)
+ {
+ key.SetValue(name, value);
+ }
+
+ public string gk(string name)
+ {
+ return (string)key.GetValue(name);
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/Log/LogWriter.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Log/LogWriter.cs
new file mode 100644
index 0000000..3480afc
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Log/LogWriter.cs
@@ -0,0 +1,95 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Utils.Log
+{
+ public class LogWriter
+ {
+ DataProvider data = new();
+
+ public void ErrorLog(string ErrorMessage, int returnCode, string Solution)
+ {
+ var LogPath = data.ErrorLog;
+ try
+ {
+ using (StreamWriter sw = new StreamWriter(LogPath, true))
+ {
+ sw.WriteLine();
+ sw.WriteLine("##################### Error Log #####################");
+ sw.WriteLine("Error Message: ");
+ sw.WriteLine(ErrorMessage);
+ sw.WriteLine("Return Code:");
+ sw.WriteLine(returnCode);
+ sw.WriteLine("Time");
+ DateTime dt = DateTime.Now;
+ sw.WriteLine(dt.ToString());
+ sw.WriteLine("Solution:");
+ sw.WriteLine(Solution);
+ sw.WriteLine("##################### Error Log #####################");
+ }
+ }
+ catch (Exception ex)
+ {
+ ErrorLog(ex.Message, -1, "这是未知的问题");
+ }
+ }
+
+ public void ErrorLog(string ErrorMessage, int returnCode)
+ {
+ var LogPath = data.ErrorLog;
+ try
+ {
+ using (StreamWriter sw = new StreamWriter(LogPath, true))
+ {
+ sw.WriteLine();
+ sw.WriteLine("##################### Error Log #####################");
+ sw.WriteLine("Error Message: ");
+ sw.WriteLine(ErrorMessage);
+ sw.WriteLine("Return Code:");
+ sw.WriteLine(returnCode);
+ sw.WriteLine("Time");
+ DateTime dt = DateTime.Now;
+ sw.WriteLine(dt.ToString());
+ sw.WriteLine("##################### Error Log #####################");
+ }
+ }
+ catch (Exception ex)
+ {
+ ErrorLog(ex.Message, -1, "这是未知的问题");
+ }
+ }
+
+ public void TempLog(string TempMessage)
+ {
+ var LogPath = data.TempLog;
+ try
+ {
+ using (StreamWriter sw = new StreamWriter(LogPath, true))
+ {
+ sw.WriteLine();
+ sw.WriteLine(TempMessage);
+ }
+ }
+ catch (Exception ex)
+ {
+ ErrorLog(ex.Message, -1, "这是未知的问题");
+ }
+ }
+
+ public void DataLog(string DataMessage)
+ {
+ var LogPath = data.DataLog;
+ try
+ {
+ using (StreamWriter sw = new StreamWriter(LogPath, false))
+ {
+ sw.WriteLine(DataMessage);
+ }
+ }
+ catch (Exception ex)
+ {
+ ErrorLog(ex.Message, -1, "这是未知的问题");
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/MenuInfo.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/MenuInfo.cs
new file mode 100644
index 0000000..f3b7d61
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/MenuInfo.cs
@@ -0,0 +1,32 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Model
+{
+ public class MenuInfo
+ {
+ private string _Name;
+
+ public string Name
+ {
+ get { return _Name; }
+ set { _Name = value; }
+ }
+
+ private string _GroupId;
+
+ public string GroupId
+ {
+ get { return _GroupId; }
+ set { _GroupId = value; }
+ }
+
+ private string _GroupName;
+
+ public string GroupName
+ {
+ get { return _GroupName; }
+ set { _GroupName = value; }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/DeveloperOption.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/DeveloperOption.cs
new file mode 100644
index 0000000..b29bd9b
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/DeveloperOption.cs
@@ -0,0 +1,19 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Utils.Model
+{
+ public class DeveloperOption
+ {
+ #region define
+
+ public bool UseDeveloperOptions = false;
+
+ #endregion
+
+ public DeveloperOption()
+ {
+
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/Files/DocumentSerializer.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/Files/DocumentSerializer.cs
new file mode 100644
index 0000000..2cbd203
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/Files/DocumentSerializer.cs
@@ -0,0 +1,38 @@
+using System.Xml.Serialization;
+
+namespace XFP.ICora.Utlis.Model.Files
+{
+ public class DocumentSerializer
+ {
+ ///
+ /// 序列化数据
+ ///
+ /// 对象类型
+ /// 对象
+ ///
+ public string Serializer(T t)
+ {
+ using (StringWriter sw = new())
+ {
+ XmlSerializer serializer = new XmlSerializer(typeof(T));
+ serializer.Serialize(sw, t);
+ return sw.ToString();
+ }
+ }
+
+ ///
+ /// 反序列化
+ ///
+ /// 对象类型
+ /// 序列化后的数据
+ ///
+ public object Deserialize(Type type, string document)
+ {
+ using (StringReader sr = new(document))
+ {
+ XmlSerializer serializer = new XmlSerializer(type);
+ return serializer.Deserialize(sr);
+ }
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/Files/INIFiles.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/Files/INIFiles.cs
new file mode 100644
index 0000000..c450315
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/Model/Files/INIFiles.cs
@@ -0,0 +1,42 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+namespace XFP.ICora.Utils.Model.Files
+{
+ public class INIFiles
+ {
+ // 声明INI文件的写操作函数 WritePrivateProfileString()
+ [System.Runtime.InteropServices.DllImport("kernel32")]
+ private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
+
+ // 声明INI文件的读操作函数 GetPrivateProfileString()
+ [System.Runtime.InteropServices.DllImport("kernel32")]
+ private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath);
+
+
+ /// 写入INI的方法
+ public void INIWrite(string section, string key, string value, string path)
+ {
+ // section=配置节点名称,key=键名,value=返回键值,path=路径
+ WritePrivateProfileString(section, key, value, path);
+ }
+
+ //读取INI的方法
+ public string INIRead(string section, string key, string path)
+ {
+ // 每次从ini中读取多少字节
+ System.Text.StringBuilder temp = new System.Text.StringBuilder(255);
+
+ // section=配置节点名称,key=键名,temp=上面,path=路径
+ GetPrivateProfileString(section, key, "", temp, 255, path);
+ return temp.ToString();
+
+ }
+
+ //删除一个INI文件
+ public void INIDelete(string FilePath)
+ {
+ File.Delete(FilePath);
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/PrimaryScreen.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/PrimaryScreen.cs
new file mode 100644
index 0000000..6e8e9a2
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/PrimaryScreen.cs
@@ -0,0 +1,121 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+using System.Drawing;
+using System.Runtime.InteropServices;
+using Size = System.Drawing.Size;
+
+namespace XFP.ICora.Utils
+{
+
+ public class PrimaryScreen
+ {
+ #region Win32 API
+ [DllImport("user32.dll")]
+ static extern IntPtr GetDC(IntPtr ptr);
+ [DllImport("gdi32.dll")]
+ static extern int GetDeviceCaps(
+ IntPtr hdc, // handle to DC
+ int nIndex // index of capability
+ );
+ [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
+ static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
+ #endregion
+ #region DeviceCaps常量
+ const int HORZRES = 8;
+ const int VERTRES = 10;
+ const int LOGPIXELSX = 88;
+ const int LOGPIXELSY = 90;
+ const int DESKTOPVERTRES = 117;
+ const int DESKTOPHORZRES = 118;
+ #endregion
+
+ #region 属性
+ ///
+ /// 获取屏幕分辨率当前物理大小
+ ///
+ public Size WorkingArea
+ {
+ get
+ {
+ IntPtr hdc = GetDC(IntPtr.Zero);
+ Size size = new Size();
+ size.Width = GetDeviceCaps(hdc, HORZRES);
+ size.Height = GetDeviceCaps(hdc, VERTRES);
+ ReleaseDC(IntPtr.Zero, hdc);
+ return size;
+ }
+ }
+ ///
+ /// 当前系统DPI_X 大小 一般为96
+ ///
+ public int DpiX
+ {
+ get
+ {
+ IntPtr hdc = GetDC(IntPtr.Zero);
+ int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
+ ReleaseDC(IntPtr.Zero, hdc);
+ return DpiX;
+ }
+ }
+ ///
+ /// 当前系统DPI_Y 大小 一般为96
+ ///
+ public int DpiY
+ {
+ get
+ {
+ IntPtr hdc = GetDC(IntPtr.Zero);
+ int DpiX = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(IntPtr.Zero, hdc);
+ return DpiX;
+ }
+ }
+ ///
+ /// 获取真实设置的桌面分辨率大小
+ ///
+ public Size DESKTOP
+ {
+ get
+ {
+ IntPtr hdc = GetDC(IntPtr.Zero);
+ Size size = new Size();
+ size.Width = GetDeviceCaps(hdc, DESKTOPHORZRES);
+ size.Height = GetDeviceCaps(hdc, DESKTOPVERTRES);
+ ReleaseDC(IntPtr.Zero, hdc);
+ return size;
+ }
+ }
+
+ ///
+ /// 获取宽度缩放百分比
+ ///
+ public float ScaleX
+ {
+ get
+ {
+ IntPtr hdc = GetDC(IntPtr.Zero);
+ int t = GetDeviceCaps(hdc, DESKTOPHORZRES);
+ int d = GetDeviceCaps(hdc, HORZRES);
+ float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
+ ReleaseDC(IntPtr.Zero, hdc);
+ return ScaleX;
+ }
+ }
+ ///
+ /// 获取高度缩放百分比
+ ///
+ public float ScaleY
+ {
+ get
+ {
+ IntPtr hdc = GetDC(IntPtr.Zero);
+ float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);
+ ReleaseDC(IntPtr.Zero, hdc);
+ return ScaleY;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/Utlis/YSAccount.cs b/XFP.Impact_Ultimate/XFP.Cora/Utlis/YSAccount.cs
new file mode 100644
index 0000000..7219acb
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/Utlis/YSAccount.cs
@@ -0,0 +1,75 @@
+//Copyright(c) XFP Group and Contributors. All rights reserved.
+//Licensed under the MIT License.
+
+using Newtonsoft.Json;
+using System.Text;
+
+namespace XFP.ICora.Utils
+{
+ [Serializable]
+ public class YSAccount
+ {
+ public string Name { get; set; }
+
+ public string MIHOYOSDK_ADL_PROD_CN_h3123967166 { get; set; }
+
+ public string GENERAL_DATA_h2389025596 { get; set; }
+
+ public static YSAccount ReadFromDisk(string name)
+ {
+ string p = Path.Combine(Environment.CurrentDirectory, "UserData", name);
+ string json = File.ReadAllText(p);
+ YSAccount acct = JsonConvert.DeserializeObject(json);
+ return acct;
+ }
+
+ public void WriteToDisk()
+ {
+ File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "UserData", Name), JsonConvert.SerializeObject(this));
+ }
+
+ public static void DeleteFromDisk(string name)
+ {
+ File.Delete(Path.Combine(Environment.CurrentDirectory, "UserData", name));
+ }
+
+ public static YSAccount ReadFromRegedit(bool needSettings)
+ {
+ YSAccount acct = new YSAccount();
+ acct.MIHOYOSDK_ADL_PROD_CN_h3123967166 = GetStringFromRegedit("MIHOYOSDK_ADL_PROD_CN_h3123967166");
+ if (needSettings)
+ {
+ acct.GENERAL_DATA_h2389025596 = GetStringFromRegedit("GENERAL_DATA_h2389025596");
+ }
+ return acct;
+ }
+
+ public void WriteToRegedit()
+ {
+ if (string.IsNullOrWhiteSpace(MIHOYOSDK_ADL_PROD_CN_h3123967166))
+ {
+ //保存账户内容为空
+ }
+ else
+ {
+ SetStringToRegedit("MIHOYOSDK_ADL_PROD_CN_h3123967166", MIHOYOSDK_ADL_PROD_CN_h3123967166);
+ if (!string.IsNullOrWhiteSpace(GENERAL_DATA_h2389025596))
+ {
+ SetStringToRegedit("GENERAL_DATA_h2389025596", GENERAL_DATA_h2389025596);
+ }
+
+ }
+ }
+
+ private static string GetStringFromRegedit(string key)
+ {
+ object value = Registry.GetValue(@"HKEY_CURRENT_USER\Software\miHoYo\原神", key, "");
+ return Encoding.UTF8.GetString((byte[])value);
+ }
+
+ private static void SetStringToRegedit(string key, string value)
+ {
+ Registry.SetValue(@"HKEY_CURRENT_USER\Software\miHoYo\原神", key, Encoding.UTF8.GetBytes(value));
+ }
+ }
+}
diff --git a/XFP.Impact_Ultimate/XFP.Cora/XFP - Backup.ICora.csproj b/XFP.Impact_Ultimate/XFP.Cora/XFP - Backup.ICora.csproj
new file mode 100644
index 0000000..e33872c
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/XFP - Backup.ICora.csproj
@@ -0,0 +1,106 @@
+
+
+ net7.0-windows
+ WinExe
+ false
+ True
+ true
+
+
+ GashByte-透明.ico
+
+
+ app1.manifest
+ XFP.ICora.App
+ x64
+ False
+ bin\
+ obj\
+ False
+ OnBuildSuccess
+ False
+
+
+
+
+
+ True
+ XFP.ICora
+ XFP.ICora
+ XFPGroup
+ x3zF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Never
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Never
+
+
+
+
+
+
+
+ True
+ True
+ Settings.settings
+
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/XFP.ICora.csproj b/XFP.Impact_Ultimate/XFP.Cora/XFP.ICora.csproj
new file mode 100644
index 0000000..b14b6d6
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/XFP.ICora.csproj
@@ -0,0 +1,108 @@
+
+
+ net7.0-windows
+ WinExe
+ false
+ True
+ true
+
+
+ GashByte-透明.ico
+
+
+ app1.manifest
+ XFP.ICora.App
+ x64
+ False
+ bin\
+ obj\
+ False
+ OnBuildSuccess
+ False
+
+
+
+
+
+ True
+ XFP.ICora
+ XFP.ICora
+ XFPGroup
+ x3zF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Never
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Never
+
+
+
+
+
+
+
+ True
+ True
+ Settings.settings
+
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/XFP.ICora.csproj.user b/XFP.Impact_Ultimate/XFP.Cora/XFP.ICora.csproj.user
new file mode 100644
index 0000000..6d8bac5
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/XFP.ICora.csproj.user
@@ -0,0 +1,62 @@
+
+
+
+ false
+
+
+ publish\
+
+
+
+
+
+ zh-CN
+ false
+
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+
+
+ Designer
+
+
+ Designer
+
+
+ Designer
+
+
+ Designer
+
+
+ Designer
+
+
+ Designer
+
+
+ Designer
+
+
+
\ No newline at end of file
diff --git a/XFP.Impact_Ultimate/XFP.Cora/app.manifest b/XFP.Impact_Ultimate/XFP.Cora/app.manifest
new file mode 100644
index 0000000..52b94cc
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/app.manifest
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/XFP.Impact_Ultimate/XFP.Cora/app1.manifest b/XFP.Impact_Ultimate/XFP.Cora/app1.manifest
new file mode 100644
index 0000000..52b94cc
--- /dev/null
+++ b/XFP.Impact_Ultimate/XFP.Cora/app1.manifest
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+