1
0
mirror of https://github.com/wangdage12/Snap.Hutao.git synced 2026-03-28 05:52:16 +08:00

更换新域名

支持打开debug控制台
修复一个可能导致元数据出问题的小问题
修改多处url
This commit is contained in:
fanbook-wangdage
2026-03-24 20:03:45 +08:00
parent 9de07754c7
commit 66263a82f2
16 changed files with 150 additions and 43 deletions

View File

@@ -6,7 +6,7 @@
自带的注入功能只有FPS调整只保证FPS调整长期可用你可以使用`注入选项`下方的第三方工具来使用更多功能,本项目提供的所有注入功能都不会影响游戏的公平性。 自带的注入功能只有FPS调整只保证FPS调整长期可用你可以使用`注入选项`下方的第三方工具来使用更多功能,本项目提供的所有注入功能都不会影响游戏的公平性。
官网https://htserver.wdg.cloudns.ch/ 官网https://htserver.wdg12.work/
**该版本的特点:** **该版本的特点:**
- 尽量保留原版功能,少重写功能,稳定性强 - 尽量保留原版功能,少重写功能,稳定性强
@@ -113,10 +113,10 @@ http://htgit.wdg.cloudns.ch/wdg1122/Snap.Metadata
![http://serverjp.wdg.cloudns.ch:3001/api/badge/10/status?style=flat-square](http://serverjp.wdg.cloudns.ch:3001/api/badge/10/status?style=flat-square) ![http://serverjp.wdg.cloudns.ch:3001/api/badge/10/status?style=flat-square](http://serverjp.wdg.cloudns.ch:3001/api/badge/10/status?style=flat-square)
https://htserver.wdg.cloudns.ch/api/ https://htserver.wdg12.work/api/
--- ---
**图片资源站:** **图片资源站:**
https://htserver.wdg.cloudns.ch/ https://htserver.wdg12.work/

View File

@@ -3,7 +3,7 @@
<Package <Package
Name="Snap.Hutao" Name="Snap.Hutao"
Manufacturer="Millennium Science Technology R-D Inst" Manufacturer="Millennium Science Technology R-D Inst"
Version="1.18.5.0" Version="1.18.6.0"
UpgradeCode="121203be-60cb-408f-92cc-7080f6598e68" UpgradeCode="121203be-60cb-408f-92cc-7080f6598e68"
Language="2052" Language="2052"
Scope="perMachine"> Scope="perMachine">

View File

@@ -22,6 +22,11 @@ public static partial class Bootstrap
private static readonly ApplicationInitializationCallback AppInitializationCallback = InitializeApp; private static readonly ApplicationInitializationCallback AppInitializationCallback = InitializeApp;
private static Mutex? mutex; private static Mutex? mutex;
/// <summary>
/// Gets a value indicating whether console output is enabled.
/// </summary>
public static bool ConsoleEnabled { get; private set; }
internal static void UseNamedPipeRedirection() internal static void UseNamedPipeRedirection()
{ {
Debug.Assert(mutex is not null); Debug.Assert(mutex is not null);
@@ -31,6 +36,19 @@ public static partial class Bootstrap
[STAThread] [STAThread]
private static void Main(string[] args) private static void Main(string[] args)
{ {
// Check for console flag
ConsoleEnabled = args.Contains("--console") || args.Contains("--debug") ||
Environment.GetEnvironmentVariable("HUTAO_DEBUG") == "1";
if (ConsoleEnabled)
{
// Allocate a console window for debug output
HutaoNativeMethods.AllocConsole();
Console.WriteLine("[Bootstrap] Console allocated for debug output");
Console.WriteLine($"[Bootstrap] Arguments: {string.Join(" ", args)}");
Console.WriteLine($"[Bootstrap] Working Directory: {Environment.CurrentDirectory}");
}
#if DEBUG #if DEBUG
System.Diagnostics.Debug.WriteLine("[Bootstrap.Main] Starting..."); System.Diagnostics.Debug.WriteLine("[Bootstrap.Main] Starting...");
#endif #endif
@@ -124,6 +142,12 @@ public static partial class Bootstrap
#if DEBUG #if DEBUG
System.Diagnostics.Debug.WriteLine("[Bootstrap.Main] Exiting"); System.Diagnostics.Debug.WriteLine("[Bootstrap.Main] Exiting");
#endif #endif
if (ConsoleEnabled)
{
Console.WriteLine("[Bootstrap] Application exiting...");
HutaoNativeMethods.FreeConsole();
}
} }
private static void InitializeApp(ApplicationInitializationCallbackParams param) private static void InitializeApp(ApplicationInitializationCallbackParams param)

View File

@@ -29,6 +29,12 @@ internal static class DependencyInjection
.AddFilter(DbLoggerCategory.Query.Name, level => level >= LogLevel.Information) .AddFilter(DbLoggerCategory.Query.Name, level => level >= LogLevel.Information)
.AddDebug() .AddDebug()
.AddSentryTelemetry(); .AddSentryTelemetry();
// Add console logging if console is enabled
if (Bootstrap.ConsoleEnabled)
{
builder.AddConsole();
}
}) })
.AddMemoryCache() .AddMemoryCache()

