using Microsoft.UI.Xaml.Media.Imaging;
using Microsoft.Win32;
using Sandbox.Definitions;
using SpaceEngineersBlueprintEditor.Model;
using SpaceEngineersBlueprintEditor.SpaceEngineersCore;
using System.Collections;
using System.Reflection;
using VRage.Collections;
using VRage.Game;
using XFEExtension.NetCore.FileExtension;
namespace SpaceEngineersBlueprintEditor.Utilities.Helpers;
/// <summary>
/// 太空工程师帮助类
/// </summary>
public static class SpaceEngineersHelper
{
/// <summary>
/// 加载完成事件
/// </summary>
public static event EventHandler? LoadComplete;
/// <summary>
/// 普通块
/// </summary>
public static string[] NormalBlock { get; } =
[
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundSlope" ,
"<SubtypeName>LargeBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransition</SubtypeName>",
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundSlope" ,
"<SubtypeName>SmallBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTip</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransition</SubtypeName>",
];
/// <summary>
/// 重甲块
/// </summary>
public static string[] HeavyBlock { get; } =
[
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundSlope" ,
"<SubtypeName>LargeHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransition</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundSlope" ,
"<SubtypeName>SmallHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransition</SubtypeName>",
];
/// <summary>
/// 小型块
/// </summary>
public static string[] SmallBlock { get; } =
[
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundSlope" ,
"<SubtypeName>SmallBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTip</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransition</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundSlope" ,
"<SubtypeName>SmallHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransition</SubtypeName>",
"<GridSizeEnum>Small</GridSizeEnum>",
];
/// <summary>
/// 大型块
/// </summary>
public static string[] LargeBlock { get; } =
[
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundSlope" ,
"<SubtypeName>LargeBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransition</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundSlope" ,
"<SubtypeName>LargeHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransition</SubtypeName>",
"<GridSizeEnum>Large</GridSizeEnum>",
];
/// <summary>
/// 是否已经加载完成
/// </summary>
public static bool IsLoadComplete { get; private set; } = false;
/// <summary>
/// 所有类型定义集
/// </summary>
public static DictionaryValuesReader<MyDefinitionId, MyDefinitionBase> AllDefinitions => MyDefinitionManager.Static.GetAllDefinitions();
/// <summary>
/// 方块定义集
/// </summary>
public static IEnumerable<MyCubeBlockDefinition> CubeBlockDefinitions => AllDefinitions.Where(definition => definition is MyCubeBlockDefinition).Cast<MyCubeBlockDefinition>();
/// <summary>
/// 组件定义集
/// </summary>
public static IEnumerable<MyComponentDefinition> ComponentDefinitions => AllDefinitions.Where(definition => definition is MyComponentDefinition).Cast<MyComponentDefinition>();
/// <summary>
/// 物品定义集
/// </summary>
public static IEnumerable<MyPhysicalItemDefinition> ItemDefinitions => AllDefinitions.Where(definition => definition is MyPhysicalItemDefinition).Cast<MyPhysicalItemDefinition>();
/// <summary>
/// 场景定义集
/// </summary>
public static IEnumerable<MyScenarioDefinition> ScenarioDefinition => AllDefinitions.Where(definition => definition is MyScenarioDefinition).Cast<MyScenarioDefinition>();
/// <summary>
/// 加载蓝图模型
/// </summary>
/// <param name="blueprintFile">蓝图文件路径</param>
/// <returns>蓝图模型(异步)</returns>
public static async Task<BlueprintModel?> LoadBlueprintModel(string blueprintFile) => new()
{
ViewData = LoadBlueprintInfo(blueprintFile)?.ToBlueprintInfoViewData(),
BlueprintDefinitions = await LoadBlueprintAsync(blueprintFile)
};
/// <summary>
/// 异步加载蓝图定义
/// </summary>
/// <param name="blueprintFile">蓝图文件路径</param>
/// <returns>蓝图定义(异步)</returns>
public static async Task<MyObjectBuilder_Definitions> LoadBlueprintAsync(string blueprintFile) => await Task.Run(() => SpaceEngineerDefinitions.Load<MyObjectBuilder_Definitions>(blueprintFile));
/// <summary>
/// 加载蓝图信息
/// </summary>
/// <param name="blueprintFile">蓝图文件路径</param>
/// <returns>蓝图信息</returns>
public static BlueprintInfo? LoadBlueprintInfo(string blueprintFile)
{
var rootPath = Path.GetDirectoryName(blueprintFile);
var imagePath = $@"{rootPath}\thumb.png";
return new(imagePath, File.Exists(blueprintFile), File.Exists(imagePath), Path.GetFileName(rootPath)!, new FileInfo(blueprintFile).Length.FileSize(), blueprintFile);
}
/// <summary>
/// 分析蓝图定义
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <param name="exceptedName">不希望分析的属性名称列表</param>
public static void AnalyzeBlueprint(BlueprintPropertyViewData blueprintPropertyViewData, params string[] exceptedName)
{
if (blueprintPropertyViewData.IsAnalyzed)
return;
blueprintPropertyViewData.IsAnalyzed = true;
blueprintPropertyViewData.Children.Clear();
if (CheckIfNull(blueprintPropertyViewData))
return;
if (IsCyclicReference(blueprintPropertyViewData))
return;
if (IsSpecialObject(blueprintPropertyViewData))
return;
var canMutateParent = !blueprintPropertyViewData.Type!.IsValueType ||
blueprintPropertyViewData.ValueSetter is not null;
foreach (var member in GetBrowsableMembers(blueprintPropertyViewData.Type, exceptedName))
{
try
{
if (member is FieldInfo fieldInfo)
{
var value = fieldInfo.GetValue(blueprintPropertyViewData.Value);
var child = new BlueprintPropertyViewData()
{
Type = fieldInfo.FieldType,
Name = fieldInfo.Name,
Value = value,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
ValueSetter = canMutateParent && !fieldInfo.IsInitOnly && !fieldInfo.IsLiteral
? targetValue => fieldInfo.SetValue(blueprintPropertyViewData.Value, targetValue)
: null
};
SetDetail(child, value);
blueprintPropertyViewData.Children.Add(child);
}
else if (member is PropertyInfo propertyInfo)
{
var value = propertyInfo.GetValue(blueprintPropertyViewData.Value);
var child = new BlueprintPropertyViewData()
{
Type = propertyInfo.PropertyType,
Name = propertyInfo.Name,
Value = value,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
ValueSetter = canMutateParent && propertyInfo.SetMethod?.IsPublic == true
? targetValue => propertyInfo.SetValue(blueprintPropertyViewData.Value, targetValue)
: null
};
SetDetail(child, value);
blueprintPropertyViewData.Children.Add(child);
}
}
catch (Exception ex)
{
blueprintPropertyViewData.Children.Add(new()
{
Type = member is FieldInfo field ? field.FieldType :
member is PropertyInfo property ? property.PropertyType : null,
Name = member.Name,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
HasError = true,
ErrorMessage = ex.GetBaseException().Message,
CustomData = ex.GetBaseException().Message
});
}
}
}
private static IEnumerable<MemberInfo> GetBrowsableMembers(Type type, string[] exceptedNames)
{
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
var fields = type.GetFields(flags)
.Where(field => !field.IsStatic)
.Cast<MemberInfo>();
var properties = type.GetProperties(flags)
.Where(property => property.GetMethod?.IsPublic == true &&
property.GetIndexParameters().Length == 0)
.Cast<MemberInfo>();
return fields
.Concat(properties)
.Where(member => !exceptedNames.Contains(member.Name, StringComparer.Ordinal))
.GroupBy(member => member.Name, StringComparer.Ordinal)
.Select(group => group.First())
.OrderBy(member => member.Name, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// 检测是否为Null
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <returns>是否为Null</returns>
private static bool CheckIfNull(BlueprintPropertyViewData blueprintPropertyViewData)
{
if (blueprintPropertyViewData.Value is null || blueprintPropertyViewData.Type is null)
{
blueprintPropertyViewData.CustomData = "NullObject".GetLocalized();
return true;
}
return false;
}
private static bool IsCyclicReference(BlueprintPropertyViewData blueprintPropertyViewData)
{
if (blueprintPropertyViewData.Type?.IsValueType != false)
return false;
for (var ancestor = blueprintPropertyViewData.Parent; ancestor is not null; ancestor = ancestor.Parent)
{
if (!ReferenceEquals(ancestor.Value, blueprintPropertyViewData.Value))
continue;
blueprintPropertyViewData.CustomData = "Cyclic reference";
return true;
}
return false;
}
/// <summary>
/// 是否是特殊对象
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <returns>是否是特殊对象</returns>
private static bool IsSpecialObject(BlueprintPropertyViewData blueprintPropertyViewData)
{
if (blueprintPropertyViewData.IsEnumerable)
{
AddArrayOrEnumerableChildren(blueprintPropertyViewData);
return true;
}
return false;
}
/// <summary>
/// 添加数组或者枚举类型子数据
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
private static void AddArrayOrEnumerableChildren(BlueprintPropertyViewData blueprintPropertyViewData)
{
var enumerable = (IEnumerable)blueprintPropertyViewData.Value!;
var list = enumerable as IList;
var index = 0;
foreach (var item in enumerable)
{
var type = item?.GetType() ?? GetEnumerableElementType(blueprintPropertyViewData.Type!) ?? typeof(object);
var itemIndex = index;
var child = new BlueprintPropertyViewData()
{
Type = type,
Name = $"[{itemIndex}]",
DisplayNameOverride = $"[{itemIndex}] {type.Name}",
Value = item,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
ValueSetter = list is not null && !list.IsReadOnly
? targetValue => list[itemIndex] = targetValue
: null
};
SetDetail(child, item);
blueprintPropertyViewData.Children.Add(child);
index++;
}
}
private static Type? GetEnumerableElementType(Type enumerableType)
{
if (enumerableType.IsArray)
return enumerableType.GetElementType();
return enumerableType
.GetInterfaces()
.Append(enumerableType)
.FirstOrDefault(type => type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
?.GetGenericArguments()[0];
}
/// <summary>
/// 设置定义细节
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <param name="value">目标定义值</param>
public static void SetDetail(BlueprintPropertyViewData blueprintPropertyViewData, object? value)
{
if (value is MyObjectBuilder_CubeBlock myObjectBuilder_CubeBlock)
{
try
{
var cubeBlock = MyDefinitionManager.Static.GetCubeBlockDefinition(myObjectBuilder_CubeBlock);
var blockName = cubeBlock?.DisplayNameText ??
myObjectBuilder_CubeBlock.SubtypeName ??
myObjectBuilder_CubeBlock.GetType().Name;
if (blueprintPropertyViewData.Name?.StartsWith('[') == true)
blueprintPropertyViewData.DisplayNameOverride = $"{blockName} {blueprintPropertyViewData.Name}";
if (cubeBlock?.Icons is { Length: > 0 })
{
var imagePath = @$"{AppPath.DefinitionImages}\{FileHelper.ChangeExtension(cubeBlock.Icons[0], "png")}";
if (File.Exists(imagePath))
blueprintPropertyViewData.CubeImage = new BitmapImage(new Uri(imagePath));
}
}
catch
{
// Mod blocks can legitimately have no currently loaded definition or icon.
}
blueprintPropertyViewData.CustomData = value is MyObjectBuilder_TerminalBlock terminalBlock
? terminalBlock.CustomName
: myObjectBuilder_CubeBlock.SubtypeName;
}
else if (value is MyObjectBuilder_CubeGrid myObjectBuilder_CubeGrid)
{
blueprintPropertyViewData.CustomData = myObjectBuilder_CubeGrid.DisplayName;
if (blueprintPropertyViewData.Name?.StartsWith('[') == true)
blueprintPropertyViewData.DisplayNameOverride =
$"{myObjectBuilder_CubeGrid.DisplayName} {blueprintPropertyViewData.Name}";
}
else if (blueprintPropertyViewData.IsEnumerable)
{
var count = value is ICollection collection
? collection.Count
: value is null
? 0
: ((IEnumerable)value).Cast<object?>().Count();
blueprintPropertyViewData.CustomData = $"{"Amount".GetLocalized()}: {count}";
}
else
{
blueprintPropertyViewData.CustomData = blueprintPropertyViewData.IsBasicType
? blueprintPropertyViewData.ValueString
: null;
}
}
/// <summary>
/// 异步加载定义集列表
/// </summary>
/// <returns>异步任务</returns>
public static async Task LoadDefinitionViewDataListAsync()
{
await Helper.Wait(() => Initializer.IsDefinitionsLoadComplete);
foreach (var definition in AllDefinitions)
if (definition is not null && definition.Icons is not null && definition.Icons.Length > 0)
{
var originalPath = @$"{SpaceEngineersPath.SpaceEngineerContentPath}\{definition.Icons[0]}";
var targetPath = @$"{AppPath.DefinitionImages}\{FileHelper.ChangeExtension(definition.Icons[0], "png")}";
FileHelper.AutoCreateDirectory(targetPath);
if (!File.Exists(targetPath))
FileHelper.ToBitmap(originalPath, targetPath);
}
IsLoadComplete = true;
LoadComplete?.Invoke(null, EventArgs.Empty);
}
/// <summary>
/// 获取定义集
/// </summary>
/// <param name="m_hash">哈希值</param>
/// <returns>定义集</returns>
public static MyDefinitionBase? GetDefinition(int m_hash) => AllDefinitions.First(definition => definition.Id.SubtypeId.m_hash == m_hash);
/// <summary>
/// 获取游戏的根目录路径
/// </summary>
/// <returns>游戏的根目录路径</returns>
public static string? GetGameRootPath()
{
var path = GetGameRootPath(@"C:\", @"D:\", @"E:\", @"F:\", @"G:\", @"H:\", @"I:\", @"J:\", @"K:\", @"L:\", @"M:\", @"N:\", @"O:\", @"P:\", @"Q:\", @"R:\", @"S:\", @"T:\", @"U:\", @"V:\", @"W:\", @"X:\", @"Y:\", @"Z:\");
if (path is not null)
return path;
if ((Environment.Is64BitProcess ? Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 244850", false) : Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 244850", false)) is RegistryKey registryKey && registryKey.GetValue("InstallLocation")?.ToString() is string stringValue && !string.IsNullOrEmpty(stringValue))
{
return stringValue;
}
path = GetSteamFilePath();
if (!string.IsNullOrEmpty(path))
return Path.Combine(path, @"SteamApps\common\SpaceEngineers");
return null;
}
/// <summary>
/// 获取游戏的根目录路径
/// </summary>
/// <param name="roots">需要检测的磁盘索引</param>
/// <returns></returns>
public static string? GetGameRootPath(params string[] roots)
{
foreach (var root in roots)
{
var targetPath = $@"{root}SteamLibrary\steamapps\common\SpaceEngineers\Bin64\SpaceEngineers.exe";
if (File.Exists(targetPath))
return $@"{root}SteamLibrary\steamapps\common\SpaceEngineers";
}
return null;
}
/// <summary>
/// 获取Steam游戏文件的根目录
/// </summary>
/// <returns></returns>
public static string? GetSteamFilePath()
{
if ((Environment.Is64BitProcess ? Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Valve\Steam", false) : Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Valve\Steam", false)) is RegistryKey registryKey)
return registryKey.GetValue("InstallPath")?.ToString();
else
return null;
}
/// <summary>
/// 字符串逐个替换
/// </summary>
/// <param name="targetString"></param>
/// <param name="sourceArray"></param>
/// <param name="targetArray"></param>
/// <returns></returns>
public static string ForeachReplace(string targetString, string[] sourceArray, string[] targetArray)
{
int i = 0;
foreach (var sourceString in sourceArray)
{
targetString = targetString.Replace(sourceString, targetArray[i]);
i++;
}
return targetString;
}
}
using Microsoft.UI.Xaml.Media.Imaging;
using Microsoft.Win32;
using Sandbox.Definitions;
using SpaceEngineersBlueprintEditor.Model;
using SpaceEngineersBlueprintEditor.SpaceEngineersCore;
using System.Collections;
using System.Reflection;
using VRage.Collections;
using VRage.Game;
using XFEExtension.NetCore.FileExtension;
namespace SpaceEngineersBlueprintEditor.Utilities.Helpers;
/// <summary>
/// 太空工程师帮助类
/// </summary>
public static class SpaceEngineersHelper
{
/// <summary>
/// 加载完成事件
/// </summary>
public static event EventHandler? LoadComplete;
/// <summary>
/// 普通块
/// </summary>
public static string[] NormalBlock { get; } =
[
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundSlope" ,
"<SubtypeName>LargeBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransition</SubtypeName>",
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundSlope" ,
"<SubtypeName>SmallBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTip</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransition</SubtypeName>",
];
/// <summary>
/// 重甲块
/// </summary>
public static string[] HeavyBlock { get; } =
[
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundSlope" ,
"<SubtypeName>LargeHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransition</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundSlope" ,
"<SubtypeName>SmallHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransition</SubtypeName>",
];
/// <summary>
/// 小型块
/// </summary>
public static string[] SmallBlock { get; } =
[
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundSlope" ,
"<SubtypeName>SmallBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTip</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>SmallBlockArmorSlopeTransition</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundSlope" ,
"<SubtypeName>SmallHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>HeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>HeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>SmallHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>SmallArmorPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>SmallArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>SmallArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>SmallArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>SmallBlockHeavyArmorSlopeTransition</SubtypeName>",
"<GridSizeEnum>Small</GridSizeEnum>",
];
/// <summary>
/// 大型块
/// </summary>
public static string[] LargeBlock { get; } =
[
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundSlope" ,
"<SubtypeName>LargeBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelLightRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLightInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipLight</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelLight</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelLight</SubtypeName>",
"<SubtypeName>LargeBlockArmorSlopeTransition</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundSlope" ,
"<SubtypeName>LargeHeavyBlockArmorRoundCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorRoundCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopedCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfCorner</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCorner</SubtypeName>",
"<SubtypeName>LargeHeavyHalfSlopeArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyHalfArmorBlock</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorBlock</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquareInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorCornerSquare</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCornerInv</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorSlope</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Base</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeInverted</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorHalfSlopeCornerInverted</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Tip</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorInvCorner2Base</SubtypeName>",
"<SubtypeName>LargeHeavyBlockArmorCorner2Tip</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBase</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTipMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionBaseMirrored</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransitionTip</SubtypeName>",
"<SubtypeName>LargeArmorPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorQuarterPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorHalfPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyLeft</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedTipPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmor2x1HalfSlopedPanelHeavyRight</SubtypeName>",
"<SubtypeName>LargeArmorHalfSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavyInv</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideTipPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedSideBasePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelTipHeavy</SubtypeName>",
"<SubtypeName>LargeArmor2x1SlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedSidePanelHeavy</SubtypeName>",
"<SubtypeName>LargeArmorSlopedPanelHeavy</SubtypeName>",
"<SubtypeName>LargeBlockHeavyArmorSlopeTransition</SubtypeName>",
"<GridSizeEnum>Large</GridSizeEnum>",
];
/// <summary>
/// 是否已经加载完成
/// </summary>
public static bool IsLoadComplete { get; private set; } = false;
/// <summary>
/// 所有类型定义集
/// </summary>
public static DictionaryValuesReader<MyDefinitionId, MyDefinitionBase> AllDefinitions => MyDefinitionManager.Static.GetAllDefinitions();
/// <summary>
/// 方块定义集
/// </summary>
public static IEnumerable<MyCubeBlockDefinition> CubeBlockDefinitions => AllDefinitions.Where(definition => definition is MyCubeBlockDefinition).Cast<MyCubeBlockDefinition>();
/// <summary>
/// 组件定义集
/// </summary>
public static IEnumerable<MyComponentDefinition> ComponentDefinitions => AllDefinitions.Where(definition => definition is MyComponentDefinition).Cast<MyComponentDefinition>();
/// <summary>
/// 物品定义集
/// </summary>
public static IEnumerable<MyPhysicalItemDefinition> ItemDefinitions => AllDefinitions.Where(definition => definition is MyPhysicalItemDefinition).Cast<MyPhysicalItemDefinition>();
/// <summary>
/// 场景定义集
/// </summary>
public static IEnumerable<MyScenarioDefinition> ScenarioDefinition => AllDefinitions.Where(definition => definition is MyScenarioDefinition).Cast<MyScenarioDefinition>();
/// <summary>
/// 加载蓝图模型
/// </summary>
/// <param name="blueprintFile">蓝图文件路径</param>
/// <returns>蓝图模型(异步)</returns>
public static async Task<BlueprintModel?> LoadBlueprintModel(string blueprintFile) => new()
{
ViewData = LoadBlueprintInfo(blueprintFile)?.ToBlueprintInfoViewData(),
BlueprintDefinitions = await LoadBlueprintAsync(blueprintFile)
};
/// <summary>
/// 异步加载蓝图定义
/// </summary>
/// <param name="blueprintFile">蓝图文件路径</param>
/// <returns>蓝图定义(异步)</returns>
public static async Task<MyObjectBuilder_Definitions> LoadBlueprintAsync(string blueprintFile) => await Task.Run(() => SpaceEngineerDefinitions.Load<MyObjectBuilder_Definitions>(blueprintFile));
/// <summary>
/// 加载蓝图信息
/// </summary>
/// <param name="blueprintFile">蓝图文件路径</param>
/// <returns>蓝图信息</returns>
public static BlueprintInfo? LoadBlueprintInfo(string blueprintFile)
{
var rootPath = Path.GetDirectoryName(blueprintFile);
var imagePath = $@"{rootPath}\thumb.png";
return new(imagePath, File.Exists(blueprintFile), File.Exists(imagePath), Path.GetFileName(rootPath)!, new FileInfo(blueprintFile).Length.FileSize(), blueprintFile);
}
/// <summary>
/// 分析蓝图定义
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <param name="exceptedName">不希望分析的属性名称列表</param>
public static void AnalyzeBlueprint(BlueprintPropertyViewData blueprintPropertyViewData, params string[] exceptedName)
{
if (blueprintPropertyViewData.IsAnalyzed)
return;
blueprintPropertyViewData.IsAnalyzed = true;
blueprintPropertyViewData.Children.Clear();
if (CheckIfNull(blueprintPropertyViewData))
return;
if (IsCyclicReference(blueprintPropertyViewData))
return;
if (IsSpecialObject(blueprintPropertyViewData))
return;
var canMutateParent = !blueprintPropertyViewData.Type!.IsValueType ||
blueprintPropertyViewData.ValueSetter is not null;
foreach (var member in GetBrowsableMembers(blueprintPropertyViewData.Type, exceptedName))
{
try
{
if (member is FieldInfo fieldInfo)
{
var value = fieldInfo.GetValue(blueprintPropertyViewData.Value);
var child = new BlueprintPropertyViewData()
{
Type = fieldInfo.FieldType,
Name = fieldInfo.Name,
Value = value,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
ValueSetter = canMutateParent && !fieldInfo.IsInitOnly && !fieldInfo.IsLiteral
? targetValue => fieldInfo.SetValue(blueprintPropertyViewData.Value, targetValue)
: null
};
SetDetail(child, value);
blueprintPropertyViewData.Children.Add(child);
}
else if (member is PropertyInfo propertyInfo)
{
var value = propertyInfo.GetValue(blueprintPropertyViewData.Value);
var child = new BlueprintPropertyViewData()
{
Type = propertyInfo.PropertyType,
Name = propertyInfo.Name,
Value = value,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
ValueSetter = canMutateParent && propertyInfo.SetMethod?.IsPublic == true
? targetValue => propertyInfo.SetValue(blueprintPropertyViewData.Value, targetValue)
: null
};
SetDetail(child, value);
blueprintPropertyViewData.Children.Add(child);
}
}
catch (Exception ex)
{
blueprintPropertyViewData.Children.Add(new()
{
Type = member is FieldInfo field ? field.FieldType :
member is PropertyInfo property ? property.PropertyType : null,
Name = member.Name,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
HasError = true,
ErrorMessage = ex.GetBaseException().Message,
CustomData = ex.GetBaseException().Message
});
}
}
}
private static IEnumerable<MemberInfo> GetBrowsableMembers(Type type, string[] exceptedNames)
{
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
var fields = type.GetFields(flags)
.Where(field => !field.IsStatic)
.Cast<MemberInfo>();
var properties = type.GetProperties(flags)
.Where(property => property.GetMethod?.IsPublic == true &&
property.GetIndexParameters().Length == 0)
.Cast<MemberInfo>();
return fields
.Concat(properties)
.Where(member => !exceptedNames.Contains(member.Name, StringComparer.Ordinal))
.GroupBy(member => member.Name, StringComparer.Ordinal)
.Select(group => group.First())
.OrderBy(member => member.Name, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// 检测是否为Null
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <returns>是否为Null</returns>
private static bool CheckIfNull(BlueprintPropertyViewData blueprintPropertyViewData)
{
if (blueprintPropertyViewData.Value is null || blueprintPropertyViewData.Type is null)
{
blueprintPropertyViewData.CustomData = "NullObject".GetLocalized();
return true;
}
return false;
}
private static bool IsCyclicReference(BlueprintPropertyViewData blueprintPropertyViewData)
{
if (blueprintPropertyViewData.Type?.IsValueType != false)
return false;
for (var ancestor = blueprintPropertyViewData.Parent; ancestor is not null; ancestor = ancestor.Parent)
{
if (!ReferenceEquals(ancestor.Value, blueprintPropertyViewData.Value))
continue;
blueprintPropertyViewData.CustomData = "Cyclic reference";
return true;
}
return false;
}
/// <summary>
/// 是否是特殊对象
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <returns>是否是特殊对象</returns>
private static bool IsSpecialObject(BlueprintPropertyViewData blueprintPropertyViewData)
{
if (blueprintPropertyViewData.IsEnumerable)
{
AddArrayOrEnumerableChildren(blueprintPropertyViewData);
return true;
}
return false;
}
/// <summary>
/// 添加数组或者枚举类型子数据
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
private static void AddArrayOrEnumerableChildren(BlueprintPropertyViewData blueprintPropertyViewData)
{
var enumerable = (IEnumerable)blueprintPropertyViewData.Value!;
var list = enumerable as IList;
var index = 0;
foreach (var item in enumerable)
{
var type = item?.GetType() ?? GetEnumerableElementType(blueprintPropertyViewData.Type!) ?? typeof(object);
var itemIndex = index;
var child = new BlueprintPropertyViewData()
{
Type = type,
Name = $"[{itemIndex}]",
DisplayNameOverride = $"[{itemIndex}] {type.Name}",
Value = item,
Parent = blueprintPropertyViewData,
ValueChanged = blueprintPropertyViewData.ValueChanged,
ValueSetter = list is not null && !list.IsReadOnly
? targetValue => list[itemIndex] = targetValue
: null
};
SetDetail(child, item);
blueprintPropertyViewData.Children.Add(child);
index++;
}
}
private static Type? GetEnumerableElementType(Type enumerableType)
{
if (enumerableType.IsArray)
return enumerableType.GetElementType();
return enumerableType
.GetInterfaces()
.Append(enumerableType)
.FirstOrDefault(type => type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
?.GetGenericArguments()[0];
}
/// <summary>
/// 设置定义细节
/// </summary>
/// <param name="blueprintPropertyViewData">蓝图属性视图数据</param>
/// <param name="value">目标定义值</param>
public static void SetDetail(BlueprintPropertyViewData blueprintPropertyViewData, object? value)
{
if (value is MyObjectBuilder_CubeBlock myObjectBuilder_CubeBlock)
{
try
{
var cubeBlock = MyDefinitionManager.Static.GetCubeBlockDefinition(myObjectBuilder_CubeBlock);
var blockName = cubeBlock?.DisplayNameText ??
myObjectBuilder_CubeBlock.SubtypeName ??
myObjectBuilder_CubeBlock.GetType().Name;
if (blueprintPropertyViewData.Name?.StartsWith('[') == true)
blueprintPropertyViewData.DisplayNameOverride = $"{blockName} {blueprintPropertyViewData.Name}";
if (cubeBlock?.Icons is { Length: > 0 })
{
var imagePath = @$"{AppPath.DefinitionImages}\{FileHelper.ChangeExtension(cubeBlock.Icons[0], "png")}";
if (File.Exists(imagePath))
blueprintPropertyViewData.CubeImage = new BitmapImage(new Uri(imagePath));
}
}
catch
{
// Mod blocks can legitimately have no currently loaded definition or icon.
}
blueprintPropertyViewData.CustomData = value is MyObjectBuilder_TerminalBlock terminalBlock
? terminalBlock.CustomName
: myObjectBuilder_CubeBlock.SubtypeName;
}
else if (value is MyObjectBuilder_CubeGrid myObjectBuilder_CubeGrid)
{
blueprintPropertyViewData.CustomData = myObjectBuilder_CubeGrid.DisplayName;
if (blueprintPropertyViewData.Name?.StartsWith('[') == true)
blueprintPropertyViewData.DisplayNameOverride =
$"{myObjectBuilder_CubeGrid.DisplayName} {blueprintPropertyViewData.Name}";
}
else if (blueprintPropertyViewData.IsEnumerable)
{
var count = value is ICollection collection
? collection.Count
: value is null
? 0
: ((IEnumerable)value).Cast<object?>().Count();
blueprintPropertyViewData.CustomData = $"{"Amount".GetLocalized()}: {count}";
}
else
{
blueprintPropertyViewData.CustomData = blueprintPropertyViewData.IsBasicType
? blueprintPropertyViewData.ValueString
: null;
}
}
/// <summary>
/// 异步加载定义集列表
/// </summary>
/// <returns>异步任务</returns>
public static async Task LoadDefinitionViewDataListAsync()
{
await Helper.Wait(() => Initializer.IsDefinitionsLoadComplete);
foreach (var definition in AllDefinitions)
if (definition is not null && definition.Icons is not null && definition.Icons.Length > 0)
{
var originalPath = @$"{SpaceEngineersPath.SpaceEngineerContentPath}\{definition.Icons[0]}";
var targetPath = @$"{AppPath.DefinitionImages}\{FileHelper.ChangeExtension(definition.Icons[0], "png")}";
FileHelper.AutoCreateDirectory(targetPath);
if (!File.Exists(targetPath))
FileHelper.ToBitmap(originalPath, targetPath);
}
IsLoadComplete = true;
LoadComplete?.Invoke(null, EventArgs.Empty);
}
/// <summary>
/// 获取定义集
/// </summary>
/// <param name="m_hash">哈希值</param>
/// <returns>定义集</returns>
public static MyDefinitionBase? GetDefinition(int m_hash) => AllDefinitions.First(definition => definition.Id.SubtypeId.m_hash == m_hash);
/// <summary>
/// 获取游戏的根目录路径
/// </summary>
/// <returns>游戏的根目录路径</returns>
public static string? GetGameRootPath()
{
var path = GetGameRootPath(@"C:\", @"D:\", @"E:\", @"F:\", @"G:\", @"H:\", @"I:\", @"J:\", @"K:\", @"L:\", @"M:\", @"N:\", @"O:\", @"P:\", @"Q:\", @"R:\", @"S:\", @"T:\", @"U:\", @"V:\", @"W:\", @"X:\", @"Y:\", @"Z:\");
if (path is not null)
return path;
if ((Environment.Is64BitProcess ? Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 244850", false) : Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 244850", false)) is RegistryKey registryKey && registryKey.GetValue("InstallLocation")?.ToString() is string stringValue && !string.IsNullOrEmpty(stringValue))
{
return stringValue;
}
path = GetSteamFilePath();
if (!string.IsNullOrEmpty(path))
return Path.Combine(path, @"SteamApps\common\SpaceEngineers");
return null;
}
/// <summary>
/// 获取游戏的根目录路径
/// </summary>
/// <param name="roots">需要检测的磁盘索引</param>
/// <returns></returns>
public static string? GetGameRootPath(params string[] roots)
{
foreach (var root in roots)
{
var targetPath = $@"{root}SteamLibrary\steamapps\common\SpaceEngineers\Bin64\SpaceEngineers.exe";
if (File.Exists(targetPath))
return $@"{root}SteamLibrary\steamapps\common\SpaceEngineers";
}
return null;
}
/// <summary>
/// 获取Steam游戏文件的根目录
/// </summary>
/// <returns></returns>
public static string? GetSteamFilePath()
{
if ((Environment.Is64BitProcess ? Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Valve\Steam", false) : Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Valve\Steam", false)) is RegistryKey registryKey)
return registryKey.GetValue("InstallPath")?.ToString();
else
return null;
}
/// <summary>
/// 字符串逐个替换
/// </summary>
/// <param name="targetString"></param>
/// <param name="sourceArray"></param>
/// <param name="targetArray"></param>
/// <returns></returns>
public static string ForeachReplace(string targetString, string[] sourceArray, string[] targetArray)
{
int i = 0;
foreach (var sourceString in sourceArray)
{
targetString = targetString.Replace(sourceString, targetArray[i]);
i++;
}
return targetString;
}
}