From c018b23913260193fef382de2cdd34c096418634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AD=B1=E5=82=91?= Date: Mon, 7 Nov 2022 23:00:57 +0800 Subject: [PATCH] Impl ShopGoodsExcelConfigData.json parsing --- .../GrasscutterTools/Forms/FormShopEditor.cs | 102 +++++++++++++++--- .../Game/Shop/ShopGoodsData.cs | 77 +++++++++++++ Source/GrasscutterTools/Game/Shop/ShopInfo.cs | 32 +++++- .../Game/Shop/ShopRefreshType.cs | 32 ++++-- .../GrasscutterTools/GrasscutterTools.csproj | 1 + .../Properties/Resources.Designer.cs | 13 ++- .../Properties/Resources.en-us.resx | 3 + .../Properties/Resources.resx | 3 + .../Properties/Resources.ru-ru.resx | 3 + .../Properties/Resources.zh-TW.resx | 3 + 10 files changed, 239 insertions(+), 30 deletions(-) create mode 100644 Source/GrasscutterTools/Game/Shop/ShopGoodsData.cs diff --git a/Source/GrasscutterTools/Forms/FormShopEditor.cs b/Source/GrasscutterTools/Forms/FormShopEditor.cs index a28a56d..7e8dfb6 100644 --- a/Source/GrasscutterTools/Forms/FormShopEditor.cs +++ b/Source/GrasscutterTools/Forms/FormShopEditor.cs @@ -102,7 +102,7 @@ namespace GrasscutterTools.Forms var dialog = new OpenFileDialog { FileName = "Shop.json", - Filter = "Shop.Json (*.json)|*.json|All files (*.*)|*.*", + Filter = "Shop.json/ShopGoodsExcelConfigData.json (*.json)|*.json|ShopGoodsData.txt (*.txt)|*.txt|All files (*.*)|*.*", }; var result = dialog.ShowDialog(); if (result == DialogResult.OK) @@ -127,40 +127,101 @@ namespace GrasscutterTools.Forms /// 文件路径 private void LoadShops(string path) { - try + var name = Path.GetFileName(path); + var content = File.ReadAllText(path); + var funs = new Action[3] { - // 反序列化 - var banners = JsonConvert.DeserializeObject>(File.ReadAllText(path)); - Shops = new Dictionary>(banners.Count); - foreach (var item in banners) - Shops.Add(item.ShopType, item.Items); + LoadShopsFromShopJson, + LoadShopsFromShopGoodsExcelConfigData, + LoadShopsFromTsv + }; + if (name == "ShopGoodsExcelConfigData.json") + { + funs[0] = LoadShopsFromShopGoodsExcelConfigData; + funs[1] = LoadShopsFromShopJson; } - catch (Exception ex) + else if (name == "ShopGoodsData.txt") + { + funs[0] = LoadShopsFromTsv; + funs[1] = LoadShopsFromShopJson; + funs[2] = LoadShopsFromShopGoodsExcelConfigData; + } + + Exception firstEx = null; + + foreach (var fun in funs) { try { - // 当Json解析失败时尝试以tsv方式解析 - LoadShopsFromTsv(path); + fun(content); + return; } - catch + catch (Exception ex) { - throw ex; + if (firstEx == null) + firstEx = ex; } } + throw firstEx; + + + //{ + // try + // { + // // 尝试当作Shop.json解析 + // LoadShopsFromShopJson(content); + // } + // catch (Exception ex) + // { + // try + // { + // // 尝试当作ShopGoodsExcelConfigData.json解析 + // LoadShopsFromShopGoodsExcelConfigData(path); + // } + // catch + // { + // try + // { + // // 当Json解析失败时尝试以tsv方式解析 + // LoadShopsFromTsv(content); + // } + // catch + // { + // throw ex; + // } + // } + // } + //} + } + + private void LoadShopsFromShopJson(string content) + { + var banners = JsonConvert.DeserializeObject>(content); + Shops = new Dictionary>(banners.Count); + foreach (var item in banners) + Shops.Add(item.ShopType, item.Items); + } + + private void LoadShopsFromShopGoodsExcelConfigData(string content) + { + var banners = JsonConvert.DeserializeObject>(content); + Shops = new Dictionary>(); + foreach (var kv in banners.GroupBy(it => it.ShopType)) + Shops.Add(kv.Key, kv.Select(it => new ShopInfo(it)).ToList()); } /// /// 从TSV加载商店 /// - /// 文件路径 - private void LoadShopsFromTsv(string path) + /// 文件内容 + private void LoadShopsFromTsv(string content) { - var lines = File.ReadAllLines(path); + var lines = content.Split('\n'); Shops = new Dictionary>(); for (int i = 1; i < lines.Length; i++) { var cells = lines[i].Split('\t'); - + if (cells.Length < 31) continue; var goods = new ShopInfo { GoodsId = int.Parse(cells[0]), @@ -215,6 +276,13 @@ namespace GrasscutterTools.Forms return; } + if (Path.GetFileName(path) != "Shop.json") + { + var ret = MessageBox.Show(Resources.ShopJsonOverrideWarning + '\n' + path, Resources.Warning, MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + if (ret != DialogResult.Yes) + return; + } + // 序列化 var banners = new List(Shops.Count); foreach (var shop in Shops) @@ -411,7 +479,7 @@ namespace GrasscutterTools.Forms MaxLevel = (int)NUDMaxLevel.Value, BeginTime = (int)new DateTimeOffset(DTPBeginTime.Value).ToUnixTimeSeconds(), EndTime = (int)new DateTimeOffset(DTPEndTime.Value).ToUnixTimeSeconds(), - RefreshType = CmbRefreshType.SelectedIndex == -1 ? ShopRefreshType.None : (ShopRefreshType)CmbRefreshType.SelectedIndex, + RefreshType = CmbRefreshType.SelectedIndex == -1 ? ShopRefreshType.NONE : (ShopRefreshType)CmbRefreshType.SelectedIndex, ShopRefreshParam = (int)NUDRefreshParm.Value, HCoin = (int)NUDCostHcoin.Value, SCoin = (int)NUDCostScoin.Value, diff --git a/Source/GrasscutterTools/Game/Shop/ShopGoodsData.cs b/Source/GrasscutterTools/Game/Shop/ShopGoodsData.cs new file mode 100644 index 0000000..5e0af4f --- /dev/null +++ b/Source/GrasscutterTools/Game/Shop/ShopGoodsData.cs @@ -0,0 +1,77 @@ +/** + * Grasscutter Tools + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + **/ +using System; +using System.Collections.Generic; + +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace GrasscutterTools.Game.Shop +{ + public class ShopGoodsData + { + [JsonProperty("goodsId")] + public int GoodsId { get; set; } + + [JsonProperty("shopType")] + public int ShopType { get; set; } + + [JsonProperty("itemId")] + public int ItemId { get; set; } + + [JsonProperty("itemCount")] + public int ItemCount { get; set; } + + [JsonProperty("costScoin")] + public int CostScoin { get; set; } + + [JsonProperty("costHcoin")] + public int CostHcoin { get; set; } + + [JsonProperty("costMcion")] + public int CostMcion { get; set; } + + [JsonProperty("costItems")] + public List CostItems { get; set; } + + [JsonProperty("minPlayerLevel")] + public int MinPlayerLevel { get; set; } + + [JsonProperty("maxPlayerLevel")] + public int MaxPlayerLevel { get; set; } + + [JsonProperty("buyLimit")] + public int BuyLimit { get; set; } + + [JsonProperty("subTabId")] + public int SubTabId { get; set; } + + [JsonProperty("refreshType"), JsonConverter(typeof(StringEnumConverter))] + public ShopRefreshType RefreshType { get; set; } + + [JsonProperty("refreshParam")] + public int RefreshParam { get; set; } + + [JsonProperty("beginTime")] + public DateTime? BeginTime { get; set; } + + [JsonProperty("endTime")] + public DateTime? EndTime { get; set; } + } +} diff --git a/Source/GrasscutterTools/Game/Shop/ShopInfo.cs b/Source/GrasscutterTools/Game/Shop/ShopInfo.cs index 9595740..bd72140 100644 --- a/Source/GrasscutterTools/Game/Shop/ShopInfo.cs +++ b/Source/GrasscutterTools/Game/Shop/ShopInfo.cs @@ -16,14 +16,44 @@ * along with this program. If not, see . * **/ +using System; using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; namespace GrasscutterTools.Game.Shop { public class ShopInfo { + public ShopInfo() + { + + } + + public ShopInfo(ShopGoodsData sgd) + { + GoodsId = sgd.GoodsId; + GoodsItem = new ItemParamData(sgd.ItemId, sgd.ItemCount); + SCoin = sgd.CostScoin; + MCoin = sgd.CostMcion; + HCoin = sgd.CostHcoin; + BuyLimit = sgd.BuyLimit; + + MinLevel = sgd.MinPlayerLevel; + MaxLevel = sgd.MaxPlayerLevel; + CostItemList = sgd.CostItems.Where(it => it.Id != 0).ToList(); + SecondarySheetId = sgd.SubTabId; + RefreshType = sgd.RefreshType; + ShopRefreshParam = sgd.RefreshParam; + if (sgd.BeginTime != null && sgd.EndTime != null) + { + BeginTime = (int)new DateTimeOffset(sgd.BeginTime.Value).ToUnixTimeSeconds(); + EndTime = (int)new DateTimeOffset(sgd.EndTime.Value).ToUnixTimeSeconds(); + } + } + [JsonProperty("goodsId")] public int GoodsId { get; set; } @@ -79,7 +109,7 @@ namespace GrasscutterTools.Game.Shop [JsonProperty("secondarySheetId")] public int SecondarySheetId { get; set; } - [JsonProperty("refreshType")] + [JsonProperty("refreshType"), JsonConverter(typeof(StringEnumConverter))] public ShopRefreshType RefreshType { get; set; } [JsonProperty("shopRefreshParam")] diff --git a/Source/GrasscutterTools/Game/Shop/ShopRefreshType.cs b/Source/GrasscutterTools/Game/Shop/ShopRefreshType.cs index 98b320b..7a13bd2 100644 --- a/Source/GrasscutterTools/Game/Shop/ShopRefreshType.cs +++ b/Source/GrasscutterTools/Game/Shop/ShopRefreshType.cs @@ -1,5 +1,21 @@ -using Newtonsoft.Json; - +/** + * Grasscutter Tools + * Copyright (C) 2022 jie65535 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + **/ namespace GrasscutterTools.Game.Shop { /// @@ -10,25 +26,21 @@ namespace GrasscutterTools.Game.Shop /// /// 不刷新 /// - [JsonProperty("NONE")] - None, + NONE, /// /// 按天刷新 /// - [JsonProperty("SHOP_REFRESH_DAILY")] - Daily, + SHOP_REFRESH_DAILY, /// /// 按周刷新 /// - [JsonProperty("SHOP_REFRESH_WEEKLY")] - Weekly, + SHOP_REFRESH_WEEKLY, /// /// 按月刷新 /// - [JsonProperty("SHOP_REFRESH_MONTHLY")] - Monthly, + SHOP_REFRESH_MONTHLY, } } diff --git a/Source/GrasscutterTools/GrasscutterTools.csproj b/Source/GrasscutterTools/GrasscutterTools.csproj index 978fd04..a8c0f88 100644 --- a/Source/GrasscutterTools/GrasscutterTools.csproj +++ b/Source/GrasscutterTools/GrasscutterTools.csproj @@ -141,6 +141,7 @@ + diff --git a/Source/GrasscutterTools/Properties/Resources.Designer.cs b/Source/GrasscutterTools/Properties/Resources.Designer.cs index ac54564..ef38cb2 100644 --- a/Source/GrasscutterTools/Properties/Resources.Designer.cs +++ b/Source/GrasscutterTools/Properties/Resources.Designer.cs @@ -506,7 +506,7 @@ namespace GrasscutterTools.Properties { ///自杀 ////kill 0 ///全队充能 - ////spawn 2008 25 + ////spawn 2008 x25 ///查看坐标 ////pos ///获取全部物品 @@ -528,7 +528,7 @@ namespace GrasscutterTools.Properties { ///清空全部角色命之座(需重登) ////resetconst all ///清空背包 - ////clear all l [字符串的其余部分被截断]"; 的本地化字符串。 + ////clear all [字符串的其余部分被截断]"; 的本地化字符串。 /// internal static string CustomCommands { get { @@ -1009,6 +1009,15 @@ namespace GrasscutterTools.Properties { } } + /// + /// 查找类似 仅允许以 Shop.json 格式保存!确定要覆盖当前指定文件吗? 的本地化字符串。 + /// + internal static string ShopJsonOverrideWarning { + get { + return ResourceManager.GetString("ShopJsonOverrideWarning", resourceCulture); + } + } + /// /// 查找类似 900:派蒙 ///902:礼包商城 diff --git a/Source/GrasscutterTools/Properties/Resources.en-us.resx b/Source/GrasscutterTools/Properties/Resources.en-us.resx index aa8b842..d87ea2e 100644 --- a/Source/GrasscutterTools/Properties/Resources.en-us.resx +++ b/Source/GrasscutterTools/Properties/Resources.en-us.resx @@ -282,4 +282,7 @@ Improvement suggestions have been submitted, please use caution to send emails t There is a conflict between the current goods ID and the ID in other stores, please replace with another ID or automatically generate an ID + + Only allowed to save in Shop.json format! Are you sure you want to overwrite the currently specified file? + \ No newline at end of file diff --git a/Source/GrasscutterTools/Properties/Resources.resx b/Source/GrasscutterTools/Properties/Resources.resx index 01af696..590fae6 100644 --- a/Source/GrasscutterTools/Properties/Resources.resx +++ b/Source/GrasscutterTools/Properties/Resources.resx @@ -291,4 +291,7 @@ 当前商品ID与其它商店中的ID存在冲突,请更换其它ID或自动生成ID + + 仅允许以 Shop.json 格式保存!确定要覆盖当前指定文件吗? + \ No newline at end of file diff --git a/Source/GrasscutterTools/Properties/Resources.ru-ru.resx b/Source/GrasscutterTools/Properties/Resources.ru-ru.resx index e470aff..387236d 100644 --- a/Source/GrasscutterTools/Properties/Resources.ru-ru.resx +++ b/Source/GrasscutterTools/Properties/Resources.ru-ru.resx @@ -270,4 +270,7 @@ Существует конфликт между текущим идентификатором товара и идентификатором в других магазинах, пожалуйста, замените другим идентификатором или автоматически сгенерируйте идентификатор + + Разрешено сохранять только в формате Shop.json! Вы уверены, что хотите перезаписать текущий указанный файл? + \ No newline at end of file diff --git a/Source/GrasscutterTools/Properties/Resources.zh-TW.resx b/Source/GrasscutterTools/Properties/Resources.zh-TW.resx index 5cdf91f..017e060 100644 --- a/Source/GrasscutterTools/Properties/Resources.zh-TW.resx +++ b/Source/GrasscutterTools/Properties/Resources.zh-TW.resx @@ -276,4 +276,7 @@ 當前商品ID與其它商店中的ID存在衝突,請更換其它ID或自動生成ID + + 僅允許以 Shop.json 格式保存!確定要覆蓋當前指定文件嗎? + \ No newline at end of file