View File

@@ -13,7 +13,7 @@
<Identity <Identity
Name="60568DGPStudio.SnapHutao" Name="60568DGPStudio.SnapHutao"
Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52" Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52"
Version="1.18.5.0" /> Version="1.18.6.0" />
<Properties> <Properties>
<DisplayName>Snap Hutao</DisplayName> <DisplayName>Snap Hutao</DisplayName>

View File

@@ -1127,12 +1127,21 @@
<data name="ServiceGameSetMultiChannelUnauthorizedAccess" xml:space="preserve"> <data name="ServiceGameSetMultiChannelUnauthorizedAccess" xml:space="preserve">
<value>无法读取或保存配置文件,请以管理员模式重试</value> <value>无法读取或保存配置文件,请以管理员模式重试</value>
</data> </data>
<data name="ServiceGitRepositoryCloneReasonForceInvalid" xml:space="preserve">
<value>现有元数据仓库更新失败,正在重新下载</value>
</data>
<data name="ServiceGitRepositoryCloneReasonInvalidRepo" xml:space="preserve">
<value>首次下载或仓库损坏,正在下载元数据</value>
</data>
<data name="ServiceGitRepositoryOperationCompleted" xml:space="preserve"> <data name="ServiceGitRepositoryOperationCompleted" xml:space="preserve">
<value>操作完成</value> <value>操作完成</value>
</data> </data>
<data name="ServiceGitRepositoryOperationFailed" xml:space="preserve"> <data name="ServiceGitRepositoryOperationFailed" xml:space="preserve">
<value>操作失败</value> <value>操作失败</value>
</data> </data>
<data name="ServiceGitRepositoryUpdatingExisting" xml:space="preserve">
<value>检查元数据更新</value>
</data>
<data name="ServiceHutaoUserGachaLogExpiredAt" xml:space="preserve"> <data name="ServiceHutaoUserGachaLogExpiredAt" xml:space="preserve">
<value>祈愿记录上传服务有效期至</value> <value>祈愿记录上传服务有效期至</value>
</data> </data>

View File

