添加项目文件。
This commit is contained in:
parent
4a9faaae91
commit
b3724bc752
9
App.xaml
Normal file
9
App.xaml
Normal file
@ -0,0 +1,9 @@
|
||||
<Application x:Class="WpfApp7.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:WpfApp7"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
14
App.xaml.cs
Normal file
14
App.xaml.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfApp7
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
|
||||
}
|
10
AssemblyInfo.cs
Normal file
10
AssemblyInfo.cs
Normal file
@ -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)
|
||||
)]
|
15
H5MotaUpdate.csproj
Normal file
15
H5MotaUpdate.csproj
Normal file
@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
25
H5MotaUpdate.sln
Normal file
25
H5MotaUpdate.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34330.188
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H5MotaUpdate", "H5MotaUpdate.csproj", "{47588914-BA36-4776-A2EF-268CA2F4670D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{47588914-BA36-4776-A2EF-268CA2F4670D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{47588914-BA36-4776-A2EF-268CA2F4670D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{47588914-BA36-4776-A2EF-268CA2F4670D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{47588914-BA36-4776-A2EF-268CA2F4670D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {28674D31-0DB9-4B3C-B931-D4BB89121469}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
28
MainWindow.xaml
Normal file
28
MainWindow.xaml
Normal file
@ -0,0 +1,28 @@
|
||||
<Window x:Class="H5MotaUpdate.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:H5MotaUpdate"
|
||||
xmlns:vm="clr-namespace:H5MotaUpdate.ViewModels"
|
||||
mc:Ignorable="d"
|
||||
Title="H5魔塔翻新器" Height="450" Width="800" Background="#F0F0F0">
|
||||
<Window.DataContext>
|
||||
<vm:MainViewModel></vm:MainViewModel>
|
||||
</Window.DataContext>
|
||||
<Canvas>
|
||||
<TextBlock FontSize ="16" Height="20" Canvas.Left="10" Text="旧塔文件夹" Canvas.Top="15" Width="100" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||
<TextBlock FontSize ="16" Height="20" Canvas.Left="10" Text="新样板文件夹" Canvas.Top="50" Width="100" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||
<TextBlock FontSize ="16" Height="20" Canvas.Left="10" Text="旧塔版本号" Canvas.Top="85" Width="100" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||
|
||||
<TextBlock Name ="InputFolderPath" FontSize ="14" Height="40" Canvas.Left="140" Canvas.Top="15" Width="500" TextWrapping ="Wrap" Text="{Binding SourceRootDirectory}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
<TextBlock Name ="OutputFolderPath" FontSize ="14" Height="40" Canvas.Left="140" Canvas.Top="50" Width="500" TextWrapping ="Wrap" Text="{Binding DestRootDirectory}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
<TextBlock FontSize ="16" Height="20" Canvas.Left="140" Text="{Binding VersionString}" Canvas.Top="85" Width="Auto" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
|
||||
<Button Name ="BrowseSourceFolderButton" FontSize ="16" Content="浏览" Canvas.Left="680" Canvas.Top="10" Width="40" Command="{Binding SelectSourceCommand}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
<Button x:Name ="BrowseDestFolderButton" FontSize ="16" Content="浏览" Canvas.Left="680" Canvas.Top="47" Width="40" Command="{Binding SelectDestCommand}" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||
<Button FontSize ="16" Content="开始迁移" Canvas.Left="30" Canvas.Top="127" Width="140" Command="{Binding MigrateCommand}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
|
||||
<TextBlock FontSize ="16" Canvas.Left="50" Canvas.Top="220" Width="700" TextWrapping="Wrap" Text="本工具用于辅助迁移塔的地图、元件等数据,不保证结果的正确性,请仔细手动核对结果,并注意备份原工程。
本工具不能迁移公共事件,插件和脚本,建议您手动逐个迁移。 
同理,道具,敌人,地图等地方的事件和脚本很可能无法使用,请仔细核对。 
部分事件块迁移后不能被新编辑器识别,会显示为自定义事件(如AddValue等),但不一定失效,请根据具体情况决定是否改写。
使用本工具复刻产生少量错误属于正常现象,自行修正即可,有严重bug(不能打开编辑器等)请根据控制台报错修正相应文件格式,或联系工具作者。"/>
|
||||
<CheckBox Name ="MigrateConfig" Content="迁移配置表格" Height="26" Canvas.Left="200" Canvas.Top="130" Width="100" IsChecked="{Binding MigrateServerTable}"/>
|
||||
</Canvas>
|
||||
</Window>
|
28
MainWindow.xaml.cs
Normal file
28
MainWindow.xaml.cs
Normal file
@ -0,0 +1,28 @@
|
||||
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;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using H5MotaUpdate.ViewModels;
|
||||
|
||||
namespace H5MotaUpdate
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
189
ViewModels/MainViewModel.cs
Normal file
189
ViewModels/MainViewModel.cs
Normal file
@ -0,0 +1,189 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
//silverCoin->Wand
|
||||
class MainViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private string? _sourceRootDirectory;
|
||||
private string? _destRootDirectory;
|
||||
private string? _versionString;
|
||||
private string? SourceProjectDirectory, DestProjectDirectroy;
|
||||
private bool _migrateServerTable;
|
||||
|
||||
public string? SourceRootDirectory
|
||||
{
|
||||
get { return _sourceRootDirectory; }
|
||||
set
|
||||
{
|
||||
_sourceRootDirectory = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string? DestRootDirectory
|
||||
{
|
||||
get => _destRootDirectory;
|
||||
set
|
||||
{
|
||||
_destRootDirectory = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string? VersionString
|
||||
{
|
||||
get => _versionString;
|
||||
set
|
||||
{
|
||||
_versionString = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool MigrateServerTable
|
||||
{
|
||||
get => _migrateServerTable;
|
||||
set
|
||||
{
|
||||
_migrateServerTable = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand SelectSourceCommand { get; set; }
|
||||
public ICommand SelectDestCommand { get; set; }
|
||||
public ICommand MigrateCommand { get; set; }
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
SourceRootDirectory = "请选择包含要翻新的旧塔的文件夹";
|
||||
DestRootDirectory = "请选择一个包含新的2.10.3样板的文件夹";
|
||||
VersionString = "-";
|
||||
SelectSourceCommand = new RelayCommand(SelectSourceRootFolder);
|
||||
SelectDestCommand = new RelayCommand(SelectDestRootFolder);
|
||||
MigrateCommand = new RelayCommand(StartMigrate);
|
||||
MigrateServerTable = false;
|
||||
}
|
||||
|
||||
private void SelectSourceRootFolder()
|
||||
{
|
||||
using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
|
||||
{
|
||||
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
SourceRootDirectory = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
VersionString = VersionUtils.GetVersion(SourceRootDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectDestRootFolder()
|
||||
{
|
||||
using (FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog())
|
||||
{
|
||||
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
DestRootDirectory = folderBrowserDialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查源文件夹和目标文件夹是否存在project子文件夹
|
||||
bool CheckValid()
|
||||
{
|
||||
if (!FileUtils.IsFolderPathValid(SourceRootDirectory, "源")) return false;
|
||||
if (!FileUtils.IsFolderPathValid(DestRootDirectory, "目标")) return false;
|
||||
SourceProjectDirectory = Path.Combine(SourceRootDirectory, "project");
|
||||
DestProjectDirectroy = Path.Combine(DestRootDirectory, "project");
|
||||
if (!FileUtils.IsFolderPathValid(SourceProjectDirectory, "源/project")) return false;
|
||||
if (!FileUtils.IsFolderPathValid(DestProjectDirectroy, "目标/project")) return false;
|
||||
if (!VersionUtils.IsValidVersion(VersionString))
|
||||
{
|
||||
MessageBox.Show("版本号格式不合法!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// 本按键功能:样板版本在2.7及以上,直接复制project文件夹下的animates, autotiles, bgms, fonts, images, materials, sounds, tilesets七个文件夹
|
||||
// 否则,复制animates文件夹,然后:根据data.js和icons.js等文件的注册信息,拆分sounds文件夹为sounds和bgms,拆分images文件夹
|
||||
// 在原工程未注册的素材不会复制,如有需要请手动复制
|
||||
// 需要配合“复制全塔属性”“复制素材信息”按钮完成素材的自动注册。之后请手动检查工程是否能打开,迁移结果是否正确,并进行相应调整。
|
||||
public void StartMigrate()
|
||||
{
|
||||
if (!CheckValid()) return;
|
||||
Version ver;
|
||||
Version.TryParse(VersionString, out ver);
|
||||
int width = StringUtils.ReadMapWidth(Path.Combine(SourceRootDirectory, "libs/core.js"));
|
||||
|
||||
DataJSMigrator dataJSMigrator = new(SourceProjectDirectory, DestProjectDirectroy, ver);
|
||||
EnemysJSMigrator enemysJSMigrator = new(SourceProjectDirectory, DestProjectDirectroy, ver);
|
||||
IconsJSMigrator iconsJSMigrator = new(SourceProjectDirectory, DestProjectDirectroy, ver);
|
||||
ItemsJSMigrator itemsJSMigrator = new(SourceProjectDirectory, DestProjectDirectroy, ver);
|
||||
MapsJSMigrator mapsJSMigrator = new(SourceProjectDirectory, DestProjectDirectroy, ver);
|
||||
FloorsMigrator floorsMigrator = new(SourceProjectDirectory, DestProjectDirectroy, ver, width);
|
||||
MediaSourceMigrator mediaSourceJSMigrator = new(SourceProjectDirectory, DestProjectDirectroy, ver);
|
||||
|
||||
dataJSMigrator.Migrate();
|
||||
enemysJSMigrator.Migrate();
|
||||
iconsJSMigrator.Migrate();
|
||||
itemsJSMigrator.Migrate();
|
||||
mapsJSMigrator.Migrate();
|
||||
floorsMigrator.Migrate(mapsJSMigrator.mapsIndexArray);
|
||||
mediaSourceJSMigrator.Migrate();
|
||||
|
||||
if (MigrateServerTable)
|
||||
{
|
||||
ServerTableMigrator serverTableJSMigrator = new(SourceRootDirectory, DestRootDirectory, ver);
|
||||
serverTableJSMigrator.Migrate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public class RelayCommand : ICommand
|
||||
{
|
||||
public event EventHandler? CanExecuteChanged;
|
||||
|
||||
private Action action;
|
||||
public RelayCommand(Action action)
|
||||
{
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public bool CanExecute(object? parameter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Execute(object? parameter)
|
||||
{
|
||||
action?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
331
ViewModels/Migrator/DataJSMigrator.cs
Normal file
331
ViewModels/Migrator/DataJSMigrator.cs
Normal file
@ -0,0 +1,331 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.VisualBasic.Devices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal class DataJSMigrator
|
||||
{
|
||||
string sourcePath, destPath;
|
||||
Version version;
|
||||
readonly string FILENAME = "data.js",
|
||||
DATANAME = "data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d";
|
||||
public DataJSMigrator(string oldProjectDirectory, string newProjectDirectory, Version ver)
|
||||
{
|
||||
sourcePath = System.IO.Path.Combine(oldProjectDirectory, FILENAME);
|
||||
destPath = System.IO.Path.Combine(newProjectDirectory, FILENAME);
|
||||
this.version = ver;
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 7)) >= 0)
|
||||
{
|
||||
MigrateDirect();
|
||||
}
|
||||
else
|
||||
{
|
||||
JObject jsonObject = StringUtils.getValidJson(sourcePath);
|
||||
if (version.CompareTo(new Version(2, 7)) < 0)
|
||||
{
|
||||
Convert(jsonObject);
|
||||
}
|
||||
StringBuilder newJsContent = new StringBuilder();
|
||||
newJsContent.Append("var " + DATANAME + " = ");
|
||||
newJsContent.Append(jsonObject.ToString());
|
||||
File.WriteAllText(destPath, newJsContent.ToString());
|
||||
}
|
||||
MessageBox.Show("迁移project/" + FILENAME + "文件完成。");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移project/" + FILENAME + $"过程中出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateDirect()
|
||||
{
|
||||
FileUtils.CopyFile(sourcePath, destPath, FILENAME);
|
||||
}
|
||||
|
||||
void Convert(JObject jsonObject)
|
||||
{
|
||||
|
||||
JObject mainData = (JObject)jsonObject["main"],
|
||||
firstData = (JObject)jsonObject["firstData"],
|
||||
valuesData = (JObject)jsonObject["values"],
|
||||
flagsData = (JObject)jsonObject["flags"];
|
||||
|
||||
JArray tilesetArr = (JArray)mainData["tilesets"];
|
||||
if (tilesetArr != null && tilesetArr.Count > 0) // 2.4.2(?)之前不存在main.tilesets
|
||||
{
|
||||
foreach (JToken tileset in tilesetArr)
|
||||
{
|
||||
string tilesetStr = tileset.ToString();
|
||||
if (tilesetStr.Contains('.'))
|
||||
{
|
||||
tilesetStr += ".png";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region
|
||||
// 转换难度列表levelChoose的格式
|
||||
JArray levelChooseArr = (JArray)mainData["levelChoose"];
|
||||
JArray newlevelChooseArr = new JArray();
|
||||
|
||||
if (flagsData["startDirectly"] != null && flagsData["startDirectly"].Value<bool>() == true)
|
||||
{
|
||||
// startDirectly为true时直接开始,无难度选项
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < levelChooseArr.Count; i++)
|
||||
{
|
||||
JArray level = (JArray)levelChooseArr[i];
|
||||
JObject newLevel = new JObject();
|
||||
newLevel.Add("title", level[0]);
|
||||
newLevel.Add("name", level[1]);
|
||||
newLevel.Add("hard", i);
|
||||
newLevel.Add("color", new JArray(64, 25, 85, 1));
|
||||
newLevel.Add("action", new JArray());
|
||||
newlevelChooseArr.Add(newLevel);
|
||||
}
|
||||
}
|
||||
mainData["levelChoose"] = newlevelChooseArr;
|
||||
#endregion
|
||||
|
||||
// 增加main.fonts
|
||||
mainData.Add("fonts", new JArray());
|
||||
|
||||
// 合并main.styles
|
||||
JObject newStyles = new JObject(
|
||||
new JProperty("startBackground", "project/images/bg.jpg"),
|
||||
new JProperty("startVerticalBackground", "project/images/bg.jpg"), // 竖屏标题界面背景图
|
||||
new JProperty("startLogoStyle", "color: black"),
|
||||
new JProperty("startButtonsStyle", "background-color: #32369F; opacity: 0.85; color: #FFFFFF; border: #FFFFFF 2px solid; caret-color: #FFD700;"),
|
||||
new JProperty("statusLeftBackground", "url(project/materials/ground.png) repeat"),
|
||||
new JProperty("statusTopBackground", "url(project/materials/ground.png) repeat"),
|
||||
new JProperty("toolsBackground", "url(project/materials/ground.png) repeat"),
|
||||
new JProperty("borderColor", new JArray(204, 204, 204, 1)),
|
||||
new JProperty("statusBarColor", new JArray(255, 255, 255, 1)),
|
||||
new JProperty("floorChangingStyle", "background-color: black; color: white"),
|
||||
new JProperty("font", "Verdana")
|
||||
);
|
||||
string[] styleKeys = ["startLogoStyle", "startButtonsStyle", "statusLeftBackground", "statusTopBackground", "toolsBackground", "font"];
|
||||
foreach (string key in styleKeys)
|
||||
{
|
||||
if (mainData.ContainsKey(key))
|
||||
{
|
||||
newStyles[key] = mainData[key];
|
||||
}
|
||||
}
|
||||
foreach (JProperty prop in newStyles.Properties())
|
||||
{
|
||||
string key = prop.Name;
|
||||
if (mainData.ContainsKey(key))
|
||||
{
|
||||
mainData.Remove(key);
|
||||
}
|
||||
}
|
||||
mainData["styles"] = newStyles;
|
||||
|
||||
mainData.Remove("floorChangingBackground");
|
||||
mainData.Remove("floorChangingTextColor");
|
||||
|
||||
JArray imageArr = (JArray)mainData["images"];
|
||||
if (!imageArr.Contains("hero.png")) imageArr.Add("hero.png"); //?
|
||||
|
||||
JObject heroData = (JObject)firstData["hero"],
|
||||
heroItemData = (JObject)heroData["items"];
|
||||
heroData["image"] = "hero.png";
|
||||
heroData["followers"] = new JArray();
|
||||
if (heroData["exp"] == null) heroData["exp"] = heroData["experience"];
|
||||
heroData.Remove("experience");
|
||||
|
||||
JObject heroToolsData = (JObject)heroItemData["tools"];
|
||||
JObject heroKeysData = (JObject)heroItemData["keys"];
|
||||
if (heroKeysData != null)
|
||||
{
|
||||
if (heroToolsData == null)
|
||||
{
|
||||
heroToolsData = new JObject();
|
||||
}
|
||||
StringUtils.MergeJObjects(heroToolsData, heroKeysData);
|
||||
}
|
||||
heroItemData.Remove("keys");
|
||||
|
||||
|
||||
#region
|
||||
// 转换全局商店shop的格式
|
||||
JArray shopArr = (JArray)firstData["shops"];
|
||||
for (int i = 0; i < shopArr.Count; i++)
|
||||
{
|
||||
JObject shop = (JObject)shopArr[i];
|
||||
|
||||
if (shop["item"] != null && shop["item"].Value<bool>() == true) // 道具商店
|
||||
{
|
||||
shop["use"] = "money";
|
||||
}
|
||||
else if (shop.ContainsKey("commonEvent")) // 公共事件商店
|
||||
{
|
||||
|
||||
}
|
||||
else //普通商店
|
||||
{
|
||||
JArray choiceArr = (JArray)shop["choices"];
|
||||
string use = shop["use"].ToString(),
|
||||
shopNeed = shop["need"].ToString(),
|
||||
shopText = shop["text"].ToString(),
|
||||
shopId = shop["id"].ToString(),
|
||||
flagName_Time = "flag:" + shopId + "_times", // 新设的购买次数变量flag:xxx
|
||||
flagName_Price = "flag:" + shopId + "_price"; // 新设的价格变量flag:xxx
|
||||
string priceStr = shopNeed.Replace("times", flagName_Time); //用新变量名取代times之后的商店价格字符串
|
||||
shop["text"] = StringUtils.ReplaceInBetweenCurlyBraces(shopText, "times", flagName_Time);
|
||||
shop["text"] = StringUtils.ReplaceInBetweenCurlyBraces(shopText, "need", flagName_Price);
|
||||
shop["disablePreview"] = false;
|
||||
|
||||
if (use == "experience")
|
||||
{
|
||||
use = "exp";
|
||||
}
|
||||
|
||||
for (int j = 0; j < choiceArr.Count; j++)
|
||||
{
|
||||
JObject choice = (JObject)choiceArr[j];
|
||||
string requirement;
|
||||
string? choiceNeed = null;
|
||||
if (choice.ContainsKey("need"))
|
||||
{
|
||||
choiceNeed = choice["need"].ToString().Replace("times", flagName_Time);
|
||||
requirement = "status:" + use + ">=" + choiceNeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
requirement = "status:" + use + ">=" + priceStr;
|
||||
}
|
||||
choice["need"] = requirement; // 单个选项的使用条件
|
||||
|
||||
JArray newAction = new JArray();
|
||||
JObject setPrice = StringUtils.getAddValueJson(flagName_Price, choiceNeed != null ? choiceNeed : priceStr, "="),
|
||||
deductMoney = StringUtils.getAddValueJson("status:" + use, flagName_Price, "-="),
|
||||
addTime = StringUtils.getAddValueJson(flagName_Time, "1", "+=");
|
||||
newAction.Add(setPrice);
|
||||
newAction.Add(deductMoney);
|
||||
newAction.Add(addTime);
|
||||
|
||||
string oldEffect = choice["effect"].ToString();
|
||||
var newEffectJArray = StringUtils.doEffect(oldEffect);
|
||||
newAction.Merge(newEffectJArray);
|
||||
choice["action"] = newAction; //单个选项使用时执行的事件
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
if (valuesData["statusCanvasRowsOnMobile"] == null)
|
||||
{
|
||||
valuesData["statusCanvasRowsOnMobile"] = flagsData["statusCanvasRowsOnMobile"];
|
||||
}
|
||||
flagsData.Remove("statusCanvasRowsOnMobile");
|
||||
|
||||
if (valuesData["redGem"] == null)
|
||||
{
|
||||
valuesData["redGem"] = valuesData["redJewel"];
|
||||
}
|
||||
valuesData.Remove("redJewel");
|
||||
|
||||
if (valuesData["blueGem"] == null)
|
||||
{
|
||||
valuesData["blueGem"] = valuesData["blueJewel"];
|
||||
}
|
||||
valuesData.Remove("blueJewel");
|
||||
|
||||
if (valuesData["greenGem"] == null)
|
||||
{
|
||||
valuesData["greenGem"] = valuesData["greenJewel"];
|
||||
}
|
||||
valuesData.Remove("greenJewel");
|
||||
|
||||
valuesData.Remove("moveSpeed");
|
||||
valuesData.Remove("floorChangeTime");
|
||||
|
||||
string[] statusList = [
|
||||
"enableHP",
|
||||
"enableAtk",
|
||||
"enableDef",
|
||||
"enableFloor",
|
||||
"enableName",
|
||||
"enableLv",
|
||||
"enableHPMax",
|
||||
"enableMana",
|
||||
"enableMDef",
|
||||
"enableMoney",
|
||||
"enableExp",
|
||||
"enableLevelUp",
|
||||
"levelUpLeftMode",
|
||||
"enableKeys",
|
||||
"enableGreenKey",
|
||||
"enablePZF",
|
||||
"enableDebuff",
|
||||
"enableSkill",
|
||||
];
|
||||
|
||||
if (flagsData["statusBarItems"] == null)
|
||||
{
|
||||
JArray statusBarItemsArr = new JArray();
|
||||
foreach (string status in statusList)
|
||||
{
|
||||
if (flagsData.ContainsKey(status) && flagsData[status].Value<bool>() == true)
|
||||
{
|
||||
statusBarItemsArr.Add(status);
|
||||
}
|
||||
else if (new string[] { "enableHP", "enableAtk", "enableDef" }.Contains(status)) // hp,atk,def为2.7前默认显示的变量,必须显示
|
||||
|
||||
{
|
||||
statusBarItemsArr.Add(status);
|
||||
}
|
||||
else if (status == "enableExp" && flagsData["enableExperience"].Value<bool>() == true) // experience更新为exp
|
||||
{
|
||||
statusBarItemsArr.Add(status);
|
||||
}
|
||||
}
|
||||
flagsData["statusBarItems"] = statusBarItemsArr;
|
||||
}
|
||||
foreach (string status in statusList)
|
||||
{
|
||||
flagsData.Remove(status);
|
||||
}
|
||||
flagsData.Remove("pickaxeFourDirections");
|
||||
flagsData.Remove("bombFourDirections");
|
||||
flagsData.Remove("snowFourDirections");
|
||||
flagsData.Remove("bigKeyIsBox");
|
||||
flagsData.Remove("equipment");
|
||||
flagsData.Remove("iconInEquipbox");
|
||||
flagsData.Remove("hatredDecrease");
|
||||
flagsData.Remove("betweenAttackCeil");
|
||||
flagsData.Remove("startDirectly");
|
||||
flagsData.Remove("enableDisabledShop");
|
||||
flagsData.Remove("checkConsole");
|
||||
}
|
||||
}
|
||||
}
|
216
ViewModels/Migrator/EnemysJSMigrator.cs
Normal file
216
ViewModels/Migrator/EnemysJSMigrator.cs
Normal file
@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
||||
// 功能:复制project/enemy.js文件
|
||||
// 样板版本在2.9以下 按照如下逻辑改写相关数据:敌人具有光环属性:enemy.haloRange = enemy.range;同时若不具有领域enemy.range=null
|
||||
// 敌人具有光环属性:enemy.haloSquare = enemy.zoneSquare;同时若不具有领域enemy.zoneSquare=null
|
||||
// 敌人具有光环属性:enemy.haloAdd = enemy.Add;同时若不具有吸血enemy.add=null
|
||||
// 敌人具有反击属性: enemy.counterAttack = enemy.atkValue;同时若不具有退化 enemy.atkValue = null
|
||||
// 敌人具有破甲属性: enemy.breakArmor = enemy.defValue;同时若不具有退化 enemy.defValue = null
|
||||
// 敌人具有领域、阻击、激光属性 分别令enemy.zone/repulse/laser
|
||||
// enemy.value = null
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal class EnemysJSMigrator
|
||||
{
|
||||
string sourcePath, destPath;
|
||||
Version version;
|
||||
readonly string FILENAME = "enemys.js",
|
||||
DATANAME = "enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80";
|
||||
|
||||
/// <summary>
|
||||
/// 请输入新旧Project文件夹的路径
|
||||
/// </summary>
|
||||
public EnemysJSMigrator(string oldProjectDirectory, string newProjectDirectory, Version ver)
|
||||
{
|
||||
sourcePath = System.IO.Path.Combine(oldProjectDirectory, FILENAME);
|
||||
destPath = System.IO.Path.Combine(newProjectDirectory, FILENAME);
|
||||
version = ver;
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 9)) >= 0)
|
||||
{
|
||||
MigrateDirect();
|
||||
}
|
||||
else
|
||||
{
|
||||
JObject jsonObject = StringUtils.getValidJson(sourcePath);
|
||||
Convert(jsonObject);
|
||||
StringBuilder newJsContent = new StringBuilder();
|
||||
newJsContent.Append("var " + DATANAME + " = ");
|
||||
newJsContent.Append(jsonObject.ToString());
|
||||
File.WriteAllText(destPath, newJsContent.ToString());
|
||||
}
|
||||
MessageBox.Show("迁移project/" + FILENAME + "文件完成");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移project/" + FILENAME + $"过程中出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateDirect()
|
||||
{
|
||||
FileUtils.CopyFile(sourcePath, destPath, FILENAME);
|
||||
}
|
||||
|
||||
void Convert(JObject jsonObject)
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 7)) < 0)
|
||||
{
|
||||
Convert_before2_7(jsonObject);
|
||||
}
|
||||
Convert_before2_9(jsonObject);
|
||||
}
|
||||
|
||||
static void Convert_before2_9(JObject jsonObject)
|
||||
{
|
||||
foreach (JProperty prop in jsonObject.Properties())
|
||||
{
|
||||
|
||||
JObject enemyData = (JObject)prop.Value;
|
||||
JToken enemySpecial = enemyData["special"];
|
||||
if (enemySpecial is JValue specialValue)
|
||||
{
|
||||
transferSpecialValue(specialValue, enemyData);
|
||||
}
|
||||
else if (enemySpecial is JArray specialValueArr)
|
||||
{
|
||||
transferSpecialArr(specialValueArr, enemyData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Convert_before2_7(JObject jsonObject)
|
||||
{
|
||||
foreach (JProperty prop in jsonObject.Properties())
|
||||
{
|
||||
|
||||
JObject enemyData = (JObject)prop.Value;
|
||||
JValue enemyExperience = (JValue)enemyData["experience"];
|
||||
if (enemyExperience != null)
|
||||
{
|
||||
enemyData["exp"] = enemyExperience;
|
||||
}
|
||||
enemyData.Remove("experience");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据单个特殊属性的JValue改写敌人数据
|
||||
/// </summary>
|
||||
static void transferSpecialValue(JValue specialValue, JObject enemy)
|
||||
{
|
||||
if (specialValue.Type == JTokenType.Integer)
|
||||
{
|
||||
switch ((int)specialValue)
|
||||
{
|
||||
case 7: //破甲
|
||||
enemy["counterAttack"] = enemy["atkValue"];
|
||||
enemy.Remove("atkValue");
|
||||
break;
|
||||
case 8: //反击
|
||||
enemy["breakArmor"] = enemy["defValue"];
|
||||
enemy.Remove("defValue");
|
||||
break;
|
||||
case 15://领域
|
||||
enemy["zone"] = enemy["value"];
|
||||
enemy.Remove("value");
|
||||
break;
|
||||
case 18://阻击
|
||||
enemy["repulse"] = enemy["value"];
|
||||
enemy.Remove("value");
|
||||
break;
|
||||
case 24://激光
|
||||
enemy["laser"] = enemy["value"];
|
||||
enemy.Remove("value");
|
||||
break;
|
||||
case 25: //光环
|
||||
enemy["haloRange"] = enemy["range"];
|
||||
enemy["haloSquare"] = enemy["zoneSquare"];
|
||||
enemy["haloAdd"] = enemy["add"];
|
||||
enemy.Remove("range");
|
||||
enemy.Remove("zoneSquare");
|
||||
enemy.Remove("add");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据特殊属性列表JArray改写敌人数据
|
||||
/// </summary>
|
||||
static void transferSpecialArr(JArray specialValueArr, JObject enemy)
|
||||
{
|
||||
HashSet<int> specialValuesToCheck = new HashSet<int> { 7, 8, 15, 18, 24, 25 };
|
||||
HashSet<int> foundSpecialValues = new HashSet<int>();
|
||||
|
||||
foreach (JToken item in specialValueArr)
|
||||
{
|
||||
if (item.Type == JTokenType.Integer && specialValuesToCheck.Contains((int)item))
|
||||
{
|
||||
foundSpecialValues.Add((int)item);
|
||||
}
|
||||
}
|
||||
|
||||
if (foundSpecialValues.Contains(7))
|
||||
{
|
||||
enemy["counterAttack"] = enemy["atkValue"];
|
||||
if (!foundSpecialValues.Contains(21)) enemy.Remove("atkValue");
|
||||
}
|
||||
if (foundSpecialValues.Contains(8))
|
||||
{
|
||||
enemy["breakArmor"] = enemy["defValue"];
|
||||
if (!foundSpecialValues.Contains(21)) enemy.Remove("defValue");
|
||||
}
|
||||
if (foundSpecialValues.Contains(15))
|
||||
{
|
||||
enemy["zone"] = enemy["value"];
|
||||
enemy.Remove("value");
|
||||
}
|
||||
if (foundSpecialValues.Contains(18))
|
||||
{
|
||||
enemy["repulse"] = enemy["value"];
|
||||
enemy.Remove("value");
|
||||
}
|
||||
if (foundSpecialValues.Contains(24))
|
||||
{
|
||||
enemy["laser"] = enemy["value"];
|
||||
enemy.Remove("value");
|
||||
}
|
||||
if (foundSpecialValues.Contains(25))
|
||||
{
|
||||
enemy["haloRange"] = enemy["range"];
|
||||
enemy["haloSquare"] = enemy["zoneSquare"];
|
||||
enemy["haloAdd"] = enemy["add"];
|
||||
if (!foundSpecialValues.Contains(11)) enemy.Remove("add");
|
||||
if (!foundSpecialValues.Contains(15))
|
||||
{
|
||||
enemy.Remove("range");
|
||||
enemy.Remove("zoneSquare");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
170
ViewModels/Migrator/FloorsMigrator.cs
Normal file
170
ViewModels/Migrator/FloorsMigrator.cs
Normal file
@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices.JavaScript;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal class FloorsMigrator
|
||||
{
|
||||
string sourcePath, destPath;
|
||||
Version version;
|
||||
readonly string FILENAME = "floors";
|
||||
string?[] mapsIndexArray;
|
||||
int mapWidth = 13;
|
||||
|
||||
/// <summary>
|
||||
/// 请输入新旧Project文件夹的路径
|
||||
/// </summary>
|
||||
public FloorsMigrator(string oldProjectDirectory, string newProjectDirectory, Version ver, int width)
|
||||
{
|
||||
sourcePath = System.IO.Path.Combine(oldProjectDirectory, FILENAME);
|
||||
destPath = System.IO.Path.Combine(newProjectDirectory, FILENAME);
|
||||
this.version = ver;
|
||||
this.mapWidth = width;
|
||||
}
|
||||
|
||||
public void Migrate(string?[] mapsIndexArray)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 7)) >= 0)
|
||||
{
|
||||
MigrateDirect();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.mapsIndexArray = mapsIndexArray;
|
||||
MigrateFloors();
|
||||
}
|
||||
MessageBox.Show("迁移project/" + FILENAME + "文件夹完成。");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移project/" + FILENAME + $"文件夹过程中出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateDirect()
|
||||
{
|
||||
FileUtils.CopyFolderContents(sourcePath, destPath);
|
||||
}
|
||||
|
||||
void MigrateFloors()
|
||||
{
|
||||
string[] files = Directory.GetFiles(sourcePath);
|
||||
foreach (string file in files)
|
||||
{
|
||||
string sourceFilePath = System.IO.Path.Combine(sourcePath, System.IO.Path.GetFileName(file)),
|
||||
destFilePath = System.IO.Path.Combine(destPath, System.IO.Path.GetFileName(file));
|
||||
MigrateOneFloor(sourceFilePath, destFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateOneFloor(string sourceFilePath, string destFilePath)
|
||||
{
|
||||
// 每一层try catch一次,一层出错不影响其它层继续复制
|
||||
try
|
||||
{
|
||||
string floorName = System.IO.Path.GetFileNameWithoutExtension(sourceFilePath);
|
||||
JObject jsonObject = StringUtils.getValidJson(sourceFilePath);
|
||||
if (version.CompareTo(new Version(2, 7)) <= 0)
|
||||
{
|
||||
Convert(jsonObject);
|
||||
}
|
||||
StringBuilder newJsContent = new StringBuilder();
|
||||
newJsContent.Append("main.floors." + floorName + " = ");
|
||||
newJsContent.Append(jsonObject.ToString());
|
||||
File.WriteAllText(destFilePath, newJsContent.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移楼层文件" + System.IO.Path.GetFileName(sourceFilePath) + $"时出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void Convert(JObject jsonObject)
|
||||
{
|
||||
jsonObject["canFlyFrom"] = jsonObject["canFlyTo"];
|
||||
jsonObject["ratio"] = jsonObject["item_ratio"];
|
||||
jsonObject.Remove("item_ratio");
|
||||
jsonObject["width"] = mapWidth;
|
||||
jsonObject["height"] = mapWidth;
|
||||
jsonObject["autoEvent"] = new JObject();
|
||||
|
||||
#region
|
||||
// 楼层贴图:老版本为一字符串或数组,字符串会被自动转为[0,0,str]
|
||||
// 其中t[0],t[1]分别为x,y,t[2]为贴图名字 剩下的不知道干嘛的
|
||||
JToken oldImages = jsonObject["images"];
|
||||
string imageName = null;
|
||||
if (oldImages is JArray oldImagesArr)
|
||||
{
|
||||
if (oldImagesArr.Count >= 3)
|
||||
{
|
||||
imageName = oldImagesArr[2].ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
imageName = oldImages.ToString();
|
||||
}
|
||||
if (imageName == null)
|
||||
{
|
||||
jsonObject["images"] = new JArray();
|
||||
}
|
||||
JObject newImages = new JObject(new JProperty("name", imageName),
|
||||
new JProperty("canvas", "bg"),
|
||||
new JProperty("sx", 0),
|
||||
new JProperty("sy", 0),
|
||||
new JProperty("w", 416),
|
||||
new JProperty("h", 416)
|
||||
);
|
||||
jsonObject["images"] = new JArray(newImages);
|
||||
#endregion
|
||||
|
||||
#region
|
||||
JArray mapMatrix = (JArray)jsonObject["map"];
|
||||
JArray zeroBgMatrix = StringUtils.CreateMatrix(mapWidth, mapWidth);
|
||||
for (int i = 0; i < mapMatrix.Count; i++)
|
||||
{
|
||||
JArray lineArr = (JArray)mapMatrix[i];
|
||||
for (int j = 0; j < lineArr.Count; j++)
|
||||
{
|
||||
int onePoint = lineArr[j].Value<int>();
|
||||
if (onePoint >= 81 && onePoint <= 86 && mapsIndexArray != null)
|
||||
{ // 将terrains门替换为animates门
|
||||
lineArr[j] = mapsIndexArray[onePoint - 81];
|
||||
}
|
||||
if (onePoint == 167 && version.CompareTo(new Version(2, 6)) < 0)
|
||||
{
|
||||
// 2.6以后,滑冰转移到背景层
|
||||
JArray bgMatrix = (JArray)jsonObject["bgmap"].DeepClone();
|
||||
if (bgMatrix == null || bgMatrix.Count == 0)
|
||||
{
|
||||
jsonObject["bgmap"] = zeroBgMatrix.DeepClone();
|
||||
}
|
||||
jsonObject["bgmap"][i][j] = 167;
|
||||
mapMatrix[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
117
ViewModels/Migrator/IconsJSMigrator.cs
Normal file
117
ViewModels/Migrator/IconsJSMigrator.cs
Normal file
@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal class IconsJSMigrator
|
||||
{
|
||||
string sourcePath, destPath;
|
||||
Version version;
|
||||
readonly string FILENAME = "icons.js",
|
||||
DATANAME = "icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1";
|
||||
|
||||
/// <summary>
|
||||
/// 请输入新旧Project文件夹的路径
|
||||
/// </summary>
|
||||
public IconsJSMigrator(string oldProjectDirectory, string newProjectDirectory, Version ver)
|
||||
{
|
||||
sourcePath = System.IO.Path.Combine(oldProjectDirectory, FILENAME);
|
||||
destPath = System.IO.Path.Combine(newProjectDirectory, FILENAME);
|
||||
version = ver;
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 7)) >= 0)
|
||||
{
|
||||
MigrateDirect();
|
||||
}
|
||||
else
|
||||
{
|
||||
JObject jsonObject = StringUtils.getValidJson(sourcePath);
|
||||
if (version.CompareTo(new Version(2, 7)) < 0)
|
||||
{
|
||||
ConvertIconsJS_before2_7(jsonObject);
|
||||
}
|
||||
StringBuilder newJsContent = new StringBuilder();
|
||||
newJsContent.Append("var " + DATANAME + " = ");
|
||||
newJsContent.Append(jsonObject.ToString());
|
||||
File.WriteAllText(destPath, newJsContent.ToString());
|
||||
}
|
||||
MessageBox.Show("迁移project/" + FILENAME + "文件完成");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移project/" + FILENAME + $"过程中出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateDirect()
|
||||
{
|
||||
|
||||
FileUtils.CopyFile(sourcePath, destPath, FILENAME);
|
||||
}
|
||||
|
||||
void ConvertIconsJS_before2_7(JObject jsonObject)
|
||||
{
|
||||
// 暂时将错就错沿用旧名字,有问题再说
|
||||
/*
|
||||
JObject terrains = (JObject)jsonObject["terrains"];
|
||||
terrains.Remove("yellowWall");
|
||||
terrains.Remove("blueWall");
|
||||
terrains.Remove("whiteWall");
|
||||
terrains.Remove("yellowDoor");
|
||||
terrains.Remove("blueDoor");
|
||||
terrains.Remove("redDoor");
|
||||
terrains.Remove("greenDoor");
|
||||
terrains.Remove("specialDoor");
|
||||
terrains.Remove("steelDoor");
|
||||
|
||||
if (terrains["blueShopLeft"] == null)
|
||||
{
|
||||
terrains["blueShopLeft"] = terrains["blueShop-left"];
|
||||
}
|
||||
terrains.Remove("blueShop-right");
|
||||
if (terrains["blueShopRight"] == null)
|
||||
{
|
||||
terrains["blueShopRight"] = terrains["blueShop-right"];
|
||||
}
|
||||
terrains.Remove("blueShop-right");
|
||||
if (terrains["pinkShopLeft"] == null)
|
||||
{
|
||||
terrains["pinkShopLeft"] = terrains["pinkShop-left"];
|
||||
}
|
||||
terrains.Remove("pinkShop-left");
|
||||
if (terrains["pinkShopRight"] == null)
|
||||
{
|
||||
terrains["pinkShopRight"] = terrains["pinkShop-right"];
|
||||
}
|
||||
terrains.Remove("pinkShop-left");
|
||||
JObject items = (JObject)jsonObject["items"];
|
||||
if (items["snow"] != null)
|
||||
{
|
||||
items["freezeBadge"] = items["snow"];
|
||||
}
|
||||
items.Remove("snow");
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
117
ViewModels/Migrator/ItemsJSMigrator.cs
Normal file
117
ViewModels/Migrator/ItemsJSMigrator.cs
Normal file
@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal class ItemsJSMigrator
|
||||
{
|
||||
string sourcePath, destPath;
|
||||
Version version;
|
||||
readonly string FILENAME = "items.js",
|
||||
DATANAME = "items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a";
|
||||
|
||||
/// <summary>
|
||||
/// 请输入新旧Project文件夹的路径
|
||||
/// </summary>
|
||||
public ItemsJSMigrator(string oldProjectDirectory, string newProjectDirectory, Version ver)
|
||||
{
|
||||
sourcePath = System.IO.Path.Combine(oldProjectDirectory, FILENAME);
|
||||
destPath = System.IO.Path.Combine(newProjectDirectory, FILENAME);
|
||||
this.version = ver;
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 7)) >= 0)
|
||||
{
|
||||
MigrateDirect();
|
||||
}
|
||||
else
|
||||
{
|
||||
JObject jsonObject = StringUtils.getValidJson(sourcePath);
|
||||
if (version.CompareTo(new Version(2, 7)) < 0)
|
||||
{
|
||||
Convert(ref jsonObject);
|
||||
}
|
||||
StringBuilder newJsContent = new StringBuilder();
|
||||
newJsContent.Append("var " + DATANAME + " = ");
|
||||
newJsContent.Append(jsonObject.ToString());
|
||||
File.WriteAllText(destPath, newJsContent.ToString());
|
||||
}
|
||||
MessageBox.Show("迁移project/" + FILENAME + "文件完成。");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移project/" + FILENAME + $"过程中出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateDirect()
|
||||
{
|
||||
FileUtils.CopyFile(sourcePath, destPath, FILENAME);
|
||||
}
|
||||
|
||||
void Convert(ref JObject jsonObject)
|
||||
{
|
||||
//2.7之前items.js有items,itemEffect, itemEffectTip, useItemEvent, useItemEffect, canUseItemEffect, equipCondition七个键
|
||||
//新建一个items对象,迁移其他对象中的内容
|
||||
JObject newItemDatas = (JObject)jsonObject["items"],
|
||||
itemEffect = (JObject)jsonObject["itemEffect"],
|
||||
itemEffectTip = (JObject)jsonObject["itemEffectTip"],
|
||||
useItemEvent = (JObject)jsonObject["useItemEvent"],
|
||||
useItemEffect = (JObject)jsonObject[" useItemEffect"],
|
||||
canUseItemEffect = (JObject)jsonObject["canUseItemEffect"],
|
||||
equipCondition = (JObject)jsonObject["equipCondition"];
|
||||
string[] arr = ["itemEffect", "itemEffectTip", "useItemEvent", "useItemEffect", "canUseItemEffect", "equipCondition"];
|
||||
foreach (string ele in arr)
|
||||
{
|
||||
JObject eleData = (JObject)jsonObject[ele];
|
||||
if (eleData == null || eleData.Count == 0) { continue; }
|
||||
foreach (JProperty prop in eleData.Properties())
|
||||
{
|
||||
string key = prop.Name,
|
||||
valueString = prop.Value.ToString();
|
||||
valueString = StringUtils.ReplaceOldNames(valueString, version); //危险操作
|
||||
if (newItemDatas.ContainsKey(key))
|
||||
{
|
||||
JObject itemData = (JObject)newItemDatas[key];
|
||||
itemData[ele] = valueString;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (JProperty prop in newItemDatas.Properties())
|
||||
{
|
||||
string key = prop.Name;
|
||||
JObject perData = (JObject)prop.Value;
|
||||
if (perData["cls"].ToString() == "keys")
|
||||
{
|
||||
perData["cls"] = "tools";
|
||||
perData["hideInToolbox"] = true;
|
||||
}
|
||||
}
|
||||
if (newItemDatas.ContainsKey("snow"))
|
||||
{
|
||||
newItemDatas["freezeBadge"] = newItemDatas["snow"];
|
||||
newItemDatas.Remove("snow");
|
||||
}
|
||||
jsonObject = newItemDatas; //直接赋值操作需要加ref
|
||||
}
|
||||
}
|
||||
}
|
188
ViewModels/Migrator/MapsJSMigrator.cs
Normal file
188
ViewModels/Migrator/MapsJSMigrator.cs
Normal file
@ -0,0 +1,188 @@
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal class MapsJSMigrator
|
||||
{
|
||||
string sourcePath, destPath;
|
||||
Version version;
|
||||
readonly string FILENAME = "maps.js",
|
||||
DATANAME = "maps_90f36752_8815_4be8_b32b_d7fad1d0542e";
|
||||
public string?[] mapsIndexArray;
|
||||
|
||||
/// <summary>
|
||||
/// 请输入新旧Project文件夹的路径
|
||||
/// </summary>
|
||||
public MapsJSMigrator(string oldProjectDirectory, string newProjectDirectory, Version ver)
|
||||
{
|
||||
sourcePath = System.IO.Path.Combine(oldProjectDirectory, FILENAME);
|
||||
destPath = System.IO.Path.Combine(newProjectDirectory, FILENAME);
|
||||
this.version = ver;
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 7)) >= 0)
|
||||
{
|
||||
MigrateDirect();
|
||||
}
|
||||
else
|
||||
{
|
||||
JObject jsonObject = StringUtils.getValidJson(sourcePath);
|
||||
if (version.CompareTo(new Version(2, 7)) < 0)
|
||||
{
|
||||
Convert_before2_7(jsonObject);
|
||||
}
|
||||
StringBuilder newJsContent = new StringBuilder();
|
||||
newJsContent.Append("var " + DATANAME + " = ");
|
||||
newJsContent.Append(jsonObject.ToString());
|
||||
File.WriteAllText(destPath, newJsContent.ToString());
|
||||
}
|
||||
MessageBox.Show("迁移project/" + FILENAME + "文件完成。");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移project/" + FILENAME + $"过程中出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateDirect()
|
||||
{
|
||||
FileUtils.CopyFile(sourcePath, destPath, FILENAME);
|
||||
}
|
||||
|
||||
void Convert_before2_7(JObject jsonObject)
|
||||
{
|
||||
// 下面列出一些样板图块名字的更改,以备后续需求。为适配旧有事件和脚本,暂时沿用原来的名字。
|
||||
// blueShop-left -> blueShopLeft,
|
||||
// blueShop-right -> blueShopRight,
|
||||
// pinkShop-left -> pinkShopLeft
|
||||
// pinkShop-right -> pinkShopRight
|
||||
// snow -> freezeBadge
|
||||
Dictionary<string, JObject> dictionary = new Dictionary<string, JObject>{
|
||||
{ "blueShop-left", new JObject { { "cls", "terrains" } } },
|
||||
{ "blueShop-right", new JObject { { "cls", "terrains" } } },
|
||||
{ "pinkShop-left", new JObject { { "cls", "terrains" } } },
|
||||
{ "pinkShop-right", new JObject { { "cls", "terrains" } } },
|
||||
{ "lavaNet", new JObject { { "cls", "animates" }, { "canPass", true }, { "trigger", "null" }, { "script", "(function () {\n\t// 血网的伤害效果移动到 checkBlock 中处理\n\n\t// 如果要做一次性血网,可直接注释掉下面这句话:\n\t// core.removeBlock(core.getHeroLoc('x'), core.getHeroLoc('y'));\n})();" }, { "name", "血网" } } },
|
||||
{ "poisonNet", new JObject { { "cls", "animates" }, { "canPass", true }, { "trigger", "null" }, { "script", "(function () {\n\t// 直接插入公共事件进行毒处理\n\tif (!core.hasItem('amulet')) {\n\t\tcore.insertAction({ \"type\": \"insert\", \"name\": \"毒衰咒处理\", \"args\": [0] });\n\t}\n\n\t// 如果要做一次性毒网,可直接注释掉下面这句话:\n\t// core.removeBlock(core.getHeroLoc('x'), core.getHeroLoc('y'));\n})()" }, { "name", "毒网" } } },
|
||||
{ "weakNet", new JObject { { "cls", "animates" }, { "canPass", true }, { "trigger", "null" }, { "script", "(function () {\n\t// 直接插入公共事件进行衰处理\n\tif (!core.hasItem('amulet')) {\n\t\tcore.insertAction({ \"type\": \"insert\", \"name\": \"毒衰咒处理\", \"args\": [1] });\n\t}\n\n\t// 如果要做一次性衰网,可直接注释掉下面这句话:\n\t// core.removeBlock(core.getHeroLoc('x'), core.getHeroLoc('y'));\n})()" }, { "name", "衰网" } } },
|
||||
{ "curseNet", new JObject { { "cls", "animates" }, { "canPass", true }, { "trigger", "null" }, { "script", "(function () {\n\t// 直接插入公共事件进行咒处理\n\tif (!core.hasItem('amulet')) {\n\t\tcore.insertAction({ \"type\": \"insert\", \"name\": \"毒衰咒处理\", \"args\": [2] });\n\t}\n\n\t// 如果要做一次性咒网,可直接注释掉下面这句话:\n\t// core.removeBlock(core.getHeroLoc('x'), core.getHeroLoc('y'));\n})()" }, { "name", "咒网" } } },
|
||||
{ "snow", new JObject { { "cls", "items" } } },
|
||||
{ "arrowUp", new JObject { { "cls", "terrains" }, { "canPass", true }, { "cannotOut", new JArray { "left", "right", "down" } }, { "cannotIn", new JArray { "up" } } } },
|
||||
{ "arrowDown", new JObject { { "cls", "terrains" }, { "canPass", true }, { "cannotOut", new JArray { "left", "right", "up" } }, { "cannotIn", new JArray { "down" } } } },
|
||||
{ "arrowLeft", new JObject { { "cls", "terrains" }, { "canPass", true }, { "cannotOut", new JArray { "up", "down", "right" } }, { "cannotIn", new JArray { "left" } } } },
|
||||
{ "arrowRight", new JObject { { "cls", "terrains" }, { "canPass", true }, { "cannotOut", new JArray { "up", "down", "left" } }, { "cannotIn", new JArray { "right" } } } },
|
||||
{ "light", new JObject { { "cls", "terrains" }, { "trigger", "null" }, { "canPass", true }, { "script", "(function () {\n\tcore.setBlock(core.getNumberById('darkLight'), core.getHeroLoc('x'), core.getHeroLoc('y'));\n})();" } } },
|
||||
};
|
||||
|
||||
// 原先不存在的新图块信息
|
||||
Dictionary<string, JObject> newIconsDictionary = new Dictionary<string, JObject> {
|
||||
{ "yellowDoor", new JObject { { "cls", "animates" }, { "trigger", "openDoor" }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject { { "yellowKey", 1 } } } } }, { "name", "黄门" } } },
|
||||
{ "blueDoor", new JObject { { "cls", "animates" }, { "trigger", "openDoor" }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject { { "blueKey", 1 } } } } }, { "name", "蓝门" } } },
|
||||
{ "redDoor", new JObject { { "cls", "animates" }, { "trigger", "openDoor" }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject { { "redKey", 1 } } } } }, { "name", "红门" } } },
|
||||
{ "greenDoor", new JObject { { "cls", "animates" }, { "trigger", "openDoor" }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject { { "greenKey", 1 } } } } }, { "name", "绿门" } } },
|
||||
{ "specialDoor", new JObject { { "cls", "animates" }, { "trigger", "openDoor" }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject { { "specialKey", 1 } } } } }, { "name", "机关门" } } },
|
||||
{ "steelDoor", new JObject { { "cls", "animates" }, { "trigger", "openDoor" }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject { { "steelKey", 1 } } } } }, { "name", "铁门" } } },
|
||||
{ "yellowWallDoor", new JObject { { "cls", "animates" }, { "canBreak", true }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject() } } } } },
|
||||
{ "whiteWallDoor", new JObject { { "cls", "animates" }, { "canBreak", true }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject() } } } } },
|
||||
{ "blueWallDoor", new JObject { { "cls", "animates" }, { "canBreak", true }, { "animate", 1 }, { "doorInfo", new JObject { { "time", 160 }, { "openSound", "door.mp3" }, { "closeSound", "door.mp3" }, { "keys", new JObject() } } } } },
|
||||
{ "ground", new JObject { { "cls", "terrains" } } },
|
||||
{ "grass", new JObject { { "cls", "terrains" } } },
|
||||
{ "grass2", new JObject { { "cls", "terrains" } } },
|
||||
{ "snowGround", new JObject { { "cls", "terrains" } } },
|
||||
{ "ground2", new JObject { { "cls", "terrains" } } },
|
||||
{ "ground3", new JObject { { "cls", "terrains" } } },
|
||||
{ "ground4", new JObject { { "cls", "terrains" } } },
|
||||
{ "sand", new JObject { { "cls", "terrains" } } },
|
||||
{ "ground5", new JObject { { "cls", "terrains" } } },
|
||||
{ "yellowWall2", new JObject { { "cls", "terrains" } } },
|
||||
{ "whiteWall2", new JObject { { "cls", "terrains" } } },
|
||||
{ "blueWall2", new JObject { { "cls", "terrains" } } },
|
||||
{ "blockWall", new JObject { { "cls", "terrains" } } },
|
||||
{ "grayWall", new JObject { { "cls", "terrains" } } },
|
||||
{ "white", new JObject { { "cls", "terrains" } } },
|
||||
{ "ground6", new JObject { { "cls", "terrains" } } },
|
||||
{ "soil", new JObject { { "cls", "terrains" } } },
|
||||
{ "ground7", new JObject { { "cls", "terrains" } } },
|
||||
{ "ground8", new JObject { { "cls", "terrains" } } }
|
||||
};
|
||||
|
||||
// 生成一个新图块序号的数组
|
||||
mapsIndexArray = new string?[newIconsDictionary.Count];
|
||||
|
||||
// 从0-10000寻找可分配给新图块的序号
|
||||
for (int i = 1, c = 0; i < 10000 && c < newIconsDictionary.Count; i++)
|
||||
{
|
||||
if (i == 17) continue; //不知道为什么,但是编辑器里17号被占用了
|
||||
string str_i = i.ToString();
|
||||
if (!jsonObject.ContainsKey(str_i))
|
||||
{
|
||||
mapsIndexArray[c++] = str_i;
|
||||
}
|
||||
if (i == 9999)
|
||||
{
|
||||
MessageBox.Show("警告!Maps.js中存在过多元素!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int index = 0;
|
||||
foreach (KeyValuePair<string, JObject> perdata in newIconsDictionary)
|
||||
{
|
||||
string key = perdata.Key;
|
||||
JObject valuePairs = perdata.Value;
|
||||
string? iconsNumber = mapsIndexArray[index++];
|
||||
if (String.IsNullOrEmpty(iconsNumber)) { break; }
|
||||
JObject iconsValue = perdata.Value;
|
||||
iconsValue = StringUtils.MergeJObjects(iconsValue, new JObject(new JProperty("id", key)));
|
||||
jsonObject[iconsNumber] = perdata.Value;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (JProperty prop in jsonObject.Properties())
|
||||
{
|
||||
JObject propObj = (JObject)prop.Value;
|
||||
|
||||
JToken noPass = propObj["noPass"];
|
||||
if (noPass != null && noPass.ToString() == "True")
|
||||
{
|
||||
propObj["canPass"] = false;
|
||||
}
|
||||
if (noPass != null && noPass.ToString() == "False")
|
||||
{
|
||||
propObj["canPass"] = true;
|
||||
}
|
||||
propObj.Remove("noPass");
|
||||
|
||||
// 原先id存在的icons直接查找替换
|
||||
string iconId = propObj["id"].ToString();
|
||||
if (dictionary.ContainsKey(iconId))
|
||||
{
|
||||
propObj = StringUtils.MergeJObjects(propObj, dictionary[iconId]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 81; i <= 86; i++)
|
||||
{ // 删除terrains的几个门的索引,避免影响animates门的匹配
|
||||
jsonObject.Remove(i.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
226
ViewModels/Migrator/MediaSourceMigrator.cs
Normal file
226
ViewModels/Migrator/MediaSourceMigrator.cs
Normal file
@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Drawing;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
public class MediaSourceMigrator
|
||||
{
|
||||
string oldProjectDirectory, newProjectDirectory;
|
||||
Version version;
|
||||
|
||||
/// <summary>
|
||||
/// 请输入新旧Project文件夹的路径
|
||||
/// </summary>
|
||||
public MediaSourceMigrator(string oldProjectDirectory, string newProjectDirectory, Version ver)
|
||||
{
|
||||
this.oldProjectDirectory = oldProjectDirectory;
|
||||
this.newProjectDirectory = newProjectDirectory;
|
||||
this.version = ver;
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (version.CompareTo(new Version(2, 7)) >= 0)
|
||||
{
|
||||
MigrateDirect();
|
||||
}
|
||||
else
|
||||
{
|
||||
Convert();
|
||||
}
|
||||
MessageBox.Show("迁移素材文件完成。");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移素材文件过程中出现错误: " + $"{e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
public void MigrateDirect()
|
||||
{
|
||||
string[] subFolderNames = ["animates", "autotiles", "bgms", "fonts", "images", "materials", "sounds", "tilesets"];
|
||||
foreach (string folderName in subFolderNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
string sourcePath = Path.Combine(oldProjectDirectory, folderName),
|
||||
destPath = Path.Combine(newProjectDirectory, folderName);
|
||||
FileUtils.CopyFolderContents(sourcePath, destPath);
|
||||
MessageBox.Show("project/" + folderName + "文件夹迁移完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("project/" + folderName + $"文件夹迁移失败,原因:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Convert()
|
||||
{
|
||||
try
|
||||
{
|
||||
string datasJsPath = Path.Combine(oldProjectDirectory, "data.js"),
|
||||
iconsJsPath = Path.Combine(oldProjectDirectory, "icons.js");
|
||||
|
||||
List<string> imagesList = [],
|
||||
bgmsList = [],
|
||||
soundsList = [],
|
||||
autotilesList = [],
|
||||
tilesetsList = [];
|
||||
JObject datasJObject = StringUtils.getValidJson(datasJsPath),
|
||||
iconsJObject = StringUtils.getValidJson(iconsJsPath);
|
||||
|
||||
if (datasJObject["main"]["images"] is JArray imagesJsonList && imagesJsonList.Count > 0)
|
||||
{
|
||||
imagesList = imagesJsonList.ToObject<List<string>>();
|
||||
imagesList.Add("hero.png"); // 2.7以前hero.png硬编码在loader.prototype._loadExtraImages中
|
||||
imagesList.Add("ground.png");
|
||||
|
||||
}
|
||||
if (datasJObject["main"]["bgms"] is JArray bgmsJsonList && bgmsJsonList.Count > 0)
|
||||
{
|
||||
bgmsList = bgmsJsonList.ToObject<List<string>>();
|
||||
}
|
||||
if (datasJObject["main"]["sounds"] is JArray soundsJsonList && soundsJsonList.Count > 0)
|
||||
{
|
||||
soundsList = soundsJsonList.ToObject<List<string>>();
|
||||
}
|
||||
if (datasJObject["main"]["tilesets"] is JArray tilesetsJsonList && tilesetsJsonList.Count > 0)
|
||||
{
|
||||
tilesetsList = tilesetsJsonList.ToObject<List<string>>();
|
||||
}
|
||||
if (iconsJObject["autotile"] is JObject autotilesJsonList && autotilesJsonList.Count > 0)
|
||||
{
|
||||
autotilesList = autotilesJsonList.Properties().Select(prop => prop.Name + ".png").ToList(); //autotile只允许是.png格式
|
||||
}
|
||||
TransferOldAnimate();
|
||||
TransferOldImages(imagesList, autotilesList, tilesetsList);
|
||||
TransferSounds(bgmsList, soundsList);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"素材文件夹迁移出错,原因:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void TransferOldAnimate()
|
||||
{
|
||||
try
|
||||
{
|
||||
string inputDirectory = Path.Combine(oldProjectDirectory, "animates"),
|
||||
outputDirectory = Path.Combine(newProjectDirectory, "animates");
|
||||
FileUtils.CopyFolderContents(inputDirectory, outputDirectory);
|
||||
MessageBox.Show("project/animates文件夹迁移完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"project/animates文件夹迁移出错,原因:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void TransferOldImages(List<string> imagesList, List<string> autotilesList, List<string> tilesetsList)
|
||||
{
|
||||
try
|
||||
{
|
||||
string inputDirectory = Path.Combine(oldProjectDirectory, "images");
|
||||
string[] files = Directory.GetFiles(inputDirectory);
|
||||
|
||||
string[] materialsFiles = ["airwall.png",
|
||||
"animates.png",
|
||||
"enemy48.png",
|
||||
"enemys.png",
|
||||
"fog.png",
|
||||
"ground.png",
|
||||
"icons.png",
|
||||
"icons_old.png",
|
||||
"items.png",
|
||||
"keyboard.png",
|
||||
"npc48.png",
|
||||
"npcs.png",
|
||||
"terrains.png"];
|
||||
foreach (string filePath in files)
|
||||
{
|
||||
string fileName = Path.GetFileName(filePath);
|
||||
if (fileName == "icons.png" && version<new Version(2,5,4)) //检查icons长度
|
||||
{
|
||||
using (Bitmap image = new Bitmap(filePath))
|
||||
{
|
||||
int width = image.Width;
|
||||
int height = image.Height;
|
||||
if (height < 1120)
|
||||
{
|
||||
MessageBox.Show("警告:原塔的icons.png长度不足!请对照最新样板使用PS工具补齐数字键和Alt图标等。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imagesList.Contains(fileName))
|
||||
{
|
||||
File.Copy(filePath, Path.Combine(newProjectDirectory, "images/" + fileName), true);
|
||||
}
|
||||
if (materialsFiles.Contains(fileName))
|
||||
{
|
||||
File.Copy(filePath, Path.Combine(newProjectDirectory, "materials/" + fileName), true);
|
||||
}
|
||||
if (autotilesList.Contains(fileName))
|
||||
{ // 样板会将autotile强制转换为.png
|
||||
File.Copy(filePath, Path.Combine(newProjectDirectory, "autotiles/" + fileName), true);
|
||||
}
|
||||
if (tilesetsList.Contains(fileName))
|
||||
{
|
||||
File.Copy(filePath, Path.Combine(newProjectDirectory, "tilesets/" + fileName), true);
|
||||
}
|
||||
}
|
||||
MessageBox.Show("project/images文件夹迁移完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"project/images文件夹迁移出错,原因:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void TransferSounds(List<string> bgmsList, List<string> soundsList)
|
||||
{
|
||||
try
|
||||
{
|
||||
string inputDirectory = Path.Combine(oldProjectDirectory, "sounds");
|
||||
string[] files = Directory.GetFiles(inputDirectory);
|
||||
|
||||
foreach (string filePath in files)
|
||||
{
|
||||
string fileName = Path.GetFileName(filePath);
|
||||
if (bgmsList.Contains(fileName))
|
||||
{
|
||||
File.Copy(filePath, Path.Combine(newProjectDirectory, "bgms/" + fileName), true);
|
||||
}
|
||||
if (soundsList.Contains(fileName))
|
||||
{
|
||||
File.Copy(filePath, Path.Combine(newProjectDirectory, "sounds/" + fileName), true);
|
||||
}
|
||||
}
|
||||
MessageBox.Show("project/sounds文件夹迁移完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"project/sounds文件夹迁移出错,原因:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
ViewModels/Migrator/ServerTableMigrator.cs
Normal file
54
ViewModels/Migrator/ServerTableMigrator.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Shapes;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.VisualBasic.Devices;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal class ServerTableMigrator
|
||||
{
|
||||
string sourcePath, destPath;
|
||||
Version version;
|
||||
readonly string FILENAME = "_server/table";
|
||||
public ServerTableMigrator(string oldRootDirectory, string newRootDirectory, Version ver)
|
||||
{
|
||||
sourcePath = System.IO.Path.Combine(oldRootDirectory, FILENAME);
|
||||
destPath = System.IO.Path.Combine(newRootDirectory, FILENAME);
|
||||
this.version = ver;
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
try
|
||||
{
|
||||
MigrateDirect();
|
||||
MessageBox.Show("迁移" + FILENAME + "文件夹完成。");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移" + FILENAME + $"过程中出现错误: {e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
void MigrateDirect()
|
||||
{
|
||||
FileUtils.CopyFolderContentsAndSubFolders(sourcePath, destPath);
|
||||
}
|
||||
}
|
||||
}
|
155
ViewModels/Utils/FileUtils.cs
Normal file
155
ViewModels/Utils/FileUtils.cs
Normal file
@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Drawing;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal static class FileUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查文件夹路径是否合法
|
||||
/// </summary>
|
||||
public static bool IsFolderPathValid(string? folderPath, string folderName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
MessageBox.Show(folderName + "文件夹不存在,请检查", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(folderName + $"文件夹不存在,请检查,错误:{e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定文件夹是否存在指定的子文件夹,若不存在,创建一个
|
||||
/// </summary>
|
||||
public static bool checkFolderExist(string folderPath, string subFolderName)
|
||||
{
|
||||
string subFolderPath = Path.Combine(folderPath, subFolderName);
|
||||
if (!Directory.Exists(subFolderPath))
|
||||
{
|
||||
return tryCreateFolder(subFolderName, subFolderPath);
|
||||
}
|
||||
else { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试在指定路径创建文件夹
|
||||
/// </summary>
|
||||
public static bool tryCreateFolder(string folderDirectory, string folderName)
|
||||
{
|
||||
try { Directory.CreateDirectory(folderDirectory); }
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show($"错误:{e.Message},目标文件夹不存在" + folderName + "子文件夹,且创建失败,请检查", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
return false;
|
||||
}
|
||||
if (!Directory.Exists(folderDirectory))
|
||||
{
|
||||
MessageBox.Show("目标文件夹不存在" + folderName + "子文件夹,且创建失败,请检查", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将源文件夹的所有文件拷贝至目标文件夹
|
||||
/// </summary>
|
||||
public static void CopyFolderContents(string sourceFolderPath, string destFolderPath)
|
||||
{
|
||||
string[] files = Directory.GetFiles(sourceFolderPath);
|
||||
foreach (string file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
string targetFilePath = Path.Combine(destFolderPath, Path.GetFileName(file));
|
||||
File.Copy(file, targetFilePath, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移" + file + $"过程中出现错误:{e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将源文件夹的所有文件(含子文件夹及其所有文件)拷贝至目标文件夹
|
||||
/// </summary>
|
||||
public static void CopyFolderContentsAndSubFolders(string sourceFolderPath, string destFolderPath)
|
||||
{
|
||||
string[] files = Directory.GetFiles(sourceFolderPath);
|
||||
foreach (string file in files)
|
||||
{
|
||||
try
|
||||
{
|
||||
string targetFilePath = Path.Combine(destFolderPath, Path.GetFileName(file));
|
||||
File.Copy(file, targetFilePath, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移" + file + $"过程中出现错误:{e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
string[] dirs = Directory.GetDirectories(sourceFolderPath);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
try
|
||||
{
|
||||
string targetFolderPath = Path.Combine(destFolderPath, Path.GetFileName(dir));
|
||||
CopyFolderContentsAndSubFolders(dir, targetFolderPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移" + dir + $"过程中出现错误:{e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将源文件夹名为fileName的指定文件复制到目标文件夹
|
||||
/// </summary>
|
||||
public static void CopyFile(string sourceFolderPath, string destFolderPath, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
string SourcePath = sourceFolderPath;
|
||||
string DestPath = destFolderPath;
|
||||
|
||||
if (!File.Exists(SourcePath))
|
||||
{
|
||||
MessageBox.Show("源文件夹不存在" + fileName + "子文件,请检查", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.IO.File.Copy(SourcePath, DestPath, true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("迁移" + fileName + $"文件出现错误:{e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
174
ViewModels/Utils/StringUtils.cs
Normal file
174
ViewModels/Utils/StringUtils.cs
Normal file
@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal static class StringUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// 从指定路径的.js文件中提取JObject文件
|
||||
/// </summary>
|
||||
public static JObject getValidJson(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
string jsContent = File.ReadAllText(path);
|
||||
string jsonContent;
|
||||
|
||||
int start = jsContent.IndexOf("{");
|
||||
int end = jsContent.LastIndexOf("}") + 1;
|
||||
if (end != -1)
|
||||
{
|
||||
jsonContent = jsContent.Substring(start, end - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonContent = jsContent.Substring(start);
|
||||
}
|
||||
JObject jsonObject = JObject.Parse(jsonContent);
|
||||
return jsonObject;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.Windows.Forms.MessageBox.Show("从" + path + "中读取JSON时出错:" + $"{e.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对于字符串str,找到${...}内部的内容,将其中的oldWord替换为newWord
|
||||
/// </summary>
|
||||
public static string ReplaceInBetweenCurlyBraces(string str, string oldWord, string newWord)
|
||||
{
|
||||
// 定义正则表达式模式,匹配 ${...} 中的内容
|
||||
string pattern = @"\$\{([^}]+)\}";
|
||||
|
||||
// 使用 Regex.Replace 方法进行替换
|
||||
string replacedStr = Regex.Replace(str, pattern, match =>
|
||||
{
|
||||
// 获取匹配的内容,去掉 ${ 和 }
|
||||
string content = match.Groups[1].Value;
|
||||
// 在匹配的内容中替换 oldWord 为 newWord
|
||||
string modifiedContent = content.Replace(oldWord, newWord);
|
||||
// 返回替换后的完整匹配字符串,包含 ${ 和 }
|
||||
return "${" + modifiedContent + "}";
|
||||
});
|
||||
|
||||
return replacedStr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输入要加减的变量名varName,增减值value,符号+=或-=或=,返回一个执行该事件的JSON
|
||||
/// </summary>
|
||||
public static JObject getAddValueJson(string varName, string value, string o)
|
||||
{
|
||||
JObject adder = new JObject();
|
||||
adder.Add(new JProperty("type", "setValue"));
|
||||
adder.Add(new JProperty("name", varName));
|
||||
if (o != "=") adder.Add(new JProperty("operator", o));
|
||||
adder.Add(new JProperty("value", value));
|
||||
return adder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输入effect语句,返回一个包含所有事件的数组
|
||||
/// </summary>
|
||||
/// 参考: events.js/doEffect
|
||||
public static JArray doEffect(string effects)
|
||||
{
|
||||
JArray newEffectsArray = new JArray();
|
||||
string[] effectArr = effects.Split([';']);
|
||||
foreach (string effect in effectArr)
|
||||
{
|
||||
string[] arr = effect.Split("+=");
|
||||
JObject currEffectJson = getAddValueJson(arr[0], arr[1], "+=");
|
||||
newEffectsArray.Add(currEffectJson);
|
||||
}
|
||||
return newEffectsArray;
|
||||
}
|
||||
|
||||
public static string ReplaceOldNames(string input, Version version)
|
||||
{
|
||||
input = input.Replace("Jewel", "Gem");
|
||||
input = input.Replace("ratio", "core.status.thisMap.ratio");
|
||||
return input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 合并两个JObject,jobject2中的键值对覆盖jobject1的键值对(不论原先是否存在),返回jobject1。
|
||||
/// </summary>
|
||||
/// <param name="targetJObject">要合并到并返回的对象。</param>
|
||||
/// <param name="sourceJObject">提供要合并内容的对象。</param>
|
||||
/// <returns>合并后的targetJObject。</returns>
|
||||
public static JObject MergeJObjects(JObject targetJObject, JObject sourceJObject)
|
||||
{
|
||||
foreach (JProperty prop in sourceJObject.Properties())
|
||||
{
|
||||
string key = prop.Name;
|
||||
targetJObject[key] = prop.Value;
|
||||
}
|
||||
return targetJObject;
|
||||
}
|
||||
|
||||
public static JArray CreateMatrix(int width, int height)
|
||||
{
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
throw new ArgumentException("Width and height must be greater than 0.");
|
||||
}
|
||||
|
||||
JArray matrix = new JArray();
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
JArray row = new JArray();
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
row.Add(0);
|
||||
}
|
||||
matrix.Add(row);
|
||||
}
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取塔的地图尺寸,默认值为13
|
||||
/// <summary>
|
||||
public static int ReadMapWidth(string filePath)
|
||||
{
|
||||
int width;
|
||||
try
|
||||
{
|
||||
string fileContent = File.ReadAllText(filePath);
|
||||
|
||||
string widthPattern = @"this\._WIDTH_\s*=\s*(\d+);";
|
||||
|
||||
Match widthMatch = Regex.Match(fileContent, widthPattern);
|
||||
|
||||
if (widthMatch.Success)
|
||||
{
|
||||
width = int.Parse(widthMatch.Groups[1].Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = 13;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
width = 13;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
}
|
||||
}
|
57
ViewModels/Utils/VersionUtils.cs
Normal file
57
ViewModels/Utils/VersionUtils.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace H5MotaUpdate.ViewModels
|
||||
{
|
||||
internal static class VersionUtils
|
||||
{
|
||||
public static bool IsValidVersion(string? version)
|
||||
{
|
||||
if (String.IsNullOrEmpty(version)) return false;
|
||||
string[] segments = version.Split('.');
|
||||
foreach (string segment in segments)
|
||||
{
|
||||
if (!int.TryParse(segment, out int part)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string GetVersion(string? folderPath)
|
||||
{
|
||||
if (folderPath == null) return "文件夹路径不合法";
|
||||
|
||||
string filePath = Path.Combine(folderPath, "main.js");
|
||||
string version;
|
||||
try
|
||||
{
|
||||
if (!File.Exists(filePath)) return "给定文件夹未找到文件main.js";
|
||||
|
||||
string fileContent = File.ReadAllText(filePath);
|
||||
|
||||
Regex versionRegex = new Regex(@"this\.version\s*=\s*['""](\d+(\.\d+)+)['""];");
|
||||
Match match = versionRegex.Match(fileContent);
|
||||
|
||||
if (!match.Success) return "文件 main.js中未找到版本号!";
|
||||
version = match.Groups[1].Value;
|
||||
if (!IsValidVersion(version)) return "文件 main.js中未找到格式合法的版本号!";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return "读取版本号失败,原因: " + ex.Message;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user