提交导表相关功能
This commit is contained in:
5
Config/Binary/BaitConfigData.bytes
Normal file
5
Config/Binary/BaitConfigData.bytes
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
¡Âbaits/worm_01/worm_01(ú
|
||||||
|
¢Â
|
||||||
|
baits/fly/fly(x
|
||||||
|
'£Âbaits/black_leech/black_leech(x
|
||||||
5
Config/Binary/BobberConfigData.bytes
Normal file
5
Config/Binary/BobberConfigData.bytes
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
6á§*bobbers/expressfishing/bob_25003/bob_25003 ((
|
||||||
|
:â§0bobbers/expressfishing/bob_25162_25163/bob_25162 ((
|
||||||
|
:ã§0bobbers/expressfishing/bob_25166_25167/bob_25166 ((
|
||||||
|
4ä§*bobbers/expressfishing/bob_25001/bob_25001 ((
|
||||||
2
Config/Binary/FeederConfigData.bytes
Normal file
2
Config/Binary/FeederConfigData.bytes
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
&¡÷6Feeders/Feeder 1/FeedTrash 1 d(
|
||||||
6
Config/Binary/FishConfigData.bytes
Normal file
6
Config/Binary/FishConfigData.bytes
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
ÁنBurbot_B
|
||||||
|
(0"8ˇ–€
|
||||||
|
ÂŁ†CarpCommon_B (0"8ˇ–€
|
||||||
|
ĂŁ†CarpGrass_B (0"8ˇ–€
|
||||||
|
ÄŁ†
|
||||||
3
Config/Binary/HookConfigData.bytes
Normal file
3
Config/Binary/HookConfigData.bytes
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
:áÜ*.hooks/alliance/c_hook_20789_20794/c_hook_20789 0
|
||||||
|
?âÜ*3hooks/berserk_hooks/triple_20569_20577/triple_20569 0
|
||||||
3
Config/Binary/LineConfigData.bytes
Normal file
3
Config/Binary/LineConfigData.bytes
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
(<08>Lines/UFE Mono/UFE monoClear ((0
|
||||||
|
4し(rods/syberia/bolo_10021/bolo_10021_LB400 ((0
|
||||||
5
Config/Binary/LureConfigData.bytes
Normal file
5
Config/Binary/LureConfigData.bytes
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
DÁÏ$5lures/express_fishing/crankbaits_1/775/crankbaits_775ÆÝ* 20ú
|
||||||
|
EÂÏ$7lures/express_fishing/poppers_1/poppers_590/poppers_590ÆÝ* 20x
|
||||||
|
MÃÏ$Clures/express_fishing/softplastic/ef_supergrab_6/softplastic_g_1622 20x
|
||||||
|
OÄÏ$Elures/express_fishing/softplastic/ef_superminnow_6/softplastic_m_1634 20x
|
||||||
BIN
Config/Binary/ReelConfigData.bytes
Normal file
BIN
Config/Binary/ReelConfigData.bytes
Normal file
Binary file not shown.
3
Config/Binary/RingConfigData.bytes
Normal file
3
Config/Binary/RingConfigData.bytes
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
(á‘C"rod_rings/rumoi/rumoi_oxiline_spin
|
||||||
|
)â‘C#rod_rings/smt/smt_pure_ceramic_bolo
|
||||||
4
Config/Binary/RodConfigData.bytes
Normal file
4
Config/Binary/RodConfigData.bytes
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
7¡<>&rods/syberia/tele_10037/tele_10037_t13(0ú8(@C
|
||||||
|
:¢<>(rods/syberia/bolo_10021/bolo_10021_LB400 â‘C(0x8(@
|
||||||
|
9£<>'rods/syberia/spin_10034/spin_10034_S60H á‘C(0x8(@
|
||||||
2
Config/Binary/WeightConfigData.bytes
Normal file
2
Config/Binary/WeightConfigData.bytes
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
<08>ê0Weights/Weight2_5g
|
||||||
BIN
Config/Excel/BaitConfig.xlsx
Normal file
BIN
Config/Excel/BaitConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/BobberConfig.xlsx
Normal file
BIN
Config/Excel/BobberConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/FeederConfig.xlsx
Normal file
BIN
Config/Excel/FeederConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/FishConfig.xlsx
Normal file
BIN
Config/Excel/FishConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/HookConfig.xlsx
Normal file
BIN
Config/Excel/HookConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/LineConfig.xlsx
Normal file
BIN
Config/Excel/LineConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/LureConfig.xlsx
Normal file
BIN
Config/Excel/LureConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/ReelConfig.xlsx
Normal file
BIN
Config/Excel/ReelConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/RingConfig.xlsx
Normal file
BIN
Config/Excel/RingConfig.xlsx
Normal file
Binary file not shown.
BIN
Config/Excel/RodConfig.xlsx
Normal file
BIN
Config/Excel/RodConfig.xlsx
Normal file
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
{"WorksheetNames":[-8419147776733210060,-3495952183970875596,1720330851179383898,5812538452563588342],"Tables":{"-3495952183970875596":1757296589391,"-1088042625810372120":1748918712210,"1720330851179383898":1753770985781,"3730651590607244245":1748918712210,"5812538452563588342":1751250727840}}
|
|
||||||
BIN
Config/Excel/WeightConfig.xlsx
Normal file
BIN
Config/Excel/WeightConfig.xlsx
Normal file
Binary file not shown.
6
Config/Json/Server/BaitConfigData.Json
Normal file
6
Config/Json/Server/BaitConfigData.Json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":500001,"Model":"baits/worm_01/worm_01","EfficacyBase":15,"Length":0,"Weight":250},
|
||||||
|
{"Id":500002,"Model":"baits/fly/fly","EfficacyBase":15,"Length":0,"Weight":120},
|
||||||
|
{"Id":500003,"Model":"baits/black_leech/black_leech","EfficacyBase":15,"Length":0,"Weight":120},
|
||||||
|
{"Id":500004,"Model":"baits/bread/bread","EfficacyBase":15,"Length":0,"Weight":120}
|
||||||
|
]}
|
||||||
6
Config/Json/Server/BobberConfigData.Json
Normal file
6
Config/Json/Server/BobberConfigData.Json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":300001,"Model":"bobbers/expressfishing/bob_25003/bob_25003","Type":2,"Weight":1,"Displacement":40,"NightLight":0},
|
||||||
|
{"Id":300002,"Model":"bobbers/expressfishing/bob_25162_25163/bob_25162","Type":0,"Weight":1,"Displacement":40,"NightLight":0},
|
||||||
|
{"Id":300003,"Model":"bobbers/expressfishing/bob_25166_25167/bob_25166","Type":0,"Weight":1,"Displacement":40,"NightLight":0},
|
||||||
|
{"Id":300004,"Model":"bobbers/expressfishing/bob_25001/bob_25001","Type":0,"Weight":1,"Displacement":40,"NightLight":0}
|
||||||
|
]}
|
||||||
3
Config/Json/Server/FeederConfigData.Json
Normal file
3
Config/Json/Server/FeederConfigData.Json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":900001,"Model":"Feeders/Feeder 1/FeedTrash 1","Type":0,"Capacity":100,"Weight":5}
|
||||||
|
]}
|
||||||
6
Config/Json/Server/FishConfigData.Json
Normal file
6
Config/Json/Server/FishConfigData.Json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":2200001,"Model":["Burbot_B"],"Type":0,"SpeciesName":10,"MinWeight":1,"MaxWeight":34,"Accept":2100001},
|
||||||
|
{"Id":2200002,"Model":["CarpCommon_B"],"Type":0,"SpeciesName":11,"MinWeight":1,"MaxWeight":34,"Accept":2100001},
|
||||||
|
{"Id":2200003,"Model":["CarpGrass_B"],"Type":0,"SpeciesName":14,"MinWeight":1,"MaxWeight":34,"Accept":2100001},
|
||||||
|
{"Id":2200004,"Model":["CarpCrucian_B"],"Type":0,"SpeciesName":16,"MinWeight":1,"MaxWeight":34,"Accept":2100001}
|
||||||
|
]}
|
||||||
4
Config/Json/Server/HookConfigData.Json
Normal file
4
Config/Json/Server/HookConfigData.Json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":700001,"Model":"hooks/alliance/c_hook_20789_20794/c_hook_20789","Type":1,"Zadzior":1,"Length":0,"Weight":1},
|
||||||
|
{"Id":700002,"Model":"hooks/berserk_hooks/triple_20569_20577/triple_20569","Type":1,"Zadzior":1,"Length":0,"Weight":1}
|
||||||
|
]}
|
||||||
4
Config/Json/Server/LineConfigData.Json
Normal file
4
Config/Json/Server/LineConfigData.Json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":400001,"Model":"Lines/UFE Mono/UFE monoClear","Type":0,"Length":7,"Strength":40,"Size":1},
|
||||||
|
{"Id":400002,"Model":"rods/syberia/bolo_10021/bolo_10021_LB400","Type":0,"Length":5,"Strength":40,"Size":1}
|
||||||
|
]}
|
||||||
6
Config/Json/Server/LureConfigData.Json
Normal file
6
Config/Json/Server/LureConfigData.Json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":600001,"Model":"lures/express_fishing/crankbaits_1/775/crankbaits_775","Hook":[700102],"EfficacyBase":50,"Length":0,"Weight":250},
|
||||||
|
{"Id":600002,"Model":"lures/express_fishing/poppers_1/poppers_590/poppers_590","Hook":[700102],"EfficacyBase":50,"Length":0,"Weight":120},
|
||||||
|
{"Id":600003,"Model":"lures/express_fishing/softplastic/ef_supergrab_6/softplastic_g_1622","Hook":[],"EfficacyBase":50,"Length":0,"Weight":120},
|
||||||
|
{"Id":600004,"Model":"lures/express_fishing/softplastic/ef_superminnow_6/softplastic_m_1634","Hook":[],"EfficacyBase":50,"Length":0,"Weight":120}
|
||||||
|
]}
|
||||||
4
Config/Json/Server/ReelConfigData.Json
Normal file
4
Config/Json/Server/ReelConfigData.Json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":200001,"Model":"reels/syberia/spin_5002/spin_5002","Type":0,"GearRatio":[7.0],"Size":250,"Strength":40},
|
||||||
|
{"Id":200002,"Model":"reels/syberia/spin_5036/spin_5036","Type":0,"GearRatio":[5.0],"Size":120,"Strength":40}
|
||||||
|
]}
|
||||||
4
Config/Json/Server/RingConfigData.Json
Normal file
4
Config/Json/Server/RingConfigData.Json
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":1100001,"Model":"rod_rings/rumoi/rumoi_oxiline_spin"},
|
||||||
|
{"Id":1100002,"Model":"rod_rings/smt/smt_pure_ceramic_bolo"}
|
||||||
|
]}
|
||||||
5
Config/Json/Server/RodConfigData.Json
Normal file
5
Config/Json/Server/RodConfigData.Json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":100001,"Model":"rods/syberia/tele_10037/tele_10037_t13","Type":1,"Ring":0,"Length":7,"Weight":250,"Strength":40,"MaxRange":67,"ConstructionType":0},
|
||||||
|
{"Id":100002,"Model":"rods/syberia/bolo_10021/bolo_10021_LB400","Type":0,"Ring":1100002,"Length":5,"Weight":120,"Strength":40,"MaxRange":30,"ConstructionType":0},
|
||||||
|
{"Id":100003,"Model":"rods/syberia/spin_10034/spin_10034_S60H","Type":0,"Ring":1100001,"Length":5,"Weight":120,"Strength":40,"MaxRange":30,"ConstructionType":0}
|
||||||
|
]}
|
||||||
3
Config/Json/Server/WeightConfigData.Json
Normal file
3
Config/Json/Server/WeightConfigData.Json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{"List":[
|
||||||
|
{"Id":800001,"Model":"Weights/Weight2_5g","Type":0,"Weight":3}
|
||||||
|
]}
|
||||||
101
Entity/Generate/ConfigTable/Entity/BaitConfig.cs
Normal file
101
Entity/Generate/ConfigTable/Entity/BaitConfig.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class BaitConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<BaitConfig> List { get; set; } = new List<BaitConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, BaitConfig> _configs = new ConcurrentDictionary<uint, BaitConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, BaitConfig> _configs = new Dictionary<uint, BaitConfig>();
|
||||||
|
#endif
|
||||||
|
private static BaitConfigData _instance = null;
|
||||||
|
|
||||||
|
public static BaitConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<BaitConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaitConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"BaitConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out BaitConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class BaitConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint EfficacyBase { get; set; } // 吸引力
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint Length { get; set; } // 长度(毫米)
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Weight { get; set; } // 重量(克)
|
||||||
|
}
|
||||||
|
}
|
||||||
103
Entity/Generate/ConfigTable/Entity/BobberConfig.cs
Normal file
103
Entity/Generate/ConfigTable/Entity/BobberConfig.cs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class BobberConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<BobberConfig> List { get; set; } = new List<BobberConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, BobberConfig> _configs = new ConcurrentDictionary<uint, BobberConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, BobberConfig> _configs = new Dictionary<uint, BobberConfig>();
|
||||||
|
#endif
|
||||||
|
private static BobberConfigData _instance = null;
|
||||||
|
|
||||||
|
public static BobberConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<BobberConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BobberConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"BobberConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out BobberConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class BobberConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint Weight { get; set; } // 重量(克)
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Displacement { get; set; } // 位移
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public uint NightLight { get; set; } // 是否夜光
|
||||||
|
}
|
||||||
|
}
|
||||||
101
Entity/Generate/ConfigTable/Entity/FeederConfig.cs
Normal file
101
Entity/Generate/ConfigTable/Entity/FeederConfig.cs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class FeederConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<FeederConfig> List { get; set; } = new List<FeederConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, FeederConfig> _configs = new ConcurrentDictionary<uint, FeederConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, FeederConfig> _configs = new Dictionary<uint, FeederConfig>();
|
||||||
|
#endif
|
||||||
|
private static FeederConfigData _instance = null;
|
||||||
|
|
||||||
|
public static FeederConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<FeederConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeederConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"FeederConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out FeederConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class FeederConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint Capacity { get; set; } // 能力
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Weight { get; set; } // 重量(克)
|
||||||
|
}
|
||||||
|
}
|
||||||
105
Entity/Generate/ConfigTable/Entity/FishConfig.cs
Normal file
105
Entity/Generate/ConfigTable/Entity/FishConfig.cs
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class FishConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<FishConfig> List { get; set; } = new List<FishConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, FishConfig> _configs = new ConcurrentDictionary<uint, FishConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, FishConfig> _configs = new Dictionary<uint, FishConfig>();
|
||||||
|
#endif
|
||||||
|
private static FishConfigData _instance = null;
|
||||||
|
|
||||||
|
public static FishConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<FishConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FishConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"FishConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out FishConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class FishConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string[] Model { get; set; } = Array.Empty<string>(); // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint SpeciesName { get; set; } // 鱼类型Id
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint MinWeight { get; set; } // 最小重量(克)
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public uint MaxWeight { get; set; } // 最大重量(克)
|
||||||
|
[ProtoMember(7)]
|
||||||
|
public uint Accept { get; set; } // 接受饵
|
||||||
|
}
|
||||||
|
}
|
||||||
103
Entity/Generate/ConfigTable/Entity/HookConfig.cs
Normal file
103
Entity/Generate/ConfigTable/Entity/HookConfig.cs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class HookConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<HookConfig> List { get; set; } = new List<HookConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, HookConfig> _configs = new ConcurrentDictionary<uint, HookConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, HookConfig> _configs = new Dictionary<uint, HookConfig>();
|
||||||
|
#endif
|
||||||
|
private static HookConfigData _instance = null;
|
||||||
|
|
||||||
|
public static HookConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<HookConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HookConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"HookConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out HookConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class HookConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint Zadzior { get; set; } // 长钉
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Length { get; set; } // 长度(毫米)
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public uint Weight { get; set; } // 重量(克)
|
||||||
|
}
|
||||||
|
}
|
||||||
103
Entity/Generate/ConfigTable/Entity/LineConfig.cs
Normal file
103
Entity/Generate/ConfigTable/Entity/LineConfig.cs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class LineConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<LineConfig> List { get; set; } = new List<LineConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, LineConfig> _configs = new ConcurrentDictionary<uint, LineConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, LineConfig> _configs = new Dictionary<uint, LineConfig>();
|
||||||
|
#endif
|
||||||
|
private static LineConfigData _instance = null;
|
||||||
|
|
||||||
|
public static LineConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<LineConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LineConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"LineConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out LineConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class LineConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint Length { get; set; } // 长度(毫米)
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Strength { get; set; } // 强度
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public uint Size { get; set; } // 尺寸
|
||||||
|
}
|
||||||
|
}
|
||||||
103
Entity/Generate/ConfigTable/Entity/LureConfig.cs
Normal file
103
Entity/Generate/ConfigTable/Entity/LureConfig.cs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class LureConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<LureConfig> List { get; set; } = new List<LureConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, LureConfig> _configs = new ConcurrentDictionary<uint, LureConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, LureConfig> _configs = new Dictionary<uint, LureConfig>();
|
||||||
|
#endif
|
||||||
|
private static LureConfigData _instance = null;
|
||||||
|
|
||||||
|
public static LureConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<LureConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LureConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"LureConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out LureConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class LureConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint[] Hook { get; set; } = Array.Empty<uint>(); // 勾
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint EfficacyBase { get; set; } // 吸引力
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Length { get; set; } // 长度(毫米)
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public uint Weight { get; set; } // 重量(克)
|
||||||
|
}
|
||||||
|
}
|
||||||
103
Entity/Generate/ConfigTable/Entity/ReelConfig.cs
Normal file
103
Entity/Generate/ConfigTable/Entity/ReelConfig.cs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class ReelConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<ReelConfig> List { get; set; } = new List<ReelConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, ReelConfig> _configs = new ConcurrentDictionary<uint, ReelConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, ReelConfig> _configs = new Dictionary<uint, ReelConfig>();
|
||||||
|
#endif
|
||||||
|
private static ReelConfigData _instance = null;
|
||||||
|
|
||||||
|
public static ReelConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<ReelConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReelConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"ReelConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out ReelConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class ReelConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public float[] GearRatio { get; set; } = Array.Empty<float>(); // 组件比
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Size { get; set; } // 尺寸
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public uint Strength { get; set; } // 强度
|
||||||
|
}
|
||||||
|
}
|
||||||
95
Entity/Generate/ConfigTable/Entity/RingConfig.cs
Normal file
95
Entity/Generate/ConfigTable/Entity/RingConfig.cs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class RingConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<RingConfig> List { get; set; } = new List<RingConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, RingConfig> _configs = new ConcurrentDictionary<uint, RingConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, RingConfig> _configs = new Dictionary<uint, RingConfig>();
|
||||||
|
#endif
|
||||||
|
private static RingConfigData _instance = null;
|
||||||
|
|
||||||
|
public static RingConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<RingConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RingConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"RingConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out RingConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class RingConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
}
|
||||||
|
}
|
||||||
109
Entity/Generate/ConfigTable/Entity/RodConfig.cs
Normal file
109
Entity/Generate/ConfigTable/Entity/RodConfig.cs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class RodConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<RodConfig> List { get; set; } = new List<RodConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, RodConfig> _configs = new ConcurrentDictionary<uint, RodConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, RodConfig> _configs = new Dictionary<uint, RodConfig>();
|
||||||
|
#endif
|
||||||
|
private static RodConfigData _instance = null;
|
||||||
|
|
||||||
|
public static RodConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<RodConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RodConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"RodConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out RodConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class RodConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint Ring { get; set; } // 导线圈
|
||||||
|
[ProtoMember(5)]
|
||||||
|
public uint Length { get; set; } // 长度(毫米)
|
||||||
|
[ProtoMember(6)]
|
||||||
|
public uint Weight { get; set; } // 重量(克)
|
||||||
|
[ProtoMember(7)]
|
||||||
|
public uint Strength { get; set; } // 强度
|
||||||
|
[ProtoMember(8)]
|
||||||
|
public uint MaxRange { get; set; } // 最大范围
|
||||||
|
[ProtoMember(9)]
|
||||||
|
public uint ConstructionType { get; set; } // 结构类型
|
||||||
|
}
|
||||||
|
}
|
||||||
99
Entity/Generate/ConfigTable/Entity/WeightConfig.cs
Normal file
99
Entity/Generate/ConfigTable/Entity/WeightConfig.cs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace Fantasy
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class WeightConfigData : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<WeightConfig> List { get; set; } = new List<WeightConfig>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, WeightConfig> _configs = new ConcurrentDictionary<uint, WeightConfig>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, WeightConfig> _configs = new Dictionary<uint, WeightConfig>();
|
||||||
|
#endif
|
||||||
|
private static WeightConfigData _instance = null;
|
||||||
|
|
||||||
|
public static WeightConfigData Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<WeightConfigData>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeightConfig Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"WeightConfig not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out WeightConfig config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class WeightConfig : ASerialize, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public uint Id { get; set; } // Id
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public string Model { get; set; } // 模型
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public uint Type { get; set; } // 类型
|
||||||
|
[ProtoMember(4)]
|
||||||
|
public uint Weight { get; set; } // 重量(克)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,6 +61,7 @@
|
|||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APipeWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb12a8c0984934a8b9a488164bdec50312ec00_003Ff6_003F9d6126fa_003FPipeWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APipeWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb12a8c0984934a8b9a488164bdec50312ec00_003Ff6_003F9d6126fa_003FPipeWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APriorityQueue_00602_002Ecs_002Fl_003AC_0021_003FUsers_003F60527_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F46b03cd429344aac8ead6cde395f2ffd51918_003Fea_003Ff041a5cb_003FPriorityQueue_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APriorityQueue_00602_002Ecs_002Fl_003AC_0021_003FUsers_003F60527_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F46b03cd429344aac8ead6cde395f2ffd51918_003Fea_003Ff041a5cb_003FPriorityQueue_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APriorityQueue_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fd8a0b92db29b4e8f99b8db03b74e165943600_003F8e_003F0782b53d_003FPriorityQueue_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APriorityQueue_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fd8a0b92db29b4e8f99b8db03b74e165943600_003F8e_003F0782b53d_003FPriorityQueue_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProtoMemberAttribute_002Ecs_002Fl_003AC_0021_003FUsers_003FFIREBAT_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F1ad39110987b317aa178f528f27d9c837589269676a6a2ccc7fbf6b59b7d9_003FProtoMemberAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProtoMemberAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ff4d74acca13b4111aaa523ebe15f4f3348800_003F51_003Fa2613704_003FProtoMemberAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProtoMemberAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ff4d74acca13b4111aaa523ebe15f4f3348800_003F51_003Fa2613704_003FProtoMemberAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProtoMemberAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F1ad39110987b317aa178f528f27d9c837589269676a6a2ccc7fbf6b59b7d9_003FProtoMemberAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProtoMemberAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F1ad39110987b317aa178f528f27d9c837589269676a6a2ccc7fbf6b59b7d9_003FProtoMemberAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProtoWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ff4d74acca13b4111aaa523ebe15f4f3348800_003Fa9_003F36ff0954_003FProtoWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProtoWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FLibrary_003FApplication_0020Support_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Ff4d74acca13b4111aaa523ebe15f4f3348800_003Fa9_003F36ff0954_003FProtoWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
|||||||
25
Tools/ConfigBuilder/ConfigBuilder.sln
Normal file
25
Tools/ConfigBuilder/ConfigBuilder.sln
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.14.36408.4 d17.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBConfigBuilder", "NBConfigBuilder\NBConfigBuilder.csproj", "{A6264F0E-870D-401D-B1BF-698695AC674C}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{A6264F0E-870D-401D-B1BF-698695AC674C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A6264F0E-870D-401D-B1BF-698695AC674C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A6264F0E-870D-401D-B1BF-698695AC674C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A6264F0E-870D-401D-B1BF-698695AC674C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {F223241C-FF74-4903-8F47-8A5A5A0FAC99}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
3
Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user
Normal file
3
Tools/ConfigBuilder/ConfigBuilder.sln.DotSettings.user
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALogManager_002Ecs_002Fl_003AC_0021_003FUsers_003FFIREBAT_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc5462be99aec4b8dbd0143c73a99d4d1e0000_003F10_003Fa592ee39_003FLogManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANativeWindow_002Ecs_002Fl_003AC_0021_003FUsers_003FFIREBAT_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F257c19112c5249f9bf699efc998471b6cef910_003F44_003Fcc810871_003FNativeWindow_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||||
20
Tools/ConfigBuilder/NBConfigBuilder/App.cs
Normal file
20
Tools/ConfigBuilder/NBConfigBuilder/App.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
// 添加配置类
|
||||||
|
public class AppConfig
|
||||||
|
{
|
||||||
|
public string ExcelPath { get; set; }
|
||||||
|
public string ClientPath { get; set; }
|
||||||
|
public string ClientJsonPath { get; set; }
|
||||||
|
public string ServerPath { get; set; }
|
||||||
|
public string ServerJsonPath { get; set; }
|
||||||
|
public bool GenClient { get; set; }
|
||||||
|
public bool GenServer { get; set; }
|
||||||
|
|
||||||
|
public string ExcelVersionPath => Path.Combine(ExcelPath, "Version.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class App
|
||||||
|
{
|
||||||
|
public static AppConfig Config;
|
||||||
|
}
|
||||||
17
Tools/ConfigBuilder/NBConfigBuilder/Core/IPool.cs
Normal file
17
Tools/ConfigBuilder/NBConfigBuilder/Core/IPool.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实现了这个接口代表支持对象池
|
||||||
|
/// </summary>
|
||||||
|
public interface IPool
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否从池里创建的
|
||||||
|
/// </summary>
|
||||||
|
bool IsPool();
|
||||||
|
/// <summary>
|
||||||
|
/// 设置是否从池里创建的
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="isPool"></param>
|
||||||
|
void SetIsPool(bool isPool);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
public partial class IntDictionaryConfig
|
||||||
|
{
|
||||||
|
public Dictionary<int, int> Dic;
|
||||||
|
public int this[int key] => GetValue(key);
|
||||||
|
|
||||||
|
public bool TryGetValue(int key, out int value)
|
||||||
|
{
|
||||||
|
value = default;
|
||||||
|
|
||||||
|
if (!Dic.ContainsKey(key))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = Dic[key];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetValue(int key)
|
||||||
|
{
|
||||||
|
return Dic.TryGetValue(key, out var value) ? value : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using System.Buffers;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
public enum MemoryStreamBufferSource
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Pack = 1,
|
||||||
|
UnPack = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class MemoryStreamBuffer : MemoryStream, IBufferWriter<byte>
|
||||||
|
{
|
||||||
|
public MemoryStreamBufferSource MemoryStreamBufferSource;
|
||||||
|
|
||||||
|
public MemoryStreamBuffer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryStreamBuffer(MemoryStreamBufferSource memoryStreamBufferSource, int capacity) : base(capacity)
|
||||||
|
{
|
||||||
|
MemoryStreamBufferSource = memoryStreamBufferSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MemoryStreamBuffer(byte[] buffer) : base(buffer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Advance(int count)
|
||||||
|
{
|
||||||
|
if (count < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(count), count, "The value of 'count' cannot be negative.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var newLength = Position + count;
|
||||||
|
|
||||||
|
if (newLength != Length)
|
||||||
|
{
|
||||||
|
SetLength(newLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
Position = newLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Memory<byte> GetMemory(int sizeHint = 0)
|
||||||
|
{
|
||||||
|
if (sizeHint < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint,
|
||||||
|
"The value of 'count' cannot be negative.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length - Position <= sizeHint)
|
||||||
|
{
|
||||||
|
SetLength(Position + sizeHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Memory<byte>(GetBuffer(), (int)Position, (int)(Length - Position));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Span<byte> GetSpan(int sizeHint = 0)
|
||||||
|
{
|
||||||
|
if (sizeHint < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint,
|
||||||
|
"The value of 'count' cannot be negative.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length - Position <= sizeHint)
|
||||||
|
{
|
||||||
|
SetLength(Position + sizeHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Span<byte>(GetBuffer(), (int)Position, (int)(Length - Position));
|
||||||
|
}
|
||||||
|
}
|
||||||
217
Tools/ConfigBuilder/NBConfigBuilder/Core/OneToManyList.cs
Normal file
217
Tools/ConfigBuilder/NBConfigBuilder/Core/OneToManyList.cs
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可回收的、一对多关系的列表池。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TKey">键的类型。</typeparam>
|
||||||
|
/// <typeparam name="TValue">值的类型。</typeparam>
|
||||||
|
public class OneToManyListPool<TKey, TValue> : OneToManyList<TKey, TValue>, IDisposable, IPool where TKey : notnull
|
||||||
|
{
|
||||||
|
private bool _isPool;
|
||||||
|
private bool _isDispose;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建一个 <see cref="OneToManyListPool{TKey, TValue}"/> 一对多关系的列表池的实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>创建的实例。</returns>
|
||||||
|
public static OneToManyListPool<TKey, TValue> Create()
|
||||||
|
{
|
||||||
|
var list = Pool<OneToManyListPool<TKey, TValue>>.Rent();
|
||||||
|
list._isDispose = false;
|
||||||
|
list._isPool = true;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放当前对象所占用的资源,并将对象回收到对象池中。
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_isDispose)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isDispose = true;
|
||||||
|
Clear();
|
||||||
|
Pool<OneToManyListPool<TKey, TValue>>.Return(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一个值,该值指示当前实例是否为对象池中的实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsPool()
|
||||||
|
{
|
||||||
|
return _isPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置一个值,该值指示当前实例是否为对象池中的实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="isPool"></param>
|
||||||
|
public void SetIsPool(bool isPool)
|
||||||
|
{
|
||||||
|
_isPool = isPool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 一对多关系的列表字典。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TKey">键的类型。</typeparam>
|
||||||
|
/// <typeparam name="TValue">值的类型。</typeparam>
|
||||||
|
public class OneToManyList<TKey, TValue> : Dictionary<TKey, List<TValue>> where TKey : notnull
|
||||||
|
{
|
||||||
|
private readonly int _recyclingLimit = 120;
|
||||||
|
private static readonly List<TValue> Empty = new List<TValue>();
|
||||||
|
private readonly Queue<List<TValue>> _queue = new Queue<List<TValue>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化一个新的 <see cref="OneToManyList{TKey, TValue}"/> 实例。
|
||||||
|
/// </summary>
|
||||||
|
public OneToManyList()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置最大缓存数量
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="recyclingLimit">
|
||||||
|
/// 1:防止数据量过大、所以超过recyclingLimit的数据还是走GC.
|
||||||
|
/// 2:设置成0不控制数量,全部缓存
|
||||||
|
/// </param>
|
||||||
|
public OneToManyList(int recyclingLimit)
|
||||||
|
{
|
||||||
|
_recyclingLimit = recyclingLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断给定的键和值是否存在于列表中。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">要搜索的键。</param>
|
||||||
|
/// <param name="value">要搜索的值。</param>
|
||||||
|
/// <returns>如果存在则为 <see langword="true"/>,否则为 <see langword="false"/>。</returns>
|
||||||
|
public bool Contains(TKey key, TValue value)
|
||||||
|
{
|
||||||
|
TryGetValue(key, out var list);
|
||||||
|
|
||||||
|
return list != null && list.Contains(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向列表中添加指定键和值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">要添加值的键。</param>
|
||||||
|
/// <param name="value">要添加的值。</param>
|
||||||
|
public void Add(TKey key, TValue value)
|
||||||
|
{
|
||||||
|
if (!TryGetValue(key, out var list))
|
||||||
|
{
|
||||||
|
list = Fetch();
|
||||||
|
list.Add(value);
|
||||||
|
Add(key, list);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定键对应的列表中的第一个值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">要获取值的键。</param>
|
||||||
|
/// <returns>键对应的列表中的第一个值。</returns>
|
||||||
|
public TValue First(TKey key)
|
||||||
|
{
|
||||||
|
return !TryGetValue(key, out var list) ? default : list.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从列表中移除指定键和值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">要移除值的键。</param>
|
||||||
|
/// <param name="value">要移除的值。</param>
|
||||||
|
/// <returns>如果成功移除则为 <see langword="true"/>,否则为 <see langword="false"/>。</returns>
|
||||||
|
public bool RemoveValue(TKey key, TValue value)
|
||||||
|
{
|
||||||
|
if (!TryGetValue(key, out var list))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isRemove = list.Remove(value);
|
||||||
|
|
||||||
|
if (list.Count == 0)
|
||||||
|
{
|
||||||
|
isRemove = RemoveByKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isRemove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从列表中移除指定键及其关联的所有值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">要移除的键。</param>
|
||||||
|
/// <returns>如果成功移除则为 <see langword="true"/>,否则为 <see langword="false"/>。</returns>
|
||||||
|
public bool RemoveByKey(TKey key)
|
||||||
|
{
|
||||||
|
if (!TryGetValue(key, out var list))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Remove(key);
|
||||||
|
Recycle(list);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定键关联的所有值的列表。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">要获取值的键。</param>
|
||||||
|
/// <returns>键关联的所有值的列表。</returns>
|
||||||
|
public List<TValue> GetValues(TKey key)
|
||||||
|
{
|
||||||
|
if (TryGetValue(key, out List<TValue> list))
|
||||||
|
{
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除字典中的所有键值对,并回收相关的值集合。
|
||||||
|
/// </summary>
|
||||||
|
public new void Clear()
|
||||||
|
{
|
||||||
|
foreach (var keyValuePair in this) Recycle(keyValuePair.Value);
|
||||||
|
|
||||||
|
base.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从空闲值集合队列中获取一个值集合,如果队列为空则创建一个新的值集合。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>从队列中获取的值集合。</returns>
|
||||||
|
private List<TValue> Fetch()
|
||||||
|
{
|
||||||
|
return _queue.Count <= 0 ? new List<TValue>() : _queue.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收一个不再使用的值集合到空闲值集合队列中。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="list">要回收的值集合。</param>
|
||||||
|
private void Recycle(List<TValue> list)
|
||||||
|
{
|
||||||
|
list.Clear();
|
||||||
|
|
||||||
|
if (_recyclingLimit != 0 && _queue.Count > _recyclingLimit) return;
|
||||||
|
|
||||||
|
_queue.Enqueue(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
72
Tools/ConfigBuilder/NBConfigBuilder/Core/Pool.cs
Normal file
72
Tools/ConfigBuilder/NBConfigBuilder/Core/Pool.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 静态的对象池系统,不支持多线程。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
public static class Pool<T> where T : IPool, new()
|
||||||
|
{
|
||||||
|
private static readonly Queue<T> PoolQueue = new Queue<T>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 池子里可用的数量
|
||||||
|
/// </summary>
|
||||||
|
public static int Count => PoolQueue.Count;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租借
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T Rent()
|
||||||
|
{
|
||||||
|
return PoolQueue.Count == 0 ? new T() : PoolQueue.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租借
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="generator">如果池子里没有,会先执行这个委托。</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T Rent(Func<T> generator)
|
||||||
|
{
|
||||||
|
return PoolQueue.Count == 0 ? generator() : PoolQueue.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返还
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t"></param>
|
||||||
|
public static void Return(T t)
|
||||||
|
{
|
||||||
|
if (t == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolQueue.Enqueue(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 返还
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t">返还的东西</param>
|
||||||
|
/// <param name="reset">返还后执行的委托</param>
|
||||||
|
public static void Return(T t, Action<T> reset)
|
||||||
|
{
|
||||||
|
if (t == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset(t);
|
||||||
|
PoolQueue.Enqueue(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空池子
|
||||||
|
/// </summary>
|
||||||
|
public static void Clear()
|
||||||
|
{
|
||||||
|
PoolQueue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace Fantasy.Serialize;
|
||||||
|
|
||||||
|
public abstract class ASerialize : ISupportInitialize, IDisposable
|
||||||
|
{
|
||||||
|
public virtual void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void BeginInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void EndInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void AfterDeserialization() => EndInit();
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
public sealed partial class StringDictionaryConfig
|
||||||
|
{
|
||||||
|
public Dictionary<int, string> Dic;
|
||||||
|
public string this[int key] => GetValue(key);
|
||||||
|
|
||||||
|
public bool TryGetValue(int key, out string value)
|
||||||
|
{
|
||||||
|
value = default;
|
||||||
|
|
||||||
|
if (!Dic.ContainsKey(key))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = Dic[key];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetValue(int key)
|
||||||
|
{
|
||||||
|
return Dic.TryGetValue(key, out var value) ? value : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using ProtoBuf;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 动态程序集类,用于加载动态生成的程序集并获取动态信息。
|
||||||
|
/// </summary>
|
||||||
|
public static class DynamicAssembly
|
||||||
|
{
|
||||||
|
private static void MetadataReference(out string assemblyName, out List<MetadataReference> metadataReferenceList)
|
||||||
|
{
|
||||||
|
AssemblyMetadata assemblyMetadata;
|
||||||
|
MetadataReference metadataReference;
|
||||||
|
var currentDomain = AppDomain.CurrentDomain;
|
||||||
|
assemblyName = Path.GetRandomFileName();
|
||||||
|
var assemblyArray = currentDomain.GetAssemblies();
|
||||||
|
metadataReferenceList = new List<MetadataReference>();
|
||||||
|
|
||||||
|
// 注册引用
|
||||||
|
|
||||||
|
foreach (var domainAssembly in assemblyArray)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(domainAssembly.Location))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assemblyMetadata = AssemblyMetadata.CreateFromFile(domainAssembly.Location);
|
||||||
|
metadataReference = assemblyMetadata.GetReference();
|
||||||
|
metadataReferenceList.Add(metadataReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加Proto支持
|
||||||
|
|
||||||
|
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ProtoMemberAttribute).Assembly.Location);
|
||||||
|
metadataReference = assemblyMetadata.GetReference();
|
||||||
|
metadataReferenceList.Add(metadataReference);
|
||||||
|
|
||||||
|
// 添加Fantasy支持
|
||||||
|
|
||||||
|
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ASerialize).Assembly.Location);
|
||||||
|
metadataReference = assemblyMetadata.GetReference();
|
||||||
|
metadataReferenceList.Add(metadataReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载指定路径下的动态程序集。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">程序集文件路径。</param>
|
||||||
|
/// <returns>加载的动态程序集。</returns>
|
||||||
|
public static Assembly Load(string path)
|
||||||
|
{
|
||||||
|
var fileList = new List<string>();
|
||||||
|
|
||||||
|
// 找到所有需要加载的CS文件
|
||||||
|
|
||||||
|
foreach (string file in Directory.GetFiles(path))
|
||||||
|
{
|
||||||
|
if (Path.GetExtension(file) != ".cs")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileList.Add(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
var syntaxTreeList = new List<SyntaxTree>();
|
||||||
|
|
||||||
|
foreach (var file in fileList)
|
||||||
|
{
|
||||||
|
using var fileStream = new StreamReader(file);
|
||||||
|
var cSharp = CSharpSyntaxTree.ParseText(fileStream.ReadToEnd());
|
||||||
|
syntaxTreeList.Add(cSharp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册程序集
|
||||||
|
MetadataReference(out var assemblyName, out var metadataReferenceList);
|
||||||
|
var compilation = CSharpCompilation.Create(assemblyName, syntaxTreeList, metadataReferenceList, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
var result = compilation.Emit(ms);
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
foreach (var resultDiagnostic in result.Diagnostics)
|
||||||
|
{
|
||||||
|
Log.Error(resultDiagnostic.GetMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("failures");
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
return Assembly.Load(ms.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取动态程序集中指定表格的动态信息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dynamicAssembly">动态程序集。</param>
|
||||||
|
/// <param name="tableName">表格名称。</param>
|
||||||
|
/// <returns>动态信息对象。</returns>
|
||||||
|
public static DynamicConfigDataType GetDynamicInfo(Assembly dynamicAssembly, string tableName)
|
||||||
|
{
|
||||||
|
var dynamicConfigDataType = new DynamicConfigDataType
|
||||||
|
{
|
||||||
|
ConfigDataType = GetConfigType(dynamicAssembly, $"{tableName}Data"),
|
||||||
|
ConfigType = GetConfigType(dynamicAssembly, $"{tableName}")
|
||||||
|
};
|
||||||
|
|
||||||
|
dynamicConfigDataType.ConfigData = CreateInstance(dynamicConfigDataType.ConfigDataType);
|
||||||
|
|
||||||
|
var listPropertyType = dynamicConfigDataType.ConfigDataType.GetProperty("List");
|
||||||
|
|
||||||
|
if (listPropertyType == null)
|
||||||
|
{
|
||||||
|
throw new Exception("No Property named Add was found");
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamicConfigDataType.Obj = listPropertyType.GetValue(dynamicConfigDataType.ConfigData);
|
||||||
|
dynamicConfigDataType.Method = listPropertyType.PropertyType.GetMethod("Add");
|
||||||
|
|
||||||
|
if (dynamicConfigDataType.Method == null)
|
||||||
|
{
|
||||||
|
throw new Exception("No method named Add was found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return dynamicConfigDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据类型名称获取动态类型。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dynamicAssembly">动态程序集。</param>
|
||||||
|
/// <param name="typeName">类型名称。</param>
|
||||||
|
/// <returns>动态类型。</returns>
|
||||||
|
private static Type GetConfigType(Assembly dynamicAssembly, string typeName)
|
||||||
|
{
|
||||||
|
var configType = dynamicAssembly.GetType($"Fantasy.{typeName}");
|
||||||
|
|
||||||
|
if (configType == null)
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException($"Fantasy.{typeName} not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
return configType;
|
||||||
|
// return dynamicAssembly.GetType($"Fantasy.{typeName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建动态实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="configType">动态类型。</param>
|
||||||
|
/// <returns>动态实例。</returns>
|
||||||
|
public static object CreateInstance(Type configType)
|
||||||
|
{
|
||||||
|
var config = Activator.CreateInstance(configType);
|
||||||
|
|
||||||
|
if (config == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"{configType.Name} is Activator.CreateInstance error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 动态配置数据类型类,用于存储动态配置数据的相关信息。
|
||||||
|
/// </summary>
|
||||||
|
public class DynamicConfigDataType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 配置数据对象,继承自 AProto 基类。
|
||||||
|
/// </summary>
|
||||||
|
public object ConfigData;
|
||||||
|
/// <summary>
|
||||||
|
/// 配置数据类型。
|
||||||
|
/// </summary>
|
||||||
|
public Type ConfigDataType;
|
||||||
|
/// <summary>
|
||||||
|
/// 配置类型。
|
||||||
|
/// </summary>
|
||||||
|
public Type ConfigType;
|
||||||
|
/// <summary>
|
||||||
|
/// 反射方法信息,用于调用特定方法。
|
||||||
|
/// </summary>
|
||||||
|
public MethodInfo Method;
|
||||||
|
/// <summary>
|
||||||
|
/// 配置数据对象实例。
|
||||||
|
/// </summary>
|
||||||
|
public object Obj;
|
||||||
|
/// <summary>
|
||||||
|
/// 用于生成 JSON 格式数据的字符串构建器。
|
||||||
|
/// </summary>
|
||||||
|
public StringBuilder Json = new StringBuilder();
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using ProtoBuf;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
public class OneDynamicAssembly
|
||||||
|
{
|
||||||
|
private readonly List<SyntaxTree> _syntaxTreeList = new List<SyntaxTree>();
|
||||||
|
|
||||||
|
public void Load(string file)
|
||||||
|
{
|
||||||
|
using var fileStream = new StreamReader(file);
|
||||||
|
var cSharp = CSharpSyntaxTree.ParseText(fileStream.ReadToEnd());
|
||||||
|
_syntaxTreeList.Add(cSharp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Assembly Assembly
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
AssemblyMetadata assemblyMetadata;
|
||||||
|
MetadataReference metadataReference;
|
||||||
|
var currentDomain = AppDomain.CurrentDomain;
|
||||||
|
var assemblyName = Path.GetRandomFileName();
|
||||||
|
var assemblyArray = currentDomain.GetAssemblies();
|
||||||
|
var metadataReferenceList = new List<MetadataReference>();
|
||||||
|
// 注册引用
|
||||||
|
foreach (var domainAssembly in assemblyArray)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(domainAssembly.Location))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assemblyMetadata = AssemblyMetadata.CreateFromFile(domainAssembly.Location);
|
||||||
|
metadataReference = assemblyMetadata.GetReference();
|
||||||
|
metadataReferenceList.Add(metadataReference);
|
||||||
|
}
|
||||||
|
// 添加ProtoEntity支持
|
||||||
|
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ASerialize).Assembly.Location);
|
||||||
|
metadataReference = assemblyMetadata.GetReference();
|
||||||
|
metadataReferenceList.Add(metadataReference);
|
||||||
|
// 添加MessagePack支持
|
||||||
|
assemblyMetadata = AssemblyMetadata.CreateFromFile(typeof(ProtoMemberAttribute).Assembly.Location);
|
||||||
|
metadataReference = assemblyMetadata.GetReference();
|
||||||
|
metadataReferenceList.Add(metadataReference);
|
||||||
|
CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, _syntaxTreeList, metadataReferenceList, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
||||||
|
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
var result = compilation.Emit(ms);
|
||||||
|
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
foreach (var resultDiagnostic in result.Diagnostics)
|
||||||
|
{
|
||||||
|
Log.Error(resultDiagnostic.GetMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("failures");
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
return Assembly.Load(ms.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
950
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs
Normal file
950
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelExporter.cs
Normal file
@@ -0,0 +1,950 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Loader;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Microsoft.VisualBasic.ApplicationServices;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using OfficeOpenXml;
|
||||||
|
using static System.String;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
using TableDictionary = SortedDictionary<string, List<int>>;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Excel 数据导出器,用于从 Excel 文件导出数据到二进制格式和生成 C# 类文件。
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ExcelExporter
|
||||||
|
{
|
||||||
|
public ExportType ExportType;
|
||||||
|
private readonly string _excelProgramPath;
|
||||||
|
private readonly string _versionFilePath;
|
||||||
|
|
||||||
|
// private readonly string _excelClientFileDirectory;
|
||||||
|
// private readonly string _excelServerFileDirectory;
|
||||||
|
// private readonly string _excelServerJsonDirectory;
|
||||||
|
// private readonly string _excelClientJsonDirectory;
|
||||||
|
|
||||||
|
public VersionInfo VersionInfo; // 存储 Excel 文件的版本信息。
|
||||||
|
private readonly Regex _regexName = new Regex("^[a-zA-Z][a-zA-Z0-9_]*$"); // 用于验证 Excel 表名的正则表达式。
|
||||||
|
private readonly HashSet<string> _loadFiles = [".xlsx", ".xlsm", ".csv"]; // 加载的支持文件扩展名。
|
||||||
|
|
||||||
|
private readonly OneToManyList<string, ExportInfo>
|
||||||
|
_tables = new OneToManyList<string, ExportInfo>(); // 存储 Excel 表及其导出信息。
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, ExcelTable> _excelTables =
|
||||||
|
new ConcurrentDictionary<string, ExcelTable>(); // 存储解析后的 Excel 表。
|
||||||
|
|
||||||
|
public readonly ConcurrentDictionary<string, ExcelWorksheet> Worksheets =
|
||||||
|
new ConcurrentDictionary<string, ExcelWorksheet>(); // 存储已加载的 Excel 工作表。
|
||||||
|
|
||||||
|
public readonly Dictionary<string, string> IgnoreTable = new Dictionary<string, string>(); // 存储以#开头的的表和路径
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导表支持的数据类型集合。
|
||||||
|
/// </summary>
|
||||||
|
public static readonly HashSet<string> ColTypeSet =
|
||||||
|
[
|
||||||
|
"", "0", "bool", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "string",
|
||||||
|
"IntDictionaryConfig", "StringDictionaryConfig",
|
||||||
|
"short[]", "int[]", "long[]", "float[]", "string[]", "uint[]"
|
||||||
|
];
|
||||||
|
|
||||||
|
static ExcelExporter()
|
||||||
|
{
|
||||||
|
ExcelPackage.License.SetNonCommercialOrganization("Fantasy");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据指定的 exportType 初始化 ExcelExporter 类的新实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exportType">要执行的导出类型(AllExcel 或 AllExcelIncrement)。</param>
|
||||||
|
public ExcelExporter(ExportType exportType)
|
||||||
|
{
|
||||||
|
ExportType = exportType;
|
||||||
|
|
||||||
|
if (App.Config.ExcelVersionPath == null || App.Config.ExcelVersionPath.Trim() == "")
|
||||||
|
{
|
||||||
|
Log.Info($"ExcelVersionFile Can not be empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.ExcelPath == null || App.Config.ExcelPath.Trim() == "")
|
||||||
|
{
|
||||||
|
Log.Info($"ExcelProgramPath Can not be empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_excelProgramPath = FileHelper.GetFullPath(App.Config.ExcelPath);
|
||||||
|
_versionFilePath = FileHelper.GetFullPath(App.Config.ExcelVersionPath);
|
||||||
|
|
||||||
|
if (App.Config.GenClient)
|
||||||
|
{
|
||||||
|
if (App.Config.ClientJsonPath == null ||
|
||||||
|
App.Config.ClientJsonPath.Trim() == "")
|
||||||
|
{
|
||||||
|
Log.Info($"ExcelClientJsonDirectory Can not be empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.ClientPath == null ||
|
||||||
|
App.Config.ClientPath.Trim() == "")
|
||||||
|
{
|
||||||
|
Log.Info($"ExcelServerFileDirectory Can not be empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.GenServer)
|
||||||
|
{
|
||||||
|
if (App.Config.ServerPath == null ||
|
||||||
|
App.Config.ServerPath.Trim() == "")
|
||||||
|
{
|
||||||
|
Log.Info($"ExcelServerFileDirectory Can not be empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.ServerJsonPath == null ||
|
||||||
|
App.Config.ServerJsonPath.Trim() == "")
|
||||||
|
{
|
||||||
|
Log.Info($"ExcelServerJsonDirectory Can not be empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ExportType)
|
||||||
|
{
|
||||||
|
case ExportType.AllExcelIncrement:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ExportType.AllExcel:
|
||||||
|
{
|
||||||
|
if (File.Exists(_versionFilePath))
|
||||||
|
{
|
||||||
|
File.Delete(_versionFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializerManager.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
Find();
|
||||||
|
Parsing();
|
||||||
|
ExportToBinary();
|
||||||
|
File.WriteAllText(_versionFilePath, JsonConvert.SerializeObject(VersionInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找配置文件
|
||||||
|
/// </summary>
|
||||||
|
private void Find()
|
||||||
|
{
|
||||||
|
VersionInfo = File.Exists(_versionFilePath)
|
||||||
|
? JsonConvert.DeserializeObject<VersionInfo>(File.ReadAllText(_versionFilePath))
|
||||||
|
: new VersionInfo();
|
||||||
|
|
||||||
|
var dir = new DirectoryInfo(_excelProgramPath);
|
||||||
|
var excelFiles = dir.GetFiles("*", SearchOption.AllDirectories);
|
||||||
|
|
||||||
|
if (excelFiles.Length <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var excelFile in excelFiles)
|
||||||
|
{
|
||||||
|
// 过滤掉非指定后缀的文件
|
||||||
|
|
||||||
|
if (!_loadFiles.Contains(excelFile.Extension))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastIndexOf = excelFile.Name.LastIndexOf(".", StringComparison.Ordinal);
|
||||||
|
|
||||||
|
if (lastIndexOf < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fullName = excelFile.FullName;
|
||||||
|
var excelName = excelFile.Name.Substring(0, lastIndexOf);
|
||||||
|
var path = fullName.Substring(0, fullName.Length - excelFile.Name.Length);
|
||||||
|
|
||||||
|
// 过滤~开头文件
|
||||||
|
|
||||||
|
if (excelName.StartsWith("~", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果文件名以#开头,那么这个文件夹下的所有文件都不导出
|
||||||
|
|
||||||
|
if (excelName.StartsWith("#", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
IgnoreTable.Add(excelName, fullName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果文件夹名包含#,那么这个文件夹下的所有文件都不导出
|
||||||
|
|
||||||
|
if (path.Contains("#", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_regexName.IsMatch(excelName))
|
||||||
|
{
|
||||||
|
Log.Info($"{excelName} 配置文件名非法");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var exportInfo = new ExportInfo()
|
||||||
|
{
|
||||||
|
Name = excelName, FileInfo = excelFile
|
||||||
|
};
|
||||||
|
|
||||||
|
_tables.Add(excelName.Split('_')[0], exportInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
var removeTables = new List<string>();
|
||||||
|
|
||||||
|
foreach (var (tableName, tableList) in _tables)
|
||||||
|
{
|
||||||
|
var isNeedExport = false;
|
||||||
|
|
||||||
|
foreach (var exportInfo in tableList)
|
||||||
|
{
|
||||||
|
var key = HashCodeHelper.ComputeHash64(exportInfo.Name);
|
||||||
|
var timer = TimeHelper.Transition(exportInfo.FileInfo.LastWriteTime);
|
||||||
|
|
||||||
|
if (!isNeedExport)
|
||||||
|
{
|
||||||
|
if (VersionInfo.Tables.TryGetValue(key, out var lastWriteTime))
|
||||||
|
{
|
||||||
|
isNeedExport = lastWriteTime != timer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isNeedExport = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VersionInfo.Tables[key] = timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNeedExport)
|
||||||
|
{
|
||||||
|
removeTables.Add(tableName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var removeTable in removeTables)
|
||||||
|
{
|
||||||
|
_tables.Remove(removeTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var (_, exportInfo) in _tables)
|
||||||
|
{
|
||||||
|
exportInfo.Sort((x, y) => Compare(x.Name, y.Name, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成配置文件
|
||||||
|
/// </summary>
|
||||||
|
private void Parsing()
|
||||||
|
{
|
||||||
|
var generateTasks = new List<Task>();
|
||||||
|
|
||||||
|
foreach (var (tableName, tableList) in _tables)
|
||||||
|
{
|
||||||
|
var task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
var writeToClassTask = new List<Task>();
|
||||||
|
var excelTable = new ExcelTable(tableName);
|
||||||
|
|
||||||
|
// 筛选需要导出的列
|
||||||
|
foreach (var exportInfo in tableList)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var serverColInfoList = new List<int>();
|
||||||
|
var clientColInfoList = new List<int>();
|
||||||
|
var worksheet = LoadExcel(exportInfo.FileInfo.FullName, true);
|
||||||
|
|
||||||
|
for (var col = 3; col <= worksheet.Columns.EndColumn; col++)
|
||||||
|
{
|
||||||
|
// 列名字第一个字符是#不参与导出
|
||||||
|
|
||||||
|
var colName = worksheet.GetCellValue(5, col);
|
||||||
|
if (colName.StartsWith("#", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数值列不参与导出
|
||||||
|
|
||||||
|
var numericalCol = worksheet.GetCellValue(3, col);
|
||||||
|
if (numericalCol != "" && numericalCol != "0")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var serverType = worksheet.GetCellValue(1, col);
|
||||||
|
var clientType = worksheet.GetCellValue(2, col);
|
||||||
|
var isExportServer = !IsNullOrEmpty(serverType) && serverType != "0";
|
||||||
|
var isExportClient = !IsNullOrEmpty(clientType) && clientType != "0";
|
||||||
|
|
||||||
|
if (!isExportServer && !isExportClient)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isExportServer && isExportClient & serverType != clientType)
|
||||||
|
{
|
||||||
|
Log.Info(
|
||||||
|
$"配置表 {exportInfo.Name} {col} 列 [{colName}] 客户端类型 {clientType} 和 服务端类型 {serverType} 不一致");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ColTypeSet.Contains(serverType) || !ColTypeSet.Contains(clientType))
|
||||||
|
{
|
||||||
|
Log.Info(
|
||||||
|
$"配置表 {exportInfo.Name} {col} 列 [{colName}] 客户端类型 {clientType}, 服务端类型 {serverType} 不合法");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_regexName.IsMatch(colName))
|
||||||
|
{
|
||||||
|
Log.Info($"配置表 {exportInfo.Name} {col} 列 [{colName}] 列名非法");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
serverColInfoList.Add(col);
|
||||||
|
|
||||||
|
if (isExportClient)
|
||||||
|
{
|
||||||
|
clientColInfoList.Add(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientColInfoList.Count > 0)
|
||||||
|
{
|
||||||
|
excelTable.ClientColInfos.Add(exportInfo.FileInfo.FullName, clientColInfoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverColInfoList.Count > 0)
|
||||||
|
{
|
||||||
|
excelTable.ServerColInfos.Add(exportInfo.FileInfo.FullName, serverColInfoList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error($"Config : {tableName}, Name : {exportInfo.Name}, Error : {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成cs文件
|
||||||
|
|
||||||
|
if (App.Config.GenServer)
|
||||||
|
{
|
||||||
|
writeToClassTask.Add(Task.Run(() =>
|
||||||
|
{
|
||||||
|
WriteToClass(excelTable.ServerColInfos, App.Config.ServerPath, true);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.GenClient)
|
||||||
|
{
|
||||||
|
writeToClassTask.Add(Task.Run(() =>
|
||||||
|
{
|
||||||
|
WriteToClass(excelTable.ClientColInfos, App.Config.ClientPath, false);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.WaitAll(writeToClassTask.ToArray());
|
||||||
|
_excelTables.TryAdd(tableName, excelTable);
|
||||||
|
});
|
||||||
|
|
||||||
|
generateTasks.Add(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.WaitAll(generateTasks.ToArray());
|
||||||
|
Console.WriteLine("build success===");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把数据和实体类转换二进制导出到文件中
|
||||||
|
/// </summary>
|
||||||
|
private void ExportToBinary()
|
||||||
|
{
|
||||||
|
System.Reflection.Assembly dynamicServerAssembly = null;
|
||||||
|
System.Reflection.Assembly dynamicClientAssembly = null;
|
||||||
|
var exportToBinaryTasks = new List<Task>();
|
||||||
|
|
||||||
|
if (App.Config.GenServer &&
|
||||||
|
Directory.Exists(App.Config.ServerPath))
|
||||||
|
{
|
||||||
|
dynamicServerAssembly = DynamicAssembly.Load(App.Config.ServerPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.GenClient &&
|
||||||
|
Directory.Exists(App.Config.ClientPath))
|
||||||
|
{
|
||||||
|
dynamicClientAssembly = DynamicAssembly.Load(App.Config.ClientPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var (tableName, tableList) in _tables)
|
||||||
|
{
|
||||||
|
var task = Task.Run(() =>
|
||||||
|
{
|
||||||
|
DynamicConfigDataType serverDynamicInfo = null;
|
||||||
|
DynamicConfigDataType clientDynamicInfo = null;
|
||||||
|
|
||||||
|
var idCheck = new HashSet<string>();
|
||||||
|
var excelTable = _excelTables[tableName];
|
||||||
|
var csName = Path.GetFileNameWithoutExtension(tableName);
|
||||||
|
|
||||||
|
if (App.Config.GenServer)
|
||||||
|
{
|
||||||
|
var serverColInfoCount = excelTable.ServerColInfos.Sum(d => d.Value.Count);
|
||||||
|
serverDynamicInfo = serverColInfoCount == 0
|
||||||
|
? null
|
||||||
|
: DynamicAssembly.GetDynamicInfo(dynamicServerAssembly, csName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.GenClient)
|
||||||
|
{
|
||||||
|
var clientColInfoCount = excelTable.ClientColInfos.Sum(d => d.Value.Count);
|
||||||
|
clientDynamicInfo = clientColInfoCount == 0
|
||||||
|
? null
|
||||||
|
: DynamicAssembly.GetDynamicInfo(dynamicClientAssembly, csName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tableList.Count; i++)
|
||||||
|
{
|
||||||
|
var tableListName = tableList[i];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fileInfoFullName = tableListName.FileInfo.FullName;
|
||||||
|
var excelWorksheet = LoadExcel(fileInfoFullName, false);
|
||||||
|
var rows = excelWorksheet.Dimension.Rows;
|
||||||
|
excelTable.ServerColInfos.TryGetValue(fileInfoFullName, out var serverCols);
|
||||||
|
excelTable.ClientColInfos.TryGetValue(fileInfoFullName, out var clientCols);
|
||||||
|
|
||||||
|
for (var row = 7; row <= rows; row++)
|
||||||
|
{
|
||||||
|
if (excelWorksheet.GetCellValue(row, 1).StartsWith("#", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = excelWorksheet.GetCellValue(row, 3);
|
||||||
|
|
||||||
|
if (idCheck.Contains(id))
|
||||||
|
{
|
||||||
|
Log.Info($"{tableListName.Name} 存在重复Id {id} 行号 {row}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
idCheck.Add(id);
|
||||||
|
var isLast = row == rows && (i == tableList.Count - 1);
|
||||||
|
|
||||||
|
if (App.Config.GenServer)
|
||||||
|
{
|
||||||
|
GenerateBinary(fileInfoFullName, excelWorksheet, serverDynamicInfo, serverCols, id, row,
|
||||||
|
isLast, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (App.Config.GenClient)
|
||||||
|
{
|
||||||
|
GenerateBinary(fileInfoFullName, excelWorksheet, clientDynamicInfo, clientCols, id, row,
|
||||||
|
isLast, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error($"Table:{tableListName} error! \n{e}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverDynamicInfo?.ConfigData != null)
|
||||||
|
{
|
||||||
|
// var memoryStream = new MemoryStreamBuffer();
|
||||||
|
// SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf)
|
||||||
|
// .Serialize(serverDynamicInfo.ConfigData, memoryStream);
|
||||||
|
// if (!Directory.Exists(_excelServerBinaryDirectory))
|
||||||
|
// {
|
||||||
|
// Directory.CreateDirectory(_excelServerBinaryDirectory);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var asSpan = memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position);
|
||||||
|
// File.WriteAllBytes(Path.Combine(_excelServerBinaryDirectory, $"{csName}Data.bytes"),
|
||||||
|
// asSpan.ToArray());
|
||||||
|
|
||||||
|
if (serverDynamicInfo.Json.Length > 0)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(App.Config.ServerJsonPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(App.Config.ServerJsonPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var sw = new StreamWriter(Path.Combine(App.Config.ServerJsonPath, $"{csName}Data.Json"));
|
||||||
|
sw.WriteLine("{\"List\":[");
|
||||||
|
sw.Write(serverDynamicInfo.Json.ToString());
|
||||||
|
sw.WriteLine("]}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientDynamicInfo?.ConfigData != null)
|
||||||
|
{
|
||||||
|
// var memoryStream = new MemoryStreamBuffer();
|
||||||
|
// SerializerManager.GetSerializer(FantasySerializerType.ProtoBuf)
|
||||||
|
// .Serialize(clientDynamicInfo.ConfigData, memoryStream);
|
||||||
|
// if (!Directory.Exists(_excelClientBinaryDirectory))
|
||||||
|
// {
|
||||||
|
// Directory.CreateDirectory(_excelClientBinaryDirectory);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// var asSpan = memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Position);
|
||||||
|
// File.WriteAllBytes(Path.Combine(_excelClientBinaryDirectory, $"{csName}Data.bytes"),
|
||||||
|
// asSpan.ToArray());
|
||||||
|
|
||||||
|
if (clientDynamicInfo.Json.Length > 0)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(App.Config.ClientJsonPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(App.Config.ClientJsonPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var sw = new StreamWriter(Path.Combine(App.Config.ClientJsonPath, $"{csName}Data.Json"));
|
||||||
|
sw.WriteLine("{\"List\":[");
|
||||||
|
sw.Write(clientDynamicInfo.Json.ToString());
|
||||||
|
sw.WriteLine("]}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
exportToBinaryTasks.Add(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
Task.WaitAll(exportToBinaryTasks.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenerateBinary(string fileInfoFullName, ExcelWorksheet excelWorksheet,
|
||||||
|
DynamicConfigDataType dynamicInfo, List<int> cols, string id, int row, bool isLast, bool isServer)
|
||||||
|
{
|
||||||
|
if (cols == null || IsNullOrEmpty(id) || cols.Count <= 0 || dynamicInfo?.ConfigType == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = DynamicAssembly.CreateInstance(dynamicInfo.ConfigType);
|
||||||
|
|
||||||
|
for (var i = 0; i < cols.Count; i++)
|
||||||
|
{
|
||||||
|
string colType;
|
||||||
|
var colIndex = cols[i];
|
||||||
|
var colName = excelWorksheet.GetCellValue(5, colIndex);
|
||||||
|
var value = excelWorksheet.GetCellValue(row, colIndex);
|
||||||
|
|
||||||
|
if (isServer)
|
||||||
|
{
|
||||||
|
colType = excelWorksheet.GetCellValue(1, colIndex);
|
||||||
|
|
||||||
|
if (IsNullOrEmpty(colType) || colType == "0")
|
||||||
|
{
|
||||||
|
colType = excelWorksheet.GetCellValue(2, colIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colType = excelWorksheet.GetCellValue(2, colIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SetNewValue(dynamicInfo.ConfigType.GetProperty(colName), config, colType, value);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(
|
||||||
|
$"Error Table {fileInfoFullName} Col:{colName} colType:{colType} Row:{row} value:{value} {e}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamicInfo.Method.Invoke(dynamicInfo.Obj, new object[] { config });
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeObject(config);
|
||||||
|
|
||||||
|
if (isLast)
|
||||||
|
{
|
||||||
|
dynamicInfo.Json.AppendLine(json);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dynamicInfo.Json.AppendLine($"{json},");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从 Excel 文件加载工作表并返回 ExcelWorksheet 对象。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">工作表的名称或文件路径。</param>
|
||||||
|
/// <param name="isAddToDic">是否将加载的工作表添加到缓存字典中。</param>
|
||||||
|
/// <returns>表示 Excel 工作表的 ExcelWorksheet 对象。</returns>
|
||||||
|
public ExcelWorksheet LoadExcel(string name, bool isAddToDic)
|
||||||
|
{
|
||||||
|
if (Worksheets.TryGetValue(name, out var worksheet))
|
||||||
|
{
|
||||||
|
return worksheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
var workbookWorksheets = ExcelHelper.LoadExcel(name).Workbook.Worksheets;
|
||||||
|
worksheet = workbookWorksheets[0];
|
||||||
|
|
||||||
|
if (isAddToDic)
|
||||||
|
{
|
||||||
|
Worksheets.TryAdd(name, worksheet);
|
||||||
|
|
||||||
|
foreach (var workbookWorksheet in workbookWorksheets)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var hash = HashCodeHelper.ComputeHash64(workbookWorksheet.Name);
|
||||||
|
VersionInfo.WorksheetNames.Add(hash);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Worksheets.TryAdd(workbookWorksheet.Name, workbookWorksheet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Info(name);
|
||||||
|
return workbookWorksheets[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写入到cs
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="colInfos"></param>
|
||||||
|
/// <param name="exportPath"></param>
|
||||||
|
/// <param name="isServer"></param>
|
||||||
|
private void WriteToClass(TableDictionary colInfos, string exportPath, bool isServer)
|
||||||
|
{
|
||||||
|
if (colInfos.Count <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
var fileBuilder = new StringBuilder();
|
||||||
|
var colNameSet = new HashSet<string>();
|
||||||
|
|
||||||
|
if (colInfos.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var csName = Path.GetFileNameWithoutExtension(colInfos.First().Key)?.Split('_')[0];
|
||||||
|
|
||||||
|
foreach (var (tableName, cols) in colInfos)
|
||||||
|
{
|
||||||
|
if (cols == null || cols.Count == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var excelWorksheet = LoadExcel(tableName, false);
|
||||||
|
|
||||||
|
foreach (var colIndex in cols)
|
||||||
|
{
|
||||||
|
var colName = excelWorksheet.GetCellValue(5, colIndex);
|
||||||
|
|
||||||
|
if (colNameSet.Contains(colName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
colNameSet.Add(colName);
|
||||||
|
|
||||||
|
string colType;
|
||||||
|
|
||||||
|
if (isServer)
|
||||||
|
{
|
||||||
|
colType = excelWorksheet.GetCellValue(1, colIndex);
|
||||||
|
|
||||||
|
if (IsNullOrEmpty(colType) || colType == "0")
|
||||||
|
{
|
||||||
|
colType = excelWorksheet.GetCellValue(2, colIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colType = excelWorksheet.GetCellValue(2, colIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
var remarks = excelWorksheet.GetCellValue(4, colIndex);
|
||||||
|
|
||||||
|
// 解决不同平台换行符不一致的问题
|
||||||
|
|
||||||
|
switch (Environment.OSVersion.Platform)
|
||||||
|
{
|
||||||
|
case PlatformID.Win32NT:
|
||||||
|
case PlatformID.Win32S:
|
||||||
|
case PlatformID.Win32Windows:
|
||||||
|
case PlatformID.WinCE:
|
||||||
|
{
|
||||||
|
fileBuilder.Append($"\r\n\t\t[ProtoMember({++index})]\r\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
fileBuilder.Append($"\n\t\t[ProtoMember({++index})]\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileBuilder.Append(
|
||||||
|
IsArray(colType, out var t)
|
||||||
|
? $"\t\tpublic {colType} {colName} {{ get; set; }} = Array.Empty<{t}>(); // {remarks}"
|
||||||
|
: $"\t\tpublic {colType} {colName} {{ get; set; }} // {remarks}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var template = ExcelTemplate.Template;
|
||||||
|
|
||||||
|
if (fileBuilder.Length > 0)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(exportPath))
|
||||||
|
{
|
||||||
|
FileHelper.CreateDirectory(exportPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
var content = template.Replace("(namespace)", "Fantasy")
|
||||||
|
.Replace("(ConfigName)", csName)
|
||||||
|
.Replace("(Fields)", fileBuilder.ToString());
|
||||||
|
File.WriteAllText(Path.Combine(exportPath, $"{csName}.cs"), content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetNewValue(PropertyInfo propertyInfo, object config, string type, string value)
|
||||||
|
{
|
||||||
|
if (IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case "short":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToInt16(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "ushort":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToUInt16(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "uint":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToUInt32(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "int":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToInt32(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "decimal":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToDecimal(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "string":
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, value);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "bool":
|
||||||
|
{
|
||||||
|
// 空字符串
|
||||||
|
|
||||||
|
value = value.ToLower();
|
||||||
|
|
||||||
|
if (IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, false);
|
||||||
|
}
|
||||||
|
else if (bool.TryParse(value, out bool b))
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, b);
|
||||||
|
}
|
||||||
|
else if (int.TryParse(value, out int v))
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, v != 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "ulong":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToUInt64(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "long":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToInt64(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "double":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToDouble(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "float":
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, Convert.ToSingle(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "int32[]":
|
||||||
|
case "int[]":
|
||||||
|
{
|
||||||
|
if (value != "0")
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToInt32(d)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "uint[]":
|
||||||
|
{
|
||||||
|
if (value != "0")
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToUInt32(d)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "long[]":
|
||||||
|
{
|
||||||
|
if (value != "0")
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToInt64(d)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "double[]":
|
||||||
|
{
|
||||||
|
if (value != "0")
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToDouble(d)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "string[]":
|
||||||
|
{
|
||||||
|
if (value == "0")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var list = value.Split(",").ToArray();
|
||||||
|
|
||||||
|
for (var i = 0; i < list.Length; i++)
|
||||||
|
{
|
||||||
|
list[i] = list[i].Replace("\"", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
propertyInfo.SetValue(config, value.Split(",").ToArray());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "float[]":
|
||||||
|
{
|
||||||
|
if (value != "0")
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, value.Split(",").Select(d => Convert.ToSingle(d)).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "IntDictionaryConfig":
|
||||||
|
{
|
||||||
|
if (value.Trim() == "" || value.Trim() == "{}")
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var attr = new IntDictionaryConfig { Dic = JsonConvert.DeserializeObject<Dictionary<int, int>>(value) };
|
||||||
|
|
||||||
|
propertyInfo.SetValue(config, attr);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case "StringDictionaryConfig":
|
||||||
|
{
|
||||||
|
if (value.Trim() == "" || value.Trim() == "{}")
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(config, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var attr = new StringDictionaryConfig
|
||||||
|
{ Dic = JsonConvert.DeserializeObject<Dictionary<int, string>>(value) };
|
||||||
|
|
||||||
|
propertyInfo.SetValue(config, attr);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"不支持此类型: {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsArray(string type, out string t)
|
||||||
|
{
|
||||||
|
t = null;
|
||||||
|
var index = type.IndexOf("[]", StringComparison.Ordinal);
|
||||||
|
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
t = type.Remove(index, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return index >= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelHelper.cs
Normal file
47
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelHelper.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using OfficeOpenXml;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供操作 Excel 文件的辅助方法。
|
||||||
|
/// </summary>
|
||||||
|
public static class ExcelHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 加载 Excel 文件并返回 ExcelPackage 实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Excel 文件的路径。</param>
|
||||||
|
/// <returns>ExcelPackage 实例。</returns>
|
||||||
|
public static ExcelPackage LoadExcel(string name)
|
||||||
|
{
|
||||||
|
return new ExcelPackage(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定工作表中指定行列位置的单元格值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sheet">Excel 工作表。</param>
|
||||||
|
/// <param name="row">行索引。</param>
|
||||||
|
/// <param name="column">列索引。</param>
|
||||||
|
/// <returns>单元格值。</returns>
|
||||||
|
public static string GetCellValue(this ExcelWorksheet sheet, int row, int column)
|
||||||
|
{
|
||||||
|
ExcelRange cell = sheet.Cells[row, column];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (cell.Value == null)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string s = cell.GetValue<string>();
|
||||||
|
|
||||||
|
return s.Trim();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new Exception($"Rows {row} Columns {column} Content {cell.Text} {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs
Normal file
28
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExcelTable.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Excel表格类,用于存储表格的名称和列信息。
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ExcelTable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表格的名称。
|
||||||
|
/// </summary>
|
||||||
|
public readonly string Name;
|
||||||
|
/// <summary>
|
||||||
|
/// 客户端列信息,使用排序字典存储列名和列索引列表。
|
||||||
|
/// </summary>
|
||||||
|
public readonly SortedDictionary<string, List<int>> ClientColInfos = new();
|
||||||
|
/// <summary>
|
||||||
|
/// 服务器端列信息,使用排序字典存储列名和列索引列表。
|
||||||
|
/// </summary>
|
||||||
|
public readonly SortedDictionary<string, List<int>> ServerColInfos = new();
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,初始化Excel表格对象并设置表格名称。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">表格名称。</param>
|
||||||
|
public ExcelTable(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
public static class ExcelTemplate
|
||||||
|
{
|
||||||
|
public static readonly string Template = """
|
||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
using Fantasy;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using Fantasy.ConfigTable;
|
||||||
|
using Fantasy.Serialize;
|
||||||
|
// ReSharper disable CollectionNeverUpdated.Global
|
||||||
|
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||||
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
#pragma warning disable CS0169
|
||||||
|
#pragma warning disable CS8618
|
||||||
|
#pragma warning disable CS8625
|
||||||
|
#pragma warning disable CS8603
|
||||||
|
|
||||||
|
namespace (namespace)
|
||||||
|
{
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class (ConfigName)Data : ASerialize, IConfigTable, IProto
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public List<(ConfigName)> List { get; set; } = new List<(ConfigName)>();
|
||||||
|
#if FANTASY_NET
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly ConcurrentDictionary<uint, (ConfigName)> _configs = new ConcurrentDictionary<uint, (ConfigName)>();
|
||||||
|
#else
|
||||||
|
[ProtoIgnore]
|
||||||
|
private readonly Dictionary<uint, (ConfigName)> _configs = new Dictionary<uint, (ConfigName)>();
|
||||||
|
#endif
|
||||||
|
private static (ConfigName)Data _instance = null;
|
||||||
|
|
||||||
|
public static (ConfigName)Data Instance
|
||||||
|
{
|
||||||
|
get { return _instance ??= ConfigTableHelper.Load<(ConfigName)Data>(); }
|
||||||
|
private set => _instance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (ConfigName) Get(uint id, bool check = true)
|
||||||
|
{
|
||||||
|
if (_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _configs[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check)
|
||||||
|
{
|
||||||
|
throw new Exception($"(ConfigName) not find {id} Id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public bool TryGet(uint id, out (ConfigName) config)
|
||||||
|
{
|
||||||
|
config = null;
|
||||||
|
|
||||||
|
if (!_configs.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config = _configs[id];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override void AfterDeserialization()
|
||||||
|
{
|
||||||
|
foreach (var config in List)
|
||||||
|
{
|
||||||
|
#if FANTASY_NET
|
||||||
|
_configs.TryAdd(config.Id, config);
|
||||||
|
#else
|
||||||
|
_configs.Add(config.Id, config);
|
||||||
|
#endif
|
||||||
|
config.AfterDeserialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public sealed partial class (ConfigName) : ASerialize, IProto
|
||||||
|
{(Fields)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using OfficeOpenXml;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
public sealed class ExcelWorksheets(ExcelExporter excelExporter)
|
||||||
|
{
|
||||||
|
public bool TryGetValue(string worksheetName, out ExcelWorksheet excelWorksheet)
|
||||||
|
{
|
||||||
|
if (excelExporter.Worksheets.TryGetValue(worksheetName, out excelWorksheet))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var computeHash64 = HashCodeHelper.ComputeHash64(worksheetName);
|
||||||
|
if (!excelExporter.VersionInfo.WorksheetNames.Contains(computeHash64))
|
||||||
|
{
|
||||||
|
Log.Info($"{worksheetName} is not exist!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportInfo.cs
Normal file
17
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportInfo.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导出信息类,用于存储导出操作的名称和文件信息。
|
||||||
|
/// </summary>
|
||||||
|
public class ExportInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 导出操作的名称。
|
||||||
|
/// </summary>
|
||||||
|
public string Name;
|
||||||
|
/// <summary>
|
||||||
|
/// 导出操作生成的文件信息。
|
||||||
|
/// </summary>
|
||||||
|
public FileInfo FileInfo;
|
||||||
|
}
|
||||||
24
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportType.cs
Normal file
24
Tools/ConfigBuilder/NBConfigBuilder/Exporter/ExportType.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导出类型枚举,用于标识不同类型的导出操作。
|
||||||
|
/// </summary>
|
||||||
|
public enum ExportType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 无导出类型。
|
||||||
|
/// </summary>
|
||||||
|
None = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// 所有数据的增量导出Excel类型。
|
||||||
|
/// </summary>
|
||||||
|
AllExcelIncrement = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// 所有数据的全量导出Excel类型。
|
||||||
|
/// </summary>
|
||||||
|
AllExcel = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// 导出类型枚举的最大值,一定要放在最后。
|
||||||
|
/// </summary>
|
||||||
|
Max,
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
public class VersionInfo
|
||||||
|
{
|
||||||
|
public SortedSet<long> WorksheetNames = [];
|
||||||
|
public SortedDictionary<long, long> Tables = new();
|
||||||
|
}
|
||||||
265
Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs
generated
Normal file
265
Tools/ConfigBuilder/NBConfigBuilder/Form1.Designer.cs
generated
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
namespace NBConfigBuilder
|
||||||
|
{
|
||||||
|
partial class Form1
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
textBoxExcelPath = new TextBox();
|
||||||
|
buttonSelectExcelPath = new Button();
|
||||||
|
label1 = new Label();
|
||||||
|
textBoxClientGenPath = new TextBox();
|
||||||
|
buttonSelectClientPath = new Button();
|
||||||
|
checkBoxGenClient = new CheckBox();
|
||||||
|
label2 = new Label();
|
||||||
|
textBoxServerGenPath = new TextBox();
|
||||||
|
label3 = new Label();
|
||||||
|
checkBoxGenServer = new CheckBox();
|
||||||
|
buttonSelectServerPath = new Button();
|
||||||
|
buttonRun = new Button();
|
||||||
|
textBoxClientGenJsonPath = new TextBox();
|
||||||
|
label4 = new Label();
|
||||||
|
buttonSelectClientJsonPath = new Button();
|
||||||
|
textBoxServerGenJsonPath = new TextBox();
|
||||||
|
label5 = new Label();
|
||||||
|
buttonSelectServerJsonPath = new Button();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// textBoxExcelPath
|
||||||
|
//
|
||||||
|
textBoxExcelPath.Location = new Point(84, 13);
|
||||||
|
textBoxExcelPath.Name = "textBoxExcelPath";
|
||||||
|
textBoxExcelPath.Size = new Size(322, 23);
|
||||||
|
textBoxExcelPath.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// buttonSelectExcelPath
|
||||||
|
//
|
||||||
|
buttonSelectExcelPath.Location = new Point(412, 13);
|
||||||
|
buttonSelectExcelPath.Name = "buttonSelectExcelPath";
|
||||||
|
buttonSelectExcelPath.Size = new Size(75, 23);
|
||||||
|
buttonSelectExcelPath.TabIndex = 1;
|
||||||
|
buttonSelectExcelPath.Text = "选择";
|
||||||
|
buttonSelectExcelPath.UseVisualStyleBackColor = true;
|
||||||
|
buttonSelectExcelPath.Click += buttonSelectExcelPath_Click;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(7, 17);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(68, 17);
|
||||||
|
label1.TabIndex = 2;
|
||||||
|
label1.Text = "配置表路径";
|
||||||
|
//
|
||||||
|
// textBoxClientGenPath
|
||||||
|
//
|
||||||
|
textBoxClientGenPath.Location = new Point(84, 42);
|
||||||
|
textBoxClientGenPath.Name = "textBoxClientGenPath";
|
||||||
|
textBoxClientGenPath.Size = new Size(318, 23);
|
||||||
|
textBoxClientGenPath.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// buttonSelectClientPath
|
||||||
|
//
|
||||||
|
buttonSelectClientPath.Location = new Point(412, 42);
|
||||||
|
buttonSelectClientPath.Name = "buttonSelectClientPath";
|
||||||
|
buttonSelectClientPath.Size = new Size(75, 23);
|
||||||
|
buttonSelectClientPath.TabIndex = 4;
|
||||||
|
buttonSelectClientPath.Text = "选择";
|
||||||
|
buttonSelectClientPath.UseVisualStyleBackColor = true;
|
||||||
|
buttonSelectClientPath.Click += buttonSelectClientPath_Click;
|
||||||
|
//
|
||||||
|
// checkBoxGenClient
|
||||||
|
//
|
||||||
|
checkBoxGenClient.AutoSize = true;
|
||||||
|
checkBoxGenClient.Checked = true;
|
||||||
|
checkBoxGenClient.CheckState = CheckState.Checked;
|
||||||
|
checkBoxGenClient.Location = new Point(495, 44);
|
||||||
|
checkBoxGenClient.Name = "checkBoxGenClient";
|
||||||
|
checkBoxGenClient.Size = new Size(87, 21);
|
||||||
|
checkBoxGenClient.TabIndex = 5;
|
||||||
|
checkBoxGenClient.Text = "生产服务端";
|
||||||
|
checkBoxGenClient.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.AutoSize = true;
|
||||||
|
label2.Location = new Point(7, 47);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(68, 17);
|
||||||
|
label2.TabIndex = 6;
|
||||||
|
label2.Text = "客户端代码";
|
||||||
|
//
|
||||||
|
// textBoxServerGenPath
|
||||||
|
//
|
||||||
|
textBoxServerGenPath.Location = new Point(84, 100);
|
||||||
|
textBoxServerGenPath.Name = "textBoxServerGenPath";
|
||||||
|
textBoxServerGenPath.Size = new Size(318, 23);
|
||||||
|
textBoxServerGenPath.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
label3.AutoSize = true;
|
||||||
|
label3.Location = new Point(7, 103);
|
||||||
|
label3.Name = "label3";
|
||||||
|
label3.Size = new Size(68, 17);
|
||||||
|
label3.TabIndex = 8;
|
||||||
|
label3.Text = "服务端代码";
|
||||||
|
//
|
||||||
|
// checkBoxGenServer
|
||||||
|
//
|
||||||
|
checkBoxGenServer.AutoSize = true;
|
||||||
|
checkBoxGenServer.Checked = true;
|
||||||
|
checkBoxGenServer.CheckState = CheckState.Checked;
|
||||||
|
checkBoxGenServer.Location = new Point(495, 16);
|
||||||
|
checkBoxGenServer.Name = "checkBoxGenServer";
|
||||||
|
checkBoxGenServer.Size = new Size(87, 21);
|
||||||
|
checkBoxGenServer.TabIndex = 9;
|
||||||
|
checkBoxGenServer.Text = "生产客户端";
|
||||||
|
checkBoxGenServer.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// buttonSelectServerPath
|
||||||
|
//
|
||||||
|
buttonSelectServerPath.Location = new Point(412, 100);
|
||||||
|
buttonSelectServerPath.Name = "buttonSelectServerPath";
|
||||||
|
buttonSelectServerPath.Size = new Size(75, 23);
|
||||||
|
buttonSelectServerPath.TabIndex = 10;
|
||||||
|
buttonSelectServerPath.Text = "选择";
|
||||||
|
buttonSelectServerPath.UseVisualStyleBackColor = true;
|
||||||
|
buttonSelectServerPath.Click += buttonSelectServerPath_Click;
|
||||||
|
//
|
||||||
|
// buttonRun
|
||||||
|
//
|
||||||
|
buttonRun.Location = new Point(495, 71);
|
||||||
|
buttonRun.Name = "buttonRun";
|
||||||
|
buttonRun.Size = new Size(80, 81);
|
||||||
|
buttonRun.TabIndex = 12;
|
||||||
|
buttonRun.Text = "执行";
|
||||||
|
buttonRun.UseVisualStyleBackColor = true;
|
||||||
|
buttonRun.Click += buttonRun_Click;
|
||||||
|
//
|
||||||
|
// textBoxClientGenJsonPath
|
||||||
|
//
|
||||||
|
textBoxClientGenJsonPath.Location = new Point(84, 71);
|
||||||
|
textBoxClientGenJsonPath.Name = "textBoxClientGenJsonPath";
|
||||||
|
textBoxClientGenJsonPath.Size = new Size(318, 23);
|
||||||
|
textBoxClientGenJsonPath.TabIndex = 13;
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
label4.AutoSize = true;
|
||||||
|
label4.Location = new Point(7, 77);
|
||||||
|
label4.Name = "label4";
|
||||||
|
label4.Size = new Size(68, 17);
|
||||||
|
label4.TabIndex = 14;
|
||||||
|
label4.Text = "客户端配置";
|
||||||
|
//
|
||||||
|
// buttonSelectClientJsonPath
|
||||||
|
//
|
||||||
|
buttonSelectClientJsonPath.Location = new Point(412, 71);
|
||||||
|
buttonSelectClientJsonPath.Name = "buttonSelectClientJsonPath";
|
||||||
|
buttonSelectClientJsonPath.Size = new Size(75, 23);
|
||||||
|
buttonSelectClientJsonPath.TabIndex = 15;
|
||||||
|
buttonSelectClientJsonPath.Text = "选择";
|
||||||
|
buttonSelectClientJsonPath.UseVisualStyleBackColor = true;
|
||||||
|
buttonSelectClientJsonPath.Click += buttonSelectClientJsonPath_Click;
|
||||||
|
//
|
||||||
|
// textBoxServerGenJsonPath
|
||||||
|
//
|
||||||
|
textBoxServerGenJsonPath.Location = new Point(85, 129);
|
||||||
|
textBoxServerGenJsonPath.Name = "textBoxServerGenJsonPath";
|
||||||
|
textBoxServerGenJsonPath.Size = new Size(317, 23);
|
||||||
|
textBoxServerGenJsonPath.TabIndex = 16;
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
label5.AutoSize = true;
|
||||||
|
label5.Location = new Point(7, 132);
|
||||||
|
label5.Name = "label5";
|
||||||
|
label5.Size = new Size(68, 17);
|
||||||
|
label5.TabIndex = 17;
|
||||||
|
label5.Text = "服务端配置";
|
||||||
|
//
|
||||||
|
// buttonSelectServerJsonPath
|
||||||
|
//
|
||||||
|
buttonSelectServerJsonPath.Location = new Point(412, 129);
|
||||||
|
buttonSelectServerJsonPath.Name = "buttonSelectServerJsonPath";
|
||||||
|
buttonSelectServerJsonPath.Size = new Size(75, 23);
|
||||||
|
buttonSelectServerJsonPath.TabIndex = 18;
|
||||||
|
buttonSelectServerJsonPath.Text = "选择";
|
||||||
|
buttonSelectServerJsonPath.UseVisualStyleBackColor = true;
|
||||||
|
buttonSelectServerJsonPath.Click += buttonSelectServerJsonPath_Click;
|
||||||
|
//
|
||||||
|
// Form1
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 17F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(585, 161);
|
||||||
|
Controls.Add(buttonSelectServerJsonPath);
|
||||||
|
Controls.Add(label5);
|
||||||
|
Controls.Add(textBoxServerGenJsonPath);
|
||||||
|
Controls.Add(buttonSelectClientJsonPath);
|
||||||
|
Controls.Add(label4);
|
||||||
|
Controls.Add(textBoxClientGenJsonPath);
|
||||||
|
Controls.Add(buttonRun);
|
||||||
|
Controls.Add(buttonSelectServerPath);
|
||||||
|
Controls.Add(checkBoxGenServer);
|
||||||
|
Controls.Add(label3);
|
||||||
|
Controls.Add(textBoxServerGenPath);
|
||||||
|
Controls.Add(label2);
|
||||||
|
Controls.Add(checkBoxGenClient);
|
||||||
|
Controls.Add(buttonSelectClientPath);
|
||||||
|
Controls.Add(textBoxClientGenPath);
|
||||||
|
Controls.Add(label1);
|
||||||
|
Controls.Add(buttonSelectExcelPath);
|
||||||
|
Controls.Add(textBoxExcelPath);
|
||||||
|
Name = "Form1";
|
||||||
|
Text = "配置生成导出";
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private TextBox textBoxExcelPath;
|
||||||
|
private Button buttonSelectExcelPath;
|
||||||
|
private Label label1;
|
||||||
|
private TextBox textBoxClientGenPath;
|
||||||
|
private Button buttonSelectClientPath;
|
||||||
|
private CheckBox checkBoxGenClient;
|
||||||
|
private Label label2;
|
||||||
|
private TextBox textBoxServerGenPath;
|
||||||
|
private Label label3;
|
||||||
|
private CheckBox checkBoxGenServer;
|
||||||
|
private Button buttonSelectServerPath;
|
||||||
|
private Button buttonRun;
|
||||||
|
private TextBox textBoxClientGenJsonPath;
|
||||||
|
private Label label4;
|
||||||
|
private Button buttonSelectClientJsonPath;
|
||||||
|
private TextBox textBoxServerGenJsonPath;
|
||||||
|
private Label label5;
|
||||||
|
private Button buttonSelectServerJsonPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
141
Tools/ConfigBuilder/NBConfigBuilder/Form1.cs
Normal file
141
Tools/ConfigBuilder/NBConfigBuilder/Form1.cs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder
|
||||||
|
{
|
||||||
|
public partial class Form1 : Form
|
||||||
|
{
|
||||||
|
// 配置文件路径
|
||||||
|
private readonly string configPath =
|
||||||
|
Path.Combine(Path.GetDirectoryName(Application.ExecutablePath) ?? string.Empty, "config.json");
|
||||||
|
|
||||||
|
public Form1()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
// 设置窗口大小不可变
|
||||||
|
this.FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
|
||||||
|
// 加载保存的配置
|
||||||
|
LoadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonRun_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// 保存当前配置
|
||||||
|
SaveConfig();
|
||||||
|
new ExcelExporter(ExportType.AllExcel).Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonSelectExcelPath_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (FolderBrowserDialog folderDlg = new FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
folderDlg.Description = "请选择配置表路径";
|
||||||
|
if (folderDlg.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
textBoxExcelPath.Text = folderDlg.SelectedPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonSelectClientJsonPath_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (FolderBrowserDialog folderDlg = new FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
folderDlg.Description = @"选择客户端json保存目录";
|
||||||
|
if (folderDlg.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
textBoxClientGenJsonPath.Text = folderDlg.SelectedPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonSelectServerJsonPath_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (FolderBrowserDialog folderDlg = new FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
folderDlg.Description = @"选择服务端json保存目录";
|
||||||
|
if (folderDlg.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
textBoxServerGenJsonPath.Text = folderDlg.SelectedPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonSelectClientPath_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (FolderBrowserDialog folderDlg = new FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
folderDlg.Description = @"选择客户端代码保存目录";
|
||||||
|
if (folderDlg.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
textBoxClientGenPath.Text = folderDlg.SelectedPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonSelectServerPath_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
using (FolderBrowserDialog folderDlg = new FolderBrowserDialog())
|
||||||
|
{
|
||||||
|
folderDlg.Description = @"选择服务端代码保存目录";
|
||||||
|
if (folderDlg.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
textBoxServerGenPath.Text = folderDlg.SelectedPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加保存和加载配置的方法
|
||||||
|
private void SaveConfig()
|
||||||
|
{
|
||||||
|
var config = new AppConfig
|
||||||
|
{
|
||||||
|
ExcelPath = textBoxExcelPath.Text,
|
||||||
|
ClientPath = textBoxClientGenPath.Text,
|
||||||
|
ClientJsonPath = textBoxClientGenJsonPath.Text,
|
||||||
|
ServerPath = textBoxServerGenPath.Text,
|
||||||
|
ServerJsonPath = textBoxServerGenJsonPath.Text,
|
||||||
|
GenClient = checkBoxGenClient.Checked,
|
||||||
|
GenServer = checkBoxGenServer.Checked,
|
||||||
|
};
|
||||||
|
App.Config = config;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true });
|
||||||
|
File.WriteAllText(configPath, json);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"保存配置失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadConfig()
|
||||||
|
{
|
||||||
|
if (!File.Exists(configPath)) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(configPath);
|
||||||
|
var config = JsonSerializer.Deserialize<AppConfig>(json);
|
||||||
|
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
App.Config = config;
|
||||||
|
textBoxExcelPath.Text = config.ExcelPath ?? "";
|
||||||
|
textBoxClientGenPath.Text = config.ClientPath ?? "";
|
||||||
|
textBoxServerGenPath.Text = config.ServerPath ?? "";
|
||||||
|
checkBoxGenClient.Checked = config.GenClient;
|
||||||
|
checkBoxGenServer.Checked = config.GenServer;
|
||||||
|
textBoxClientGenJsonPath.Text = config.ClientJsonPath ?? "";
|
||||||
|
textBoxServerGenJsonPath.Text = config.ServerJsonPath ?? "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"加载配置失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
Tools/ConfigBuilder/NBConfigBuilder/Form1.resx
Normal file
120
Tools/ConfigBuilder/NBConfigBuilder/Form1.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
97
Tools/ConfigBuilder/NBConfigBuilder/Log.cs
Normal file
97
Tools/ConfigBuilder/NBConfigBuilder/Log.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
using NLog;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder
|
||||||
|
{
|
||||||
|
public static class Log
|
||||||
|
{
|
||||||
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
static Log()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录信息级别的日志消息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息。</param>
|
||||||
|
public static void Info(string msg)
|
||||||
|
{
|
||||||
|
logger.Info(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录错误级别的日志消息,并附带调用栈信息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息。</param>
|
||||||
|
public static void Error(string msg)
|
||||||
|
{
|
||||||
|
var st = new StackTrace(1, true);
|
||||||
|
logger.Error($"{msg}\n{st}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录异常的错误级别的日志消息,并附带调用栈信息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">异常对象。</param>
|
||||||
|
public static void Error(Exception e)
|
||||||
|
{
|
||||||
|
if (e.Data.Contains("StackTrace"))
|
||||||
|
{
|
||||||
|
logger.Error($"{e.Data["StackTrace"]}\n{e}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var str = e.ToString();
|
||||||
|
logger.Error(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录信息级别的格式化日志消息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">日志消息模板。</param>
|
||||||
|
/// <param name="args">格式化参数。</param>
|
||||||
|
public static void Info(string message, params object[] args)
|
||||||
|
{
|
||||||
|
logger.Info(message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录调试级别的日志消息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息。</param>
|
||||||
|
public static void Debug(string msg)
|
||||||
|
{
|
||||||
|
logger.Debug(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录警告级别的日志消息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息。</param>
|
||||||
|
public static void Warn(string msg)
|
||||||
|
{
|
||||||
|
logger.Warn(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录严重错误级别的日志消息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">日志消息。</param>
|
||||||
|
public static void Fatal(string msg)
|
||||||
|
{
|
||||||
|
logger.Fatal(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录异常的错误级别的日志消息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">异常对象。</param>
|
||||||
|
/// <param name="message">附加消息。</param>
|
||||||
|
public static void Error(Exception e, string message)
|
||||||
|
{
|
||||||
|
logger.Error(e, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj
Normal file
25
Tools/ConfigBuilder/NBConfigBuilder/NBConfigBuilder.csproj
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="EPPlus" Version="8.2.0" />
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
|
<PackageReference Include="NLog" Version="6.0.4" />
|
||||||
|
<PackageReference Include="protobuf-net" Version="3.2.56" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="NLog.config">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="Form1.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
25
Tools/ConfigBuilder/NBConfigBuilder/NLog.config
Normal file
25
Tools/ConfigBuilder/NBConfigBuilder/NLog.config
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<targets>
|
||||||
|
<!-- 文件目标 -->
|
||||||
|
<target xsi:type="File"
|
||||||
|
name="fileTarget"
|
||||||
|
fileName="logs/${shortdate}.log"
|
||||||
|
layout="${longdate} ${uppercase:${level}} ${message} ${exception:format=ToString}" />
|
||||||
|
|
||||||
|
<!-- 控制台目标 -->
|
||||||
|
<target xsi:type="Console"
|
||||||
|
name="consoleTarget"
|
||||||
|
layout="${longdate} ${uppercase:${level}} ${message} ${exception:format=ToString}" />
|
||||||
|
</targets>
|
||||||
|
|
||||||
|
<rules>
|
||||||
|
<!-- 记录所有级别高于 Debug 的日志到文件 -->
|
||||||
|
<logger name="*" minlevel="Debug" writeTo="fileTarget" />
|
||||||
|
|
||||||
|
<!-- 记录所有级别高于 Info 的日志到控制台 -->
|
||||||
|
<logger name="*" minlevel="Info" writeTo="consoleTarget" />
|
||||||
|
</rules>
|
||||||
|
</nlog>
|
||||||
25
Tools/ConfigBuilder/NBConfigBuilder/Program.cs
Normal file
25
Tools/ConfigBuilder/NBConfigBuilder/Program.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
// 配置NLog
|
||||||
|
var logger = LogManager.GetCurrentClassLogger();
|
||||||
|
logger.Info("Application started");
|
||||||
|
|
||||||
|
// To customize application configuration such as set high DPI settings or default font,
|
||||||
|
// see https://aka.ms/applicationconfiguration.
|
||||||
|
ApplicationConfiguration.Initialize();
|
||||||
|
Application.Run(new Form1());
|
||||||
|
|
||||||
|
logger.Info("Application closing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
182
Tools/ConfigBuilder/NBConfigBuilder/Utils/FileHelper.cs
Normal file
182
Tools/ConfigBuilder/NBConfigBuilder/Utils/FileHelper.cs
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件操作助手类,提供了各种文件操作方法。
|
||||||
|
/// </summary>
|
||||||
|
public static partial class FileHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取相对路径的完整路径。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativePath">相对路径。</param>
|
||||||
|
/// <returns>完整路径。</returns>
|
||||||
|
public static string GetFullPath(string relativePath)
|
||||||
|
{
|
||||||
|
return Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), relativePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取相对路径的完整路径。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativePath">相对于指定的目录的相对路径。</param>
|
||||||
|
/// <param name="srcDir">指定的目录</param>
|
||||||
|
/// <returns>完整路径。</returns>
|
||||||
|
public static string GetFullPath(string relativePath, string srcDir)
|
||||||
|
{
|
||||||
|
return Path.GetFullPath(Path.Combine(srcDir, relativePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取相对路径的的文本信息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativePath"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<string> GetTextByRelativePath(string relativePath)
|
||||||
|
{
|
||||||
|
var fullPath = GetFullPath(relativePath);
|
||||||
|
return await File.ReadAllTextAsync(fullPath, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取绝对路径的的文本信息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fullPath"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<string> GetText(string fullPath)
|
||||||
|
{
|
||||||
|
return await File.ReadAllTextAsync(fullPath, Encoding.UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据文件夹路径创建文件夹,如果文件夹不存在会自动创建文件夹。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="directoryPath"></param>
|
||||||
|
public static void CreateDirectory(string directoryPath)
|
||||||
|
{
|
||||||
|
if (directoryPath.LastIndexOf('/') != directoryPath.Length - 1)
|
||||||
|
{
|
||||||
|
directoryPath += "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
var directoriesByFilePath = GetDirectoriesByFilePath(directoryPath);
|
||||||
|
|
||||||
|
foreach (var dir in directoriesByFilePath)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(dir))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory.CreateDirectory(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将文件复制到目标路径,如果目标目录不存在会自动创建目录。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceFile">源文件路径。</param>
|
||||||
|
/// <param name="destinationFile">目标文件路径。</param>
|
||||||
|
/// <param name="overwrite">是否覆盖已存在的目标文件。</param>
|
||||||
|
public static void Copy(string sourceFile, string destinationFile, bool overwrite)
|
||||||
|
{
|
||||||
|
CreateDirectory(destinationFile);
|
||||||
|
File.Copy(sourceFile, destinationFile, overwrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件路径内的所有文件夹路径。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filePath">文件路径。</param>
|
||||||
|
/// <returns>文件夹路径列表。</returns>
|
||||||
|
public static IEnumerable<string> GetDirectoriesByFilePath(string filePath)
|
||||||
|
{
|
||||||
|
var dir = "";
|
||||||
|
var fileDirectories = filePath.Split('/');
|
||||||
|
|
||||||
|
for (var i = 0; i < fileDirectories.Length - 1; i++)
|
||||||
|
{
|
||||||
|
dir = $"{dir}{fileDirectories[i]}/";
|
||||||
|
yield return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileDirectories.Length == 1)
|
||||||
|
{
|
||||||
|
yield return filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将文件夹内的所有内容复制到目标位置。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceDirectory">源文件夹路径。</param>
|
||||||
|
/// <param name="destinationDirectory">目标文件夹路径。</param>
|
||||||
|
/// <param name="overwrite">是否覆盖已存在的文件。</param>
|
||||||
|
public static void CopyDirectory(string sourceDirectory, string destinationDirectory, bool overwrite)
|
||||||
|
{
|
||||||
|
// 创建目标文件夹
|
||||||
|
|
||||||
|
if (!Directory.Exists(destinationDirectory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(destinationDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前文件夹中的所有文件
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(sourceDirectory);
|
||||||
|
|
||||||
|
// 拷贝文件到目标文件夹
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileName(file);
|
||||||
|
var destinationPath = Path.Combine(destinationDirectory, fileName);
|
||||||
|
File.Copy(file, destinationPath, overwrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取源文件夹中的所有子文件夹
|
||||||
|
|
||||||
|
var directories = Directory.GetDirectories(sourceDirectory);
|
||||||
|
|
||||||
|
// 递归方式拷贝文件夹
|
||||||
|
|
||||||
|
foreach (var directory in directories)
|
||||||
|
{
|
||||||
|
var directoryName = Path.GetFileName(directory);
|
||||||
|
var destinationPath = Path.Combine(destinationDirectory, directoryName);
|
||||||
|
CopyDirectory(directory, destinationPath, overwrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取目录下的所有文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folderPath">文件夹路径。</param>
|
||||||
|
/// <param name="searchPattern">需要查找的文件通配符</param>
|
||||||
|
/// <param name="searchOption">查找的类型</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string[] GetDirectoryFile(string folderPath, string searchPattern, SearchOption searchOption)
|
||||||
|
{
|
||||||
|
return Directory.GetFiles(folderPath, searchPattern, searchOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空文件夹内的所有文件。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folderPath">文件夹路径。</param>
|
||||||
|
public static void ClearDirectoryFile(string folderPath)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(folderPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = Directory.GetFiles(folderPath);
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
228
Tools/ConfigBuilder/NBConfigBuilder/Utils/HashCodeHelper.cs
Normal file
228
Tools/ConfigBuilder/NBConfigBuilder/Utils/HashCodeHelper.cs
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HashCode算法帮助类
|
||||||
|
/// </summary>
|
||||||
|
public static partial class HashCodeHelper
|
||||||
|
{
|
||||||
|
private static readonly SHA256 Sha256Hash = SHA256.Create();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算两个字符串的HashCode
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a"></param>
|
||||||
|
/// <param name="b"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int GetHashCode(string a, string b)
|
||||||
|
{
|
||||||
|
var hash = 17;
|
||||||
|
hash = hash * 31 + a.GetHashCode();
|
||||||
|
hash = hash * 31 + b.GetHashCode();
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
#if FANTASY_NET || !FANTASY_WEBGL
|
||||||
|
/// <summary>
|
||||||
|
/// 使用bkdr算法生成一个long的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static unsafe long GetBKDRHashCode(string str)
|
||||||
|
{
|
||||||
|
ulong hash = 0;
|
||||||
|
// 如果要修改这个种子、建议选择一个质数来做种子
|
||||||
|
const uint seed = 13131; // 31 131 1313 13131 131313 etc..
|
||||||
|
fixed (char* p = str)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < str.Length; i++)
|
||||||
|
{
|
||||||
|
var c = p[i];
|
||||||
|
var high = (byte)(c >> 8);
|
||||||
|
var low = (byte)(c & byte.MaxValue);
|
||||||
|
hash = hash * seed + high;
|
||||||
|
hash = hash * seed + low;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (long)hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用MurmurHash3算法生成一个uint的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static unsafe uint MurmurHash3(string str)
|
||||||
|
{
|
||||||
|
const uint seed = 0xc58f1a7b;
|
||||||
|
uint hash = seed;
|
||||||
|
uint c1 = 0xcc9e2d51;
|
||||||
|
uint c2 = 0x1b873593;
|
||||||
|
|
||||||
|
fixed (char* p = str)
|
||||||
|
{
|
||||||
|
var current = p;
|
||||||
|
|
||||||
|
for (var i = 0; i < str.Length; i++)
|
||||||
|
{
|
||||||
|
var k1 = (uint)(*current);
|
||||||
|
k1 *= c1;
|
||||||
|
k1 = (k1 << 15) | (k1 >> (32 - 15));
|
||||||
|
k1 *= c2;
|
||||||
|
|
||||||
|
hash ^= k1;
|
||||||
|
hash = (hash << 13) | (hash >> (32 - 13));
|
||||||
|
hash = hash * 5 + 0xe6546b64;
|
||||||
|
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hash ^= (uint)str.Length;
|
||||||
|
hash ^= hash >> 16;
|
||||||
|
hash *= 0x85ebca6b;
|
||||||
|
hash ^= hash >> 13;
|
||||||
|
hash *= 0xc2b2ae35;
|
||||||
|
hash ^= hash >> 16;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用MurmurHash3算法生成一个long的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static unsafe long ComputeHash64(string str)
|
||||||
|
{
|
||||||
|
const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed
|
||||||
|
var hash = seed;
|
||||||
|
var c1 = 0x87c37b91114253d5UL;
|
||||||
|
var c2 = 0x4cf5ad432745937fUL;
|
||||||
|
|
||||||
|
fixed (char* p = str)
|
||||||
|
{
|
||||||
|
var current = p;
|
||||||
|
|
||||||
|
for (var i = 0; i < str.Length; i++)
|
||||||
|
{
|
||||||
|
var k1 = (ulong)(*current);
|
||||||
|
k1 *= c1;
|
||||||
|
k1 = (k1 << 31) | (k1 >> (64 - 31));
|
||||||
|
k1 *= c2;
|
||||||
|
|
||||||
|
hash ^= k1;
|
||||||
|
hash = (hash << 27) | (hash >> (64 - 27));
|
||||||
|
hash = hash * 5 + 0x52dce729;
|
||||||
|
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hash ^= (ulong)str.Length;
|
||||||
|
hash ^= hash >> 33;
|
||||||
|
hash *= 0xff51afd7ed558ccdUL;
|
||||||
|
hash ^= hash >> 33;
|
||||||
|
hash *= 0xc4ceb9fe1a85ec53UL;
|
||||||
|
hash ^= hash >> 33;
|
||||||
|
return (long)hash;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if FANTASY_WEBGL
|
||||||
|
/// <summary>
|
||||||
|
/// 使用bkdr算法生成一个long的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static long GetBKDRHashCode(string str)
|
||||||
|
{
|
||||||
|
long hash = 0;
|
||||||
|
// 如果要修改这个种子、建议选择一个质数来做种子
|
||||||
|
const uint seed = 13131; // 31 131 1313 13131 131313 etc..
|
||||||
|
foreach (var c in str)
|
||||||
|
{
|
||||||
|
var high = (byte)(c >> 8);
|
||||||
|
var low = (byte)(c & byte.MaxValue);
|
||||||
|
hash = hash * seed + high;
|
||||||
|
hash = hash * seed + low;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 使用MurmurHash3算法生成一个uint的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static uint MurmurHash3(string str)
|
||||||
|
{
|
||||||
|
const uint seed = 0xc58f1a7b;
|
||||||
|
uint hash = seed;
|
||||||
|
uint c1 = 0xcc9e2d51;
|
||||||
|
uint c2 = 0x1b873593;
|
||||||
|
|
||||||
|
foreach (var t in str)
|
||||||
|
{
|
||||||
|
var k1 = (uint)(t);
|
||||||
|
k1 *= c1;
|
||||||
|
k1 = (k1 << 15) | (k1 >> (32 - 15));
|
||||||
|
k1 *= c2;
|
||||||
|
|
||||||
|
hash ^= k1;
|
||||||
|
hash = (hash << 13) | (hash >> (32 - 13));
|
||||||
|
hash = hash * 5 + 0xe6546b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash ^= (uint)str.Length;
|
||||||
|
hash ^= hash >> 16;
|
||||||
|
hash *= 0x85ebca6b;
|
||||||
|
hash ^= hash >> 13;
|
||||||
|
hash *= 0xc2b2ae35;
|
||||||
|
hash ^= hash >> 16;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用MurmurHash3算法生成一个long的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static long ComputeHash64(string str)
|
||||||
|
{
|
||||||
|
const ulong seed = 0xc58f1a7bc58f1a7bUL; // 64-bit seed
|
||||||
|
var hash = seed;
|
||||||
|
var c1 = 0x87c37b91114253d5UL;
|
||||||
|
var c2 = 0x4cf5ad432745937fUL;
|
||||||
|
|
||||||
|
foreach (var t in str)
|
||||||
|
{
|
||||||
|
var k1 = (ulong)(t);
|
||||||
|
k1 *= c1;
|
||||||
|
k1 = (k1 << 31) | (k1 >> (64 - 31));
|
||||||
|
k1 *= c2;
|
||||||
|
|
||||||
|
hash ^= k1;
|
||||||
|
hash = (hash << 27) | (hash >> (64 - 27));
|
||||||
|
hash = hash * 5 + 0x52dce729;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash ^= (ulong)str.Length;
|
||||||
|
hash ^= hash >> 33;
|
||||||
|
hash *= 0xff51afd7ed558ccdUL;
|
||||||
|
hash ^= hash >> 33;
|
||||||
|
hash *= 0xc4ceb9fe1a85ec53UL;
|
||||||
|
hash ^= hash >> 33;
|
||||||
|
return (long)hash;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/// <summary>
|
||||||
|
/// 根据字符串计算一个Hash值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawData"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int ComputeSha256HashAsInt(string rawData)
|
||||||
|
{
|
||||||
|
var bytes = Sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));
|
||||||
|
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
65
Tools/ConfigBuilder/NBConfigBuilder/Utils/TimeHelper.cs
Normal file
65
Tools/ConfigBuilder/NBConfigBuilder/Utils/TimeHelper.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
namespace NBConfigBuilder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供与时间相关的帮助方法。
|
||||||
|
/// </summary>
|
||||||
|
public static partial class TimeHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 一小时的毫秒值。
|
||||||
|
/// </summary>
|
||||||
|
public const long Hour = 3600000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 一分钟的毫秒值。
|
||||||
|
/// </summary>
|
||||||
|
public const long Minute = 60000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 一天的毫秒值。
|
||||||
|
/// </summary>
|
||||||
|
public const long OneDay = 86400000;
|
||||||
|
|
||||||
|
// 1970年1月1日的Ticks
|
||||||
|
private const long Epoch = 621355968000000000L;
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前时间的毫秒数,从1970年1月1日开始计算。
|
||||||
|
/// </summary>
|
||||||
|
public static long Now => (DateTime.UtcNow.Ticks - Epoch) / 10000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据时间获取时间戳
|
||||||
|
/// </summary>
|
||||||
|
public static long Transition(DateTime dateTime)
|
||||||
|
{
|
||||||
|
return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据时间获取 时间戳
|
||||||
|
/// </summary>
|
||||||
|
public static long TransitionToSeconds(DateTime dateTime)
|
||||||
|
{
|
||||||
|
return (dateTime.ToUniversalTime().Ticks - Epoch) / 10000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将毫秒数转换为日期时间。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timeStamp">要转换的毫秒数。</param>
|
||||||
|
/// <returns>转换后的日期时间。</returns>
|
||||||
|
public static DateTime Transition(this long timeStamp)
|
||||||
|
{
|
||||||
|
return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToUniversalTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将毫秒数转换为本地时间的日期时间。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="timeStamp">要转换的毫秒数。</param>
|
||||||
|
/// <returns>转换后的本地时间的日期时间。</returns>
|
||||||
|
public static DateTime TransitionLocal(this long timeStamp)
|
||||||
|
{
|
||||||
|
return new DateTime(Epoch + timeStamp * 10000, DateTimeKind.Utc).ToLocalTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -664,6 +664,7 @@ public sealed class ExcelExporter
|
|||||||
|
|
||||||
Task.WaitAll(exportToBinaryTasks.ToArray());
|
Task.WaitAll(exportToBinaryTasks.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateBinary(string fileInfoFullName, ExcelWorksheet excelWorksheet, DynamicConfigDataType dynamicInfo, List<int> cols, string id, int row, bool isLast, bool isServer)
|
private void GenerateBinary(string fileInfoFullName, ExcelWorksheet excelWorksheet, DynamicConfigDataType dynamicInfo, List<int> cols, string id, int row, bool isLast, bool isServer)
|
||||||
{
|
{
|
||||||
if (cols == null || IsNullOrEmpty(id) || cols.Count <= 0 || dynamicInfo?.ConfigType == null)
|
if (cols == null || IsNullOrEmpty(id) || cols.Count <= 0 || dynamicInfo?.ConfigType == null)
|
||||||
@@ -718,6 +719,7 @@ public sealed class ExcelExporter
|
|||||||
dynamicInfo.Json.AppendLine($"{json},");
|
dynamicInfo.Json.AppendLine($"{json},");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从 Excel 文件加载工作表并返回 ExcelWorksheet 对象。
|
/// 从 Excel 文件加载工作表并返回 ExcelWorksheet 对象。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user