@@ -21,6 +21,7 @@ internal sealed partial class GitRepositoryService : IGitRepositoryService
{ {
private readonly AsyncKeyedLock<string> repoLock = new(); private readonly AsyncKeyedLock<string> repoLock = new();
private readonly BackgroundActivityOptions backgroundActivityOptions; private readonly BackgroundActivityOptions backgroundActivityOptions;
private readonly ILogger<GitRepositoryService> logger;
private readonly IServiceProvider serviceProvider; private readonly IServiceProvider serviceProvider;
private readonly ITaskContext taskContext; private readonly ITaskContext taskContext;
@@ -76,6 +77,7 @@ internal sealed partial class GitRepositoryService : IGitRepositoryService
} }
catch (Exception first) catch (Exception first)
{ {
logger.LogWarning(first, "[Metadata] Failed to update existing repository, fallback to reclone: Directory={Directory}, Url={Url}", directory, info.HttpsUrl.OriginalString);
exceptions.Add(first); exceptions.Add(first);
return EnsureRepository(activity, directory, info, true); return EnsureRepository(activity, directory, info, true);
} }
@@ -110,6 +112,14 @@ internal sealed partial class GitRepositoryService : IGitRepositoryService
{ {
// Increase & decrease count in the same method, so that crash in the middle can correctly count as failure. // Increase & decrease count in the same method, so that crash in the middle can correctly count as failure.
RepositoryAffinity.IncreaseFailure(info); RepositoryAffinity.IncreaseFailure(info);
// Debug: Log the initial state
bool isRepoValid = Repository.IsValid(directory);
bool directoryExists = Directory.Exists(directory);
logger.LogInformation("[Metadata] Checking repository: Directory={Directory}, Exists={Exists}, IsValid={IsValid}, ForceInvalid={ForceInvalid}",
directory, directoryExists, isRepoValid, forceInvalid);
FetchOptions fetchOptions = new() FetchOptions fetchOptions = new()
{ {
Depth = 1, Depth = 1,
@@ -142,10 +152,18 @@ internal sealed partial class GitRepositoryService : IGitRepositoryService
CertificateCheck = static (cert, valid, host) => true, CertificateCheck = static (cert, valid, host) => true,
}; };
if (forceInvalid || !Repository.IsValid(directory)) if (forceInvalid || !isRepoValid)
{ {
if (Directory.Exists(directory)) // Debug: Log why we're cloning
string reason = forceInvalid
? SH.ServiceGitRepositoryCloneReasonForceInvalid
: SH.ServiceGitRepositoryCloneReasonInvalidRepo;
logger.LogInformation("[Metadata] Cloning repository: Reason={Reason}, Url={Url}", reason, info.HttpsUrl.OriginalString);
activity.Update(taskContext, reason, false, false, false, false);
if (directoryExists)
{ {
logger.LogInformation("[Metadata] Deleting existing directory before clone");
Directory.SetReadOnly(directory, false); Directory.SetReadOnly(directory, false);
Directory.Delete(directory, true); Directory.Delete(directory, true);
} }
@@ -154,9 +172,15 @@ internal sealed partial class GitRepositoryService : IGitRepositoryService
{ {
Checkout = true, Checkout = true,
}); });
logger.LogInformation("[Metadata] Clone completed successfully");
} }
else else
{ {
// Debug: Log that we're updating
logger.LogInformation("[Metadata] Updating existing repository");
activity.Update(taskContext, SH.ServiceGitRepositoryUpdatingExisting, false, false, false, false);
// We need to ensure local repo is up to date // We need to ensure local repo is up to date
using (Repository repo = new(directory)) using (Repository repo = new(directory))
{ {
@@ -177,17 +201,20 @@ internal sealed partial class GitRepositoryService : IGitRepositoryService
repo.Network.Remotes.Update("origin", remote => remote.Url = info.HttpsUrl.OriginalString); repo.Network.Remotes.Update("origin", remote => remote.Url = info.HttpsUrl.OriginalString);
repo.RemoveUntrackedFiles(); repo.RemoveUntrackedFiles();
fetchOptions.UpdateFetchHead = false; fetchOptions.UpdateFetchHead = false;
Commands.Fetch(repo, repo.Head.RemoteName, Array.Empty<string>(), fetchOptions, default); Commands.Fetch(repo, "origin", Array.Empty<string>(), fetchOptions, default);
// Manually patch .git/shallow file // Manually patch .git/shallow file
File.WriteAllText(Path.Combine(directory, ".git//shallow"), string.Join("", repo.Branches.Where(static branch => branch.IsRemote).Select(static branch => $"{branch.Tip.Sha}\n"))); File.WriteAllText(Path.Combine(directory, ".git", "shallow"), string.Join("", repo.Branches.Where(static branch => branch.IsRemote).Select(static branch => $"{branch.Tip.Sha}\n")));
Branch remoteBranch = repo.Branches["origin/main"]; Branch remoteBranch = repo.Branches["origin/main"];
Branch localBranch = repo.Branches["main"] ?? repo.CreateBranch("main", remoteBranch.Tip); Branch localBranch = repo.Branches["main"] ?? repo.CreateBranch("main", remoteBranch.Tip);
repo.Branches.Update(localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName); repo.Branches.Update(localBranch, b => b.TrackedBranch = remoteBranch.CanonicalName);
Commands.Checkout(repo, localBranch);
repo.Reset(ResetMode.Hard, remoteBranch.Tip); repo.Reset(ResetMode.Hard, remoteBranch.Tip);
repo.RemoveUntrackedFiles(); repo.RemoveUntrackedFiles();
} }
logger.LogInformation("[Metadata] Update completed successfully");
} }
RepositoryAffinity.DecreaseFailure(info); RepositoryAffinity.DecreaseFailure(info);

