Init commit
This commit is contained in:
commit
18dcce592d
|
|
@ -0,0 +1,71 @@
|
||||||
|
# 用户特定文件
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# 构建结果
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
|
||||||
|
# Visual Studio 缓存/选项目录
|
||||||
|
.vs/
|
||||||
|
|
||||||
|
# MSTest 测试结果
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
|
||||||
|
# .NET Core 项目
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
**/Properties/launchSettings.json
|
||||||
|
|
||||||
|
# NuGet 包
|
||||||
|
*.nupkg
|
||||||
|
**/packages/*
|
||||||
|
!**/packages/build/
|
||||||
|
|
||||||
|
# Microsoft Azure 构建输出
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Store 应用包目录和文件
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
|
||||||
|
# Visual Studio 缓存文件
|
||||||
|
*. [Cc]ache
|
||||||
|
!?*. [Cc]ache/
|
||||||
|
|
||||||
|
# 其他
|
||||||
|
ClientBin/
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
idea/
|
||||||
|
*.sln.iml
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<Application x:Class="MCI18n.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:MCI18n"
|
||||||
|
StartupUri="MainWindow.xaml">
|
||||||
|
<Application.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<!-- 引入自定义按钮样式 -->
|
||||||
|
<ResourceDictionary Source="Theme/MCButtonStyle.xaml"/>
|
||||||
|
<ResourceDictionary Source="Theme/MCTabTheme.xaml"/>
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Data;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace MCI18n
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
[assembly: ThemeInfo(
|
||||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// or application resource dictionaries)
|
||||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// app, or any theme specific resource dictionaries)
|
||||||
|
)]
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace MCI18n;
|
||||||
|
|
||||||
|
public class NullToVisibilityConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return value != null ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="einformation_7new_mechanics.snbt">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\SharpNBT\SharpNBT\SharpNBT.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Models\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.14.36212.18
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MCI18n", "MCI18n.csproj", "{471DA248-800A-4E64-94FA-F7054AEA248F}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpNBT", "..\SharpNBT\SharpNBT\SharpNBT.csproj", "{173F7856-B894-5F24-D410-91B18378A44B}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{471DA248-800A-4E64-94FA-F7054AEA248F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{471DA248-800A-4E64-94FA-F7054AEA248F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{471DA248-800A-4E64-94FA-F7054AEA248F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{471DA248-800A-4E64-94FA-F7054AEA248F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{173F7856-B894-5F24-D410-91B18378A44B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{173F7856-B894-5F24-D410-91B18378A44B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{173F7856-B894-5F24-D410-91B18378A44B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{173F7856-B894-5F24-D410-91B18378A44B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {DF86C6F0-F56B-49DD-BF07-99777173117F}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<Window
|
||||||
|
x:Class="MCI18n.MainWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:MCI18n"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
Title="SNBT编辑器"
|
||||||
|
Width="900"
|
||||||
|
Height="600"
|
||||||
|
Background="#3d3d3d"
|
||||||
|
Foreground="White"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Window.DataContext>
|
||||||
|
<local:MainWindowViewModel />
|
||||||
|
</Window.DataContext>
|
||||||
|
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- 工具栏 -->
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="0"
|
||||||
|
Margin="10"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Button
|
||||||
|
Width="100"
|
||||||
|
Height="30"
|
||||||
|
Command="{Binding LoadQuestsCommand}"
|
||||||
|
Content="打开文件夹"
|
||||||
|
Style="{StaticResource MinecraftButtonStyle}" />
|
||||||
|
<Button
|
||||||
|
Width="100"
|
||||||
|
Height="30"
|
||||||
|
Command="{Binding SaveQuestAsCommand}"
|
||||||
|
Content="另存为"
|
||||||
|
Style="{StaticResource MinecraftButtonStyle}" />
|
||||||
|
<Button
|
||||||
|
Width="100"
|
||||||
|
Height="30"
|
||||||
|
Command="{Binding SaveQuestCommand}"
|
||||||
|
Content="保存(覆盖)"
|
||||||
|
Style="{StaticResource MinecraftButtonStyle}" />
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
<TabControl Grid.Row="1">
|
||||||
|
<TabItem Header="任务列表" />
|
||||||
|
<TabItem Header="战利品列表" />
|
||||||
|
</TabControl>
|
||||||
|
<!-- 状态栏
|
||||||
|
<StatusBar Grid.Row="2" Background="Transparent">
|
||||||
|
<TextBlock Background="Transparent" Foreground="White" Text="{Binding CurrentFilePath, StringFormat={}当前文件: {0}, TargetNullValue=未打开任何文件}"/>
|
||||||
|
</StatusBar>-->
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
using MCI18n.Utilities;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace MCI18n
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MainWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
private MainWindowViewModel viewModel;
|
||||||
|
public MainWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.DataContext = viewModel = new MainWindowViewModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using MCI18n.Utilities;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using SharpNBT;
|
||||||
|
using SharpNBT.SNBT;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace MCI18n
|
||||||
|
{
|
||||||
|
public partial class MainWindowViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _currentFilePath;
|
||||||
|
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void LoadQuests()
|
||||||
|
{
|
||||||
|
var openFileDialog = new OpenFileDialog
|
||||||
|
{
|
||||||
|
Filter = "SNBT Files (*.snbt)|*.snbt|All Files (*.*)|*.*",
|
||||||
|
Title = "选择SNBT文件"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (openFileDialog.ShowDialog() == true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CurrentFilePath = openFileDialog.FileName;
|
||||||
|
//var questData = SNBTParser.LoadFromFile<QuestData>(CurrentFilePath);
|
||||||
|
var questData = StringNbt.Parse(File.ReadAllText(CurrentFilePath));
|
||||||
|
//if (questData != null)
|
||||||
|
//{
|
||||||
|
// //QuestList = new ObservableCollection<QuestData> { questData };
|
||||||
|
// //SelectedQuest = questData;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// //QuestList = new ObservableCollection<QuestData>();
|
||||||
|
// //SelectedQuest = null;
|
||||||
|
//}
|
||||||
|
//var fileContent = File.ReadAllText(CurrentFilePath, Encoding.UTF8);
|
||||||
|
//var parser = new NbtTagParser();
|
||||||
|
//var snbtData = parser.Parse(fileContent);
|
||||||
|
// var datas = SNBTParser.LoadFromFile(CurrentFilePath).Parse();
|
||||||
|
|
||||||
|
// 解析SNBT文件
|
||||||
|
//var data = SNBTParser.ParseFile(CurrentFilePath);
|
||||||
|
//NbtFile.Write(CurrentFilePath + ".r", questData, FormatOptions.None);
|
||||||
|
//StringNbt.SaveToFile(questData, CurrentFilePath + ".r",prettyPrint:true);
|
||||||
|
SnbtWriter.SaveToFile(questData, CurrentFilePath + ".r", prettyPrint: true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"加载文件失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void SaveQuest()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void SaveQuestAs()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void CreateNewQuest()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Any CPU</Platform>
|
||||||
|
<PublishDir>bin\Release\net8.0-windows\publish\win-x64\</PublishDir>
|
||||||
|
<PublishProtocol>FileSystem</PublishProtocol>
|
||||||
|
<_TargetId>Folder</_TargetId>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
<SelfContained>false</SelfContained>
|
||||||
|
<PublishSingleFile>true</PublishSingleFile>
|
||||||
|
<PublishReadyToRun>false</PublishReadyToRun>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Style TargetType="Button" x:Key="MinecraftButtonStyle">
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
<Setter Property="Background" Value="#48494a"/>
|
||||||
|
<Setter Property="BorderBrush" Value="#373737"/>
|
||||||
|
<Setter Property="BorderThickness" Value="2"/>
|
||||||
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||||
|
<Setter Property="FontWeight" Value="Bold"/>
|
||||||
|
<Setter Property="Padding" Value="10,5"/>
|
||||||
|
<Setter Property="Cursor" Value="Hand"/>
|
||||||
|
<Setter Property="Margin" Value="2"/>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type Button}">
|
||||||
|
<Border
|
||||||
|
BorderBrush="Black"
|
||||||
|
BorderThickness="2"
|
||||||
|
>
|
||||||
|
<Grid>
|
||||||
|
<!-- 按钮底部阴影 -->
|
||||||
|
<Border x:Name="ShadowBorder"
|
||||||
|
Background="#313233"
|
||||||
|
CornerRadius="0" />
|
||||||
|
|
||||||
|
<!-- 按钮主体 -->
|
||||||
|
<Border x:Name="MainBorder"
|
||||||
|
Background="#5B5B5B"
|
||||||
|
BorderBrush="#373737"
|
||||||
|
BorderThickness="2,2,2,4"
|
||||||
|
CornerRadius="0"
|
||||||
|
Margin="0,0,0,0">
|
||||||
|
|
||||||
|
<ContentPresenter x:Name="ContentPresenter"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Content="{TemplateBinding Content}"
|
||||||
|
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||||
|
TextElement.Foreground="{TemplateBinding Foreground}"/>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<!-- 鼠标悬停效果 -->
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="MainBorder" Property="Background" Value="#6B6B6B"/>
|
||||||
|
<Setter TargetName="MainBorder" Property="BorderBrush" Value="#cccccc"/>
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<!-- 点击效果 -->
|
||||||
|
<Trigger Property="IsPressed" Value="True">
|
||||||
|
<Setter TargetName="MainBorder" Property="Margin" Value="0,2,0,0"/>
|
||||||
|
<Setter TargetName="MainBorder" Property="BorderThickness" Value="2,2,2,2"/>
|
||||||
|
<Setter TargetName="ShadowBorder" Property="Visibility" Value="Hidden"/>
|
||||||
|
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<!-- 禁用效果 -->
|
||||||
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
|
<Setter TargetName="MainBorder" Property="Background" Value="#3F3F3F"/>
|
||||||
|
<Setter TargetName="MainBorder" Property="BorderBrush" Value="#2A2A2A"/>
|
||||||
|
<Setter Property="Foreground" Value="#909090"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Style TargetType="TabControl">
|
||||||
|
<Setter Property="Background" Value="#48494a" />
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="TabItem">
|
||||||
|
<Setter Property="Background" Value="#48494a" />
|
||||||
|
<Setter Property="Foreground" Value="#fff" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type TabItem}">
|
||||||
|
|
||||||
|
|
||||||
|
<!--<Grid>
|
||||||
|
<Border Background="{TemplateBinding Background}" BorderBrush="#373737" BorderThickness="2">
|
||||||
|
<ContentPresenter x:Name="ContentSite"
|
||||||
|
ContentSource="Header"
|
||||||
|
Margin="0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
</Border>
|
||||||
|
</Grid>-->
|
||||||
|
<Border
|
||||||
|
x:Name="OutBorder"
|
||||||
|
BorderBrush="Black"
|
||||||
|
BorderThickness="1">
|
||||||
|
<Grid>
|
||||||
|
<!-- 按钮底部阴影 -->
|
||||||
|
<Border
|
||||||
|
x:Name="ShadowBorder"
|
||||||
|
Background="#313233"
|
||||||
|
CornerRadius="0" />
|
||||||
|
|
||||||
|
<!-- 按钮主体 -->
|
||||||
|
<Border
|
||||||
|
x:Name="MainBorder"
|
||||||
|
Margin="0,0,0,0"
|
||||||
|
Background="#5B5B5B"
|
||||||
|
BorderBrush="#373737"
|
||||||
|
BorderThickness="1,1,1,1"
|
||||||
|
CornerRadius="0">
|
||||||
|
|
||||||
|
<ContentPresenter
|
||||||
|
x:Name="ContentSite"
|
||||||
|
Margin="0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
ContentSource="Header" />
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<!-- 鼠标悬停效果 -->
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="MainBorder" Property="Background" Value="#6B6B6B" />
|
||||||
|
<Setter TargetName="MainBorder" Property="BorderBrush" Value="#cccccc" />
|
||||||
|
</Trigger>
|
||||||
|
|
||||||
|
<!-- 选中效果 -->
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Setter TargetName="MainBorder" Property="BorderThickness" Value="1,1,1,4" />
|
||||||
|
<Setter TargetName="ShadowBorder" Property="Visibility" Value="Hidden" />
|
||||||
|
<Setter TargetName="OutBorder" Property="BorderBrush" Value="#cccccc" />
|
||||||
|
<Setter TargetName="OutBorder" Property="BorderThickness" Value="1,1,1,0" />
|
||||||
|
|
||||||
|
</Trigger>
|
||||||
|
<!-- 禁用效果 -->
|
||||||
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
|
<Setter TargetName="MainBorder" Property="Background" Value="#3F3F3F" />
|
||||||
|
<Setter TargetName="MainBorder" Property="BorderBrush" Value="#2A2A2A" />
|
||||||
|
<Setter Property="Foreground" Value="#909090" />
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
|
|
@ -0,0 +1,211 @@
|
||||||
|
using SharpNBT;
|
||||||
|
using SharpNBT.SNBT;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MCI18n.Utilities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 提供用于将CompoundTag保存为SNBT格式文件的工具方法
|
||||||
|
/// </summary>
|
||||||
|
public static class SnbtWriter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 将CompoundTag保存为SNBT格式文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tag">要保存的CompoundTag</param>
|
||||||
|
/// <param name="filePath">文件路径</param>
|
||||||
|
/// <param name="prettyPrint">是否进行美化格式输出</param>
|
||||||
|
/// <exception cref="ArgumentNullException">当tag为null时抛出</exception>
|
||||||
|
/// <exception cref="IOException">写入文件失败时抛出</exception>
|
||||||
|
public static void SaveToFile(CompoundTag tag, string filePath, bool prettyPrint = true)
|
||||||
|
{
|
||||||
|
if (tag == null)
|
||||||
|
throw new ArgumentNullException(nameof(tag));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string snbt = ConvertToSnbt(tag, prettyPrint);
|
||||||
|
File.WriteAllText(filePath, snbt, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or DirectoryNotFoundException)
|
||||||
|
{
|
||||||
|
throw new IOException($"保存SNBT文件失败 '{filePath}': {ex.Message}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将CompoundTag转换为SNBT格式字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tag">要转换的CompoundTag</param>
|
||||||
|
/// <param name="prettyPrint">是否美化输出格式</param>
|
||||||
|
/// <returns>SNBT格式字符串</returns>
|
||||||
|
public static string ConvertToSnbt(CompoundTag tag, bool prettyPrint = true)
|
||||||
|
{
|
||||||
|
if (prettyPrint)
|
||||||
|
return FormatCompound(tag, 0);
|
||||||
|
else
|
||||||
|
return tag.Stringify(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatCompound(CompoundTag tag, int indentLevel)
|
||||||
|
{
|
||||||
|
if (tag.Count == 0)
|
||||||
|
return "{}";
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("{");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
foreach (var child in tag)
|
||||||
|
{
|
||||||
|
sb.Append('\t', indentLevel + 1);
|
||||||
|
sb.Append($"{EscapeName(child.Name)}: ");
|
||||||
|
sb.Append(FormatTag(child, indentLevel + 1));
|
||||||
|
|
||||||
|
//if (i < tag.Count - 1)
|
||||||
|
// sb.AppendLine(",");
|
||||||
|
//else
|
||||||
|
// sb.AppendLine();
|
||||||
|
sb.AppendLine();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append('\t', indentLevel);
|
||||||
|
sb.Append("}");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatTag(Tag tag, int indentLevel)
|
||||||
|
{
|
||||||
|
switch (tag)
|
||||||
|
{
|
||||||
|
case CompoundTag compoundTag:
|
||||||
|
return FormatCompound(compoundTag, indentLevel);
|
||||||
|
|
||||||
|
case ListTag listTag:
|
||||||
|
return FormatList(listTag, indentLevel);
|
||||||
|
|
||||||
|
case ByteArrayTag byteArrayTag:
|
||||||
|
return FormatArray(byteArrayTag, 'B', 'b', indentLevel);
|
||||||
|
|
||||||
|
case IntArrayTag intArrayTag:
|
||||||
|
return FormatArray(intArrayTag, 'I', null, indentLevel);
|
||||||
|
|
||||||
|
case LongArrayTag longArrayTag:
|
||||||
|
return FormatArray(longArrayTag, 'L', 'L', indentLevel);
|
||||||
|
|
||||||
|
case StringTag stringTag:
|
||||||
|
return $"\"{EscapeString(stringTag.Value)}\"";
|
||||||
|
|
||||||
|
case ByteTag byteTag:
|
||||||
|
//return $"{byteTag.Value}b";
|
||||||
|
return byteTag.Bool ? "true" : "false";
|
||||||
|
|
||||||
|
case ShortTag shortTag:
|
||||||
|
return $"{shortTag.Value}s";
|
||||||
|
|
||||||
|
case IntTag intTag:
|
||||||
|
return intTag.Value.ToString();
|
||||||
|
|
||||||
|
case LongTag longTag:
|
||||||
|
return $"{longTag.Value}L";
|
||||||
|
|
||||||
|
case FloatTag floatTag:
|
||||||
|
return $"{floatTag.Value.ToString("0.#####", CultureInfo.InvariantCulture)}f";
|
||||||
|
|
||||||
|
case DoubleTag doubleTag:
|
||||||
|
return $"{doubleTag.Value.ToString("0.#####", CultureInfo.InvariantCulture)}d";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return tag.Stringify(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatList(ListTag listTag, int indentLevel)
|
||||||
|
{
|
||||||
|
if (listTag.Count == 0)
|
||||||
|
return "[]";
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("[");
|
||||||
|
|
||||||
|
for (int i = 0; i < listTag.Count; i++)
|
||||||
|
{
|
||||||
|
sb.Append('\t', indentLevel + 1);
|
||||||
|
sb.Append(FormatTag(listTag[i], indentLevel + 1));
|
||||||
|
|
||||||
|
//if (i < listTag.Count - 1)
|
||||||
|
// sb.AppendLine(",");
|
||||||
|
//else
|
||||||
|
// sb.AppendLine();
|
||||||
|
sb.AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append('\t', indentLevel);
|
||||||
|
sb.Append("]");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatArray<T>(ArrayTag<T> arrayTag, char prefix, char? suffix, int indentLevel)
|
||||||
|
where T : unmanaged, INumber<T>
|
||||||
|
{
|
||||||
|
if (arrayTag.Count == 0)
|
||||||
|
return $"[{prefix};]";
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.Append($"[{prefix};");
|
||||||
|
|
||||||
|
// 对于数组类型,我们通常不使用多行格式
|
||||||
|
for (int i = 0; i < arrayTag.Count; i++)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
sb.AppendLine();
|
||||||
|
//sb.Append("\r\n");
|
||||||
|
|
||||||
|
|
||||||
|
sb.Append(arrayTag[i]);
|
||||||
|
|
||||||
|
if (suffix != null)
|
||||||
|
sb.Append(suffix.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append("]");
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string EscapeName(string name)
|
||||||
|
{
|
||||||
|
// 如果名称包含特殊字符,需要用引号括起来
|
||||||
|
if (string.IsNullOrEmpty(name) || NeedsQuotes(name))
|
||||||
|
return $"\"{EscapeString(name)}\"";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool NeedsQuotes(string s)
|
||||||
|
{
|
||||||
|
foreach (char c in s)
|
||||||
|
{
|
||||||
|
if (!char.IsLetterOrDigit(c) && c != '_' && c != '-' && c != '.')
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string EscapeString(string str)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(str))
|
||||||
|
return str;
|
||||||
|
|
||||||
|
return str.Replace("\\", "\\\\")
|
||||||
|
.Replace("\"", "\\\"")
|
||||||
|
.Replace("\n", "\\n")
|
||||||
|
.Replace("\r", "\\r")
|
||||||
|
.Replace("\t", "\\t");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue