-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConfiguration.cs
More file actions
198 lines (157 loc) · 6.32 KB
/
Configuration.cs
File metadata and controls
198 lines (157 loc) · 6.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
using Newtonsoft.Json;
using System.Text.RegularExpressions;
namespace PointsSystem;
internal class Configuration
{
#region 基础设置
[JsonProperty("插件开关", Order = 0)]
public bool Enabled { get; set; } = true;
[JsonProperty("数据同步秒数", Order = 1)]
public int SyncIntervalSec { get; set; } = 60;
[JsonProperty("离服清理缓存", Order = 2)]
public bool ClearOnLeave { get; set; } = false;
#endregion
#region 签到设置
[JsonProperty("签到基础积分", Order = 10)]
public int SignBasePoints { get; set; } = 10;
[JsonProperty("签到连续奖励", Order = 11)]
public int SignConsecutiveBonus { get; set; } = 5;
[JsonProperty("签到最大连续奖励", Order = 12)]
public int SignMaxConsecutiveBonus { get; set; } = 50;
#endregion
#region 掷骰子设置
[JsonProperty("掷骰子冷却秒数", Order = 20)]
public int DiceCooldownSec { get; set; } = 300;
[JsonProperty("掷骰子获胜概率", Order = 21)]
public double DiceWinProbability { get; set; } = 0.45;
[JsonProperty("掷骰子积分消耗", Order = 22)]
public int DiceCost { get; set; } = 10;
[JsonProperty("掷骰子获胜奖励", Order = 23)]
public int DiceReward { get; set; } = 25;
#endregion
#region 猜数字设置
[JsonProperty("猜数字冷却秒数", Order = 30)]
public int GuessCooldownSec { get; set; } = 600;
[JsonProperty("猜数字获胜概率", Order = 31)]
public double GuessWinProbability { get; set; } = 0.1;
[JsonProperty("猜数字最小值", Order = 32)]
public int GuessRangeMin { get; set; } = 1;
[JsonProperty("猜数字最大值", Order = 33)]
public int GuessRangeMax { get; set; } = 100;
[JsonProperty("猜数字积分消耗", Order = 34)]
public int GuessCost { get; set; } = 5;
[JsonProperty("猜数字获胜奖励", Order = 35)]
public int GuessReward { get; set; } = 50;
#endregion
#region 抢劫设置
[JsonProperty("抢劫冷却秒数", Order = 40)]
public int RobCooldownSec { get; set; } = 1800;
[JsonProperty("抢劫成功概率", Order = 41)]
public double RobSuccessProbability { get; set; } = 0.4;
[JsonProperty("抢劫最小积分", Order = 42)]
public int RobMinPoints { get; set; } = 5;
[JsonProperty("抢劫最大积分", Order = 43)]
public int RobMaxPoints { get; set; } = 50;
[JsonProperty("抢劫失败惩罚比例", Order = 44)]
public double RobFailurePenaltyRate { get; set; } = 0.5;
#endregion
#region 抽奖设置
[JsonProperty("抽奖积分消耗", Order = 50)]
public int LotteryCost { get; set; } = 20;
[JsonProperty("抽奖物品列表", Order = 51)]
public List<LotteryEntry> LotteryItems { get; set; } = DefaultLotteryItems();
/// <summary>默认抽奖列表(仅一处定义,避免重复)</summary>
private static List<LotteryEntry> DefaultLotteryItems() => new()
{
new LotteryEntry { ItemID = 73, Weight = 5 },
new LotteryEntry { ItemID = 155, Weight = 3 },
new LotteryEntry { ItemID = 65, Weight = 2 },
new LotteryEntry { ItemID = 125, Weight = 1 },
};
#endregion
#region 回收设置
[JsonProperty("回收比例", Order = 60)]
public double RecycleRate { get; set; } = 0.5;
[JsonProperty("回收最小价值(铜币)", Order = 61)]
public int RecycleMinValue { get; set; } = 100;
#endregion
#region 转账设置
[JsonProperty("转账最小积分", Order = 70)]
public int TransferMinPoints { get; set; } = 1;
[JsonProperty("转账手续费比例", Order = 71)]
public double TransferFeeRate { get; set; } = 0.0;
#endregion
#region 抽奖物品条目
public class LotteryEntry
{
[JsonProperty("物品ID")]
public int ItemID { get; set; }
[JsonProperty("权重")]
public int Weight { get; set; } = 1;
[JsonProperty("数量")]
public int Stack { get; set; } = 1;
[JsonProperty("前缀")]
public int Prefix { get; set; } = 0;
}
#endregion
#region 文件读写
public void Write(string path, CacheData cache)
{
string json = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(path, json);
cache.Save(GetCachePath(path));
}
public static Configuration Read(string path, out CacheData cache)
{
if (!File.Exists(path))
{
var cfg = new Configuration();
cache = new CacheData();
cfg.Write(path, cache);
return cfg;
}
try
{
string json = File.ReadAllText(path);
// ★★★ 关键修复:Replace 模式杜绝默认值被追加到 JSON 列表后面
var settings = new JsonSerializerSettings
{
ObjectCreationHandling = ObjectCreationHandling.Replace
};
var cfg = JsonConvert.DeserializeObject<Configuration>(json, settings)!;
// 防御:如果配置中列表为 null,回填默认值(仅当 JSON 中明确为 null 时)
if (cfg.LotteryItems == null || cfg.LotteryItems.Count == 0)
cfg.LotteryItems = DefaultLotteryItems();
cache = CacheData.Load(GetCachePath(path));
return cfg;
}
catch (JsonReaderException ex)
{
string json = File.ReadAllText(path);
string[] lines = json.Split('\n');
int line = ex.LineNumber;
int idx = Math.Max(0, Math.Min(line - 2, lines.Length - 1));
string text = lines[idx].Trim();
throw new Exception(
$"配置文件格式错误!\n" +
$"位置: 第 {line - 1} 行\n" +
$"内容: {text ?? string.Empty}\n" +
$"路径: {FormatJsonPath(ex.Path ?? string.Empty)}", ex);
}
}
private static string GetCachePath(string configPath)
{
var dir = Path.GetDirectoryName(configPath)!;
return Path.Combine(dir, "数据缓存.json");
}
private static string FormatJsonPath(string path)
{
if (string.IsNullOrEmpty(path)) return path;
return Regex.Replace(path, @"\[(\d+)\]", m =>
{
int index = int.Parse(m.Groups[1].Value);
return $":第{index + 1}项";
});
}
#endregion
}