View File

@@ -19,7 +19,7 @@ namespace Snap.Hutao.Service.ThirdPartyTool;
[Service(ServiceLifetime.Singleton, typeof(IThirdPartyToolService))] [Service(ServiceLifetime.Singleton, typeof(IThirdPartyToolService))]
internal sealed partial class ThirdPartyToolService : IThirdPartyToolService internal sealed partial class ThirdPartyToolService : IThirdPartyToolService
{ {
private const string ApiBaseUrl = "https://htserver.wdg.cloudns.ch/api"; private const string ApiBaseUrl = "https://htserver.wdg12.work/api";
private const string ToolsEndpoint = "/tools"; private const string ToolsEndpoint = "/tools";
private const string ToolInfoFileName = "tool_info.json"; private const string ToolInfoFileName = "tool_info.json";

View File

@@ -11,7 +11,7 @@
<UseWinUI>true</UseWinUI> <UseWinUI>true</UseWinUI>
<UseWPF>False</UseWPF> <UseWPF>False</UseWPF>
<!-- 配置版本号 --> <!-- 配置版本号 -->
<Version>1.18.5.0</Version> <Version>1.18.6.0</Version>
<UseWindowsForms>False</UseWindowsForms> <UseWindowsForms>False</UseWindowsForms>
<ImplicitUsings>False</ImplicitUsings> <ImplicitUsings>False</ImplicitUsings>

View File

@@ -117,10 +117,17 @@ internal partial class ScopedPage : Page
if (DataContext is IViewModel viewModel) if (DataContext is IViewModel viewModel)
{ {
// Wait to ensure critical viewmodel operation is completed try
using (viewModel.CriticalSection.Enter()) {
// Wait to ensure critical viewmodel operation is completed.
// The view model might already be disposed when window shutdown and page unload race.
using (viewModel.CriticalSection.Enter())
{
viewModel.Uninitialize();
}
}
catch (OperationCanceledException)
{ {
viewModel.Uninitialize();
} }
try try

View File

@@ -1,7 +1,7 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- DocumentLink --> <!-- DocumentLink -->
<x:String x:Key="DocumentLink_BugReport">https://hut.ao/statements/bug-report.html</x:String> <x:String x:Key="DocumentLink_BugReport">https://hut.ao/statements/bug-report.html</x:String>
<x:String x:Key="DocumentLink_Home">https://hut.ao</x:String> <x:String x:Key="DocumentLink_Home">https://htserver.wdg12.work</x:String>
<x:String x:Key="DocumentLink_MhyAccountSwitch">https://hut.ao/features/mhy-account-switch.html</x:String> <x:String x:Key="DocumentLink_MhyAccountSwitch">https://hut.ao/features/mhy-account-switch.html</x:String>
<x:String x:Key="DocumentLink_Translate">https://translate.hut.ao</x:String> <x:String x:Key="DocumentLink_Translate">https://translate.hut.ao</x:String>
<x:String x:Key="DocumentLink_Loopback">https://hut.ao/advanced/loopback.html</x:String> <x:String x:Key="DocumentLink_Loopback">https://hut.ao/advanced/loopback.html</x:String>
@@ -13,32 +13,32 @@
<x:String x:Key="IconGame">https://launcher-webstatic.mihoyo.com/launcher-public/2024/04/15/9ebf1bc5af2d83ca5fca21adb49cf341_2571779162329842818.png</x:String> <x:String x:Key="IconGame">https://launcher-webstatic.mihoyo.com/launcher-public/2024/04/15/9ebf1bc5af2d83ca5fca21adb49cf341_2571779162329842818.png</x:String>
<!-- AvatarCard --> <!-- AvatarCard -->
<x:String x:Key="UI_AvatarIcon_Costume_Card">https://htserver.wdg.cloudns.ch/static/raw/AvatarCard/UI_AvatarIcon_Costume_Card.png</x:String> <x:String x:Key="UI_AvatarIcon_Costume_Card">https://htserver.wdg12.work/static/raw/AvatarCard/UI_AvatarIcon_Costume_Card.png</x:String>
<!-- Bg --> <!-- Bg -->
<x:String x:Key="UI_ItemIcon_None">https://htserver.wdg.cloudns.ch/static/raw/Bg/UI_ItemIcon_None.png</x:String> <x:String x:Key="UI_ItemIcon_None">https://htserver.wdg12.work/static/raw/Bg/UI_ItemIcon_None.png</x:String>
<!-- Mark --> <!-- Mark -->
<x:String x:Key="UI_MarkQuest_Events_Proce">https://htserver.wdg.cloudns.ch/static/raw/Mark/UI_MarkQuest_Events_Proce.png</x:String> <x:String x:Key="UI_MarkQuest_Events_Proce">https://htserver.wdg12.work/static/raw/Mark/UI_MarkQuest_Events_Proce.png</x:String>
<x:String x:Key="UI_MarkQuest_Events_Start">https://htserver.wdg.cloudns.ch/static/raw/Mark/UI_MarkQuest_Events_Start.png</x:String> <x:String x:Key="UI_MarkQuest_Events_Start">https://htserver.wdg12.work/static/raw/Mark/UI_MarkQuest_Events_Start.png</x:String>
<x:String x:Key="UI_MarkQuest_Main_Proce">https://htserver.wdg.cloudns.ch/static/raw/Mark/UI_MarkQuest_Main_Proce.png</x:String> <x:String x:Key="UI_MarkQuest_Main_Proce">https://htserver.wdg12.work/static/raw/Mark/UI_MarkQuest_Main_Proce.png</x:String>
<x:String x:Key="UI_MarkQuest_Main_Start">https://htserver.wdg.cloudns.ch/static/raw/Mark/UI_MarkQuest_Main_Start.png</x:String> <x:String x:Key="UI_MarkQuest_Main_Start">https://htserver.wdg12.work/static/raw/Mark/UI_MarkQuest_Main_Start.png</x:String>
<x:String x:Key="UI_MarkTower">https://htserver.wdg.cloudns.ch/static/raw/Mark/UI_MarkTower.png</x:String> <x:String x:Key="UI_MarkTower">https://htserver.wdg12.work/static/raw/Mark/UI_MarkTower.png</x:String>
<!-- ItemIcon --> <!-- ItemIcon -->
<x:String x:Key="UI_ItemIcon_106">https://htserver.wdg.cloudns.ch/static/raw/ItemIcon/UI_ItemIcon_106.png</x:String> <x:String x:Key="UI_ItemIcon_106">https://htserver.wdg12.work/static/raw/ItemIcon/UI_ItemIcon_106.png</x:String>
<x:String x:Key="UI_ItemIcon_204">https://htserver.wdg.cloudns.ch/static/raw/ItemIcon/UI_ItemIcon_204.png</x:String> <x:String x:Key="UI_ItemIcon_204">https://htserver.wdg12.work/static/raw/ItemIcon/UI_ItemIcon_204.png</x:String>
<x:String x:Key="UI_ItemIcon_210">https://htserver.wdg.cloudns.ch/static/raw/ItemIcon/UI_ItemIcon_210.png</x:String> <x:String x:Key="UI_ItemIcon_210">https://htserver.wdg12.work/static/raw/ItemIcon/UI_ItemIcon_210.png</x:String>
<x:String x:Key="UI_ItemIcon_220021">https://htserver.wdg.cloudns.ch/static/raw/ItemIcon/UI_ItemIcon_220021.png</x:String> <x:String x:Key="UI_ItemIcon_220021">https://htserver.wdg12.work/static/raw/ItemIcon/UI_ItemIcon_220021.png</x:String>
<!-- EmotionIcon --> <!-- EmotionIcon -->
<x:String x:Key="UI_EmotionIcon52">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon52.png</x:String> <x:String x:Key="UI_EmotionIcon52">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon52.png</x:String>
<x:String x:Key="UI_EmotionIcon71">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon71.png</x:String> <x:String x:Key="UI_EmotionIcon71">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon71.png</x:String>
<x:String x:Key="UI_EmotionIcon89">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon89.png</x:String> <x:String x:Key="UI_EmotionIcon89">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon89.png</x:String>
<x:String x:Key="UI_EmotionIcon250">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon250.png</x:String> <x:String x:Key="UI_EmotionIcon250">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon250.png</x:String>
<x:String x:Key="UI_EmotionIcon271">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon271.png</x:String> <x:String x:Key="UI_EmotionIcon271">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon271.png</x:String>
<x:String x:Key="UI_EmotionIcon272">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon272.png</x:String> <x:String x:Key="UI_EmotionIcon272">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon272.png</x:String>
<x:String x:Key="UI_EmotionIcon293">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon293.png</x:String> <x:String x:Key="UI_EmotionIcon293">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon293.png</x:String>
<x:String x:Key="UI_EmotionIcon433">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon433.png</x:String> <x:String x:Key="UI_EmotionIcon433">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon433.png</x:String>
<x:String x:Key="UI_EmotionIcon445">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon445.png</x:String> <x:String x:Key="UI_EmotionIcon445">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon445.png</x:String>
<x:String x:Key="UI_EmotionIcon585">https://htserver.wdg.cloudns.ch/static/raw/EmotionIcon/UI_EmotionIcon585.png</x:String> <x:String x:Key="UI_EmotionIcon585">https://htserver.wdg12.work/static/raw/EmotionIcon/UI_EmotionIcon585.png</x:String>
</ResourceDictionary> </ResourceDictionary>

View File

@@ -268,7 +268,7 @@
<TextBlock> <TextBlock>
<TextBlock.Inlines> <TextBlock.Inlines>
<Run Text="{shuxm:ResourceString Name=ViewGuideStepAgreementIHaveReadText}"/> <Run Text="{shuxm:ResourceString Name=ViewGuideStepAgreementIHaveReadText}"/>
<Hyperlink NavigateUri="https://github.com/DGP-Studio/Snap.Hutao/blob/main/LICENSE"> <Hyperlink NavigateUri="https://github.com/wangdage12/Snap.Hutao/blob/main/LICENSE">
<Run Text="{shuxm:ResourceString Name=ViewGuideStepAgreementOpenSourceLicense}"/> <Run Text="{shuxm:ResourceString Name=ViewGuideStepAgreementOpenSourceLicense}"/>
</Hyperlink> </Hyperlink>
</TextBlock.Inlines> </TextBlock.Inlines>

View File

@@ -93,13 +93,13 @@
<cwcont:SettingsExpander.Items> <cwcont:SettingsExpander.Items>
<cwcont:SettingsCard <cwcont:SettingsCard
Command="{Binding NavigateToUriCommand}" Command="{Binding NavigateToUriCommand}"
CommandParameter="https://github.com/DGP-Studio/Snap.Hutao/issues/new/choose" CommandParameter="https://github.com/wangdage12/Snap.Hutao"
Description="{shuxm:ResourceString Name=ViewPageFeedbackGithubIssuesDescription}" Description="{shuxm:ResourceString Name=ViewPageFeedbackGithubIssuesDescription}"
Header="GitHub Issues" Header="GitHub Issues"
IsClickEnabled="True"/> IsClickEnabled="True"/>
<cwcont:SettingsCard <cwcont:SettingsCard
Command="{Binding NavigateToUriCommand}" Command="{Binding NavigateToUriCommand}"
CommandParameter="https://status.snapgenshin.cn/status" CommandParameter="https://stats.uptimerobot.com/fHxWxdxK61"
Description="{shuxm:ResourceString Name=ViewPageFeedbackServerStatusDescription}" Description="{shuxm:ResourceString Name=ViewPageFeedbackServerStatusDescription}"
Header="{shuxm:ResourceString Name=ViewPageFeedbackServerStatusHeader}" Header="{shuxm:ResourceString Name=ViewPageFeedbackServerStatusHeader}"
IsClickEnabled="True"/> IsClickEnabled="True"/>

View File

@@ -6,9 +6,9 @@ namespace Snap.Hutao.Web.Endpoint.Hutao;
[Service(ServiceLifetime.Singleton, typeof(IHutaoEndpoints), Key = HutaoEndpointsKind.Release)] [Service(ServiceLifetime.Singleton, typeof(IHutaoEndpoints), Key = HutaoEndpointsKind.Release)]
internal sealed class HutaoEndpointsForRelease : IHutaoEndpoints internal sealed class HutaoEndpointsForRelease : IHutaoEndpoints
{ {
string IHomaRootAccess.Root { get => "https://htserver.wdg.cloudns.ch/api"; } string IHomaRootAccess.Root { get => "https://htserver.wdg12.work/api"; }
string IInfrastructureRootAccess.Root { get => "https://htserver.wdg.cloudns.ch/api"; } string IInfrastructureRootAccess.Root { get => "https://htserver.wdg12.work/api"; }
string IInfrastructureRawRootAccess.RawRoot { get => "https://htserver.wdg.cloudns.ch/api"; } string IInfrastructureRawRootAccess.RawRoot { get => "https://htserver.wdg12.work/api"; }
} }

View File

@@ -5,7 +5,7 @@ namespace Snap.Hutao.Web.Endpoint.Hutao;
internal static class StaticResourcesEndpoints internal static class StaticResourcesEndpoints
{ {
public static string Root { get => "https://htserver.wdg.cloudns.ch"; } public static string Root { get => "https://htserver.wdg12.work"; }
public static Uri UIIconNone { get; } = StaticRaw("Bg", "UI_Icon_None.png").ToUri(); public static Uri UIIconNone { get; } = StaticRaw("Bg", "UI_Icon_None.png").ToUri();

View File

@@ -42,6 +42,10 @@ internal static unsafe class HutaoNativeMethods
// ReSharper restore InconsistentNaming // ReSharper restore InconsistentNaming
public const string DllName = "Snap.Hutao.Native.dll"; public const string DllName = "Snap.Hutao.Native.dll";
// Console APIs
public const int STD_OUTPUT_HANDLE = -11;
public const int STD_ERROR_HANDLE = -12;
public static HutaoNative HutaoCreateInstance() public static HutaoNative HutaoCreateInstance()
{ {
nint pv = default; nint pv = default;
@@ -54,6 +58,36 @@ internal static unsafe class HutaoNativeMethods
return HutaoHResultIsWin32(hr, error); return HutaoHResultIsWin32(hr, error);
} }
/// <summary>
/// Allocates a new console for the calling process.
/// </summary>
/// <returns>TRUE if the function succeeds; otherwise, FALSE.</returns>
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern BOOL AllocConsole();
/// <summary>
/// Detaches the calling process from its console.
/// </summary>
/// <returns>TRUE if the function succeeds; otherwise, FALSE.</returns>
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern BOOL FreeConsole();
/// <summary>
/// Attaches the calling process to the console of the specified process.
/// </summary>
/// <param name="dwProcessId">The identifier of the process whose console is to be used.</param>
/// <returns>TRUE if the function succeeds; otherwise, FALSE.</returns>
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern BOOL AttachConsole(uint dwProcessId);
/// <summary>
/// Retrieves a handle to the specified standard device.
/// </summary>
/// <param name="nStdHandle">The standard device.</param>
/// <returns>A handle to the specified device.</returns>
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern nint GetStdHandle(int nStdHandle);
[DllImport(DllName, CallingConvention = CallingConvention.Winapi, ExactSpelling = true)] [DllImport(DllName, CallingConvention = CallingConvention.Winapi, ExactSpelling = true)]
private static extern HRESULT HutaoCreateInstance(HutaoNative.Vftbl** ppv); private static extern HRESULT HutaoCreateInstance(HutaoNative.Vftbl** ppv);