Repository navigation
Expand file tree
/
Copy pathMoneyModule.cs
More file actions
284 lines (263 loc) · 12.4 KB
/
Copy pathMoneyModule.cs
File metadata and controls
284 lines (263 loc) · 12.4 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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
using BepInEx.Configuration;
using UnityEngine;
namespace HTFToolkit
{
/// <summary>
/// 金钱修改模块(游戏内菜单使用)。
/// 金钱是服务器权威(全房间共享 SyncVar 池):主机/单人直改;客户端无法直改。
/// 客户端变现路径(v1.9.0):Server.SetItemMultiplier 为零校验 ServerRpc,
/// 设置手中物品的售价倍率(_killScoreMultiplier 参与 TotalWorth 计算)→ 卖店变现。
/// </summary>
internal static class MoneyModule
{
private static string _customAmount = "100000";
private static string _customMult = "50";
private static GUIStyle _rowStyle;
private static GUIStyle _hintStyle;
private static GUIStyle _fieldStyle;
public static void BindConfig(ConfigFile cfg)
{
}
/// <summary>当前金钱(客户端缓存值)。未初始化返回 -1。</summary>
public static int CurrentMoney
{
get
{
try
{
return MoneyManager.Instance != null ? MoneyManager.Money : -1;
}
catch
{
return -1;
}
}
}
/// <summary>是否有权限直改金钱(仅主机/单机)。</summary>
public static bool CanUse
{
get
{
try
{
return MoneyManager.Instance != null && MoneyManager.Instance.IsServerInitialized;
}
catch
{
return false;
}
}
}
public static void Add(int amount)
{
if (HostModerationModule.IsBanned(HostModerationModule.F_Money))
{
ToastModule.Show("房主已禁止金钱修改", new Color(1f, 0.75f, 0.4f));
return;
}
if (!CanUse)
{
ToastModule.Show("金钱: 仅主机/单人可用", Color.yellow);
return;
}
if (Player.LocalPlayer == null)
{
ToastModule.Show("金钱: 玩家未初始化", Color.yellow);
return;
}
if (amount >= 0)
MoneyManager.AddMoney(amount, Player.LocalPlayer);
else
MoneyManager.RemoveMoney(-amount, Player.LocalPlayer);
ToastModule.Show($"金钱 {(amount >= 0 ? "+" : "")}{amount} → ${MoneyManager.Money}", Color.white);
}
public static void SetTo(int value)
{
if (HostModerationModule.IsBanned(HostModerationModule.F_Money))
{
ToastModule.Show("房主已禁止金钱修改", new Color(1f, 0.75f, 0.4f));
return;
}
if (!CanUse)
{
ToastModule.Show("金钱: 仅主机可直改", Color.yellow);
return;
}
// 服务器端直接改 SyncVar(与游戏内 RemoveMoney 的做法一致)
MoneyManager.Instance._money.Value = Mathf.Max(0, value);
ToastModule.Show($"金钱 设置为 ${MoneyManager.Money}", Color.white);
}
/// <summary>
/// 设置手中物品的售价倍率。
/// 游戏 SetKillscoreMultiplier 只能从 1 设一次(内部校验 _killScoreMultiplier.Value == 1f,
/// 防刷设计)→ 主机/单人:直改 SyncVar 重置为 1 后再设,可反复设/叠加;
/// 客户端:走 SetItemMultiplier RPC(受服务器校验,当前非 1 时会被忽略 → 提示先恢复原价)。
/// </summary>
public static void SetHeldMultiplier(float mult)
{
if (HostModerationModule.IsBanned(HostModerationModule.F_Money))
{
ToastModule.Show("房主已禁止金钱修改", new Color(1f, 0.75f, 0.4f));
return;
}
try
{
Player p = Player.LocalPlayer;
if (p == null || p.Holding == null)
{
ToastModule.Show("金钱: 玩家未初始化", Color.yellow);
return;
}
Item held = p.Holding.HeldItem;
if (held == null)
{
ToastModule.Show("先手持一件物品,再设置售价倍率", Color.yellow);
return;
}
if (Compat.IsHost)
{
// 主机/单人:游戏只允许从 1 设置一次;先直改 SyncVar 归 1 再走官方方法 → 可任意设置
if (held.KillScoreMultiplier != 1f && mult > 1f)
held._killScoreMultiplier.Value = 1f;
Server.Instance.SetItemMultiplier(held, mult);
}
else
{
if (held.KillScoreMultiplier != 1f)
{
ToastModule.Show("客户端受服务器限制:请先点「恢复原价 ×1」再设新倍率", Color.yellow);
return;
}
Server.Instance.SetItemMultiplier(held, mult);
}
ToastModule.Show(mult <= 1f
? $"已恢复 {ItemGalleryModule.ItemName(held)} 原价"
: $"{ItemGalleryModule.ItemName(held)} 售价 ×{mult}({held.KillScoreMultiplier:0.##})", Color.white);
}
catch (System.Exception e)
{
Plugin.Log?.LogWarning($"set multiplier failed: {e.Message}");
ToastModule.Show("金钱: 倍率设置失败", Color.yellow);
}
}
public static void Draw()
{
if (Event.current == null)
return;
if (_rowStyle == null)
{
_rowStyle = new GUIStyle(GUI.skin.label) { richText = true };
_hintStyle = new GUIStyle(GUI.skin.label)
{
normal = { textColor = new Color(0.75f, 0.75f, 0.75f) }
};
// 输入框字号必须跟页面字体走(默认 skin.textField 字号固定,会出现"数字太小")
_fieldStyle = new GUIStyle(GUI.skin.textField)
{
fontSize = UIScale.TextFont,
alignment = TextAnchor.MiddleLeft
};
}
_rowStyle.fontSize = UIScale.TextFont;
_hintStyle.fontSize = UIScale.HintFont;
_fieldStyle.fontSize = UIScale.TextFont;
GUILayout.Space(UIScale.ButtonH * 0.15f);
GUILayout.BeginHorizontal();
GUILayout.Label($"<b>金钱</b> ${(CurrentMoney >= 0 ? CurrentMoney.ToString() : "--")}", _rowStyle);
GUILayout.EndHorizontal();
// ---- 客户端:共享池无法直改,提供手中物品倍率变现 ----
if (!CanUse)
{
if (Compat.ClientRpcReady)
{
GUILayout.Label("<color=#88ccff>客户端模式</color>:金钱为全房间共享池,无法直改;", _hintStyle);
GUILayout.Label("可修改<b>手中物品</b>的售价倍率,卖店变现", _hintStyle);
DrawMultiplierSection();
GUILayout.Label("<color=#777777>提示: 配合物品图鉴免费拿货 → 调倍率 → 卖店,反复刷钱</color>", _hintStyle);
return;
}
GUILayout.Label("<color=#ffcc55>需在游戏内使用</color>", _hintStyle);
return;
}
// ---- 主机/单人:直改共享池 ----
float bw = (UIScale.W - UIScale.ButtonH * 2f) / 3f;
GUILayout.BeginHorizontal();
if (GUILayout.Button("+1000", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) Add(1000);
if (GUILayout.Button("+10000", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) Add(10000);
if (GUILayout.Button("+100000", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) Add(100000);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button("-1000", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) Add(-1000);
if (GUILayout.Button("-10000", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) Add(-10000);
if (GUILayout.Button("清零", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) SetTo(0);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
_customAmount = GUILayout.TextField(_customAmount, _fieldStyle, GUILayout.Width(UIScale.W * 0.2f), GUILayout.Height(UIScale.ButtonH));
if (GUILayout.Button("设为该金额", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(UIScale.W * 0.28f)))
{
if (int.TryParse(_customAmount.Trim(), out int v))
SetTo(v);
else
ToastModule.Show("金钱: 金额无效", Color.yellow);
}
GUILayout.EndHorizontal();
// ---- 主机也提供售价倍率(效果与客户端一致,卖店变现)----
GUILayout.Space(UIScale.ButtonH * 0.2f);
GUILayout.Label("<b>售价倍率</b>(手中物品,卖店变现)", _rowStyle);
DrawMultiplierSection();
}
/// <summary>手中物品售价倍率按钮(×10/×100/×1000/恢复×1,两角色共用)。</summary>
private static void DrawMultiplierSection()
{
string heldLabel = "(空手——先拿一件物品)";
try
{
Player p = Player.LocalPlayer;
Item held = p != null && p.Holding != null ? p.Holding.HeldItem : null;
if (held != null)
heldLabel = ItemGalleryModule.ItemName(held);
}
catch
{
// 玩家未就绪
}
GUILayout.Label($"手中物品: {heldLabel}", _rowStyle);
float bw = (UIScale.W - UIScale.ButtonH * 2f) / 3f;
GUILayout.BeginHorizontal();
if (GUILayout.Button("售价 ×10", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) SetHeldMultiplier(10f);
if (GUILayout.Button("售价 ×100", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) SetHeldMultiplier(100f);
if (GUILayout.Button("售价 ×1000", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw))) SetHeldMultiplier(1000f);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button("恢复原价 (×1)", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(bw * 1.6f))) SetHeldMultiplier(1f);
GUILayout.EndHorizontal();
// ---- 自定义倍率(自由填任意倍数,小数也支持)----
GUILayout.BeginHorizontal();
_customMult = GUILayout.TextField(_customMult, _fieldStyle, GUILayout.Width(UIScale.W * 0.2f), GUILayout.Height(UIScale.ButtonH));
if (GUILayout.Button("设为该倍率", UIScale.ButtonStyle, GUILayout.Height(UIScale.ButtonH), GUILayout.Width(UIScale.W * 0.28f)))
{
string raw = (_customMult ?? "").Trim();
if (float.TryParse(raw, out float v) && v > 0f)
SetHeldMultiplier(v);
else
ToastModule.Show("倍率无效(需大于 0 的数字)", Color.yellow);
}
GUILayout.EndHorizontal();
// 当前倍率回显 + 叠加提示
try
{
Player pl = Player.LocalPlayer;
Item hl = pl != null && pl.Holding != null ? pl.Holding.HeldItem : null;
if (hl != null)
{
GUILayout.Label($"当前倍率: ×{hl.KillScoreMultiplier:0.##}" +
(Compat.IsHost ? "(主机可随时改设新值)" : "(客户端需先恢复 ×1 才能重设)"), _hintStyle);
}
}
catch
{
// 玩家未就绪
}
}
}
}