Files
squad-rain-ops-mini/Plugins/CdkRedeemPlugin.cs

150 lines
4.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using RainOpsMini.Helpers;
using RainOpsMini.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace RainOpsMini.Plugins
{
public class CdkRedeemConfig
{
/// <summary>
/// 是否启用插件
/// </summary>
public bool Enabled { get; set; } = false;
/// <summary>
/// 消息通知方式AdminWarn=警告弹窗AdminBroadcast=全服广播)
/// </summary>
public string Method { get; set; } = "AdminWarn";
}
public class CdkRedeemPlugin : IPlugin, IDisposable
{
public string Name => "CDK兑换插件";
public string Description => "玩家在游戏内直接发送 CDK 即可激活";
public PluginCategory Category => PluginCategory.AdvancedFunction;
public bool IsEnabled => _config.Enabled;
private CdkRedeemConfig _config = new CdkRedeemConfig();
/// <summary>
/// 构造函数订阅RCON消息
/// </summary>
public CdkRedeemPlugin()
{
Program.OnRconMessageReceived += OnRconMessage;
}
/// <summary>
/// 获取当前配置
/// </summary>
/// <returns>配置对象</returns>
public object GetConfig() => _config;
/// <summary>
/// 更新配置
/// </summary>
/// <param name="config">JSON配置元素</param>
public void UpdateConfig(JsonElement config)
{
try
{
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
_config = JsonSerializer.Deserialize<CdkRedeemConfig>(config.GetRawText(), options) ?? new CdkRedeemConfig();
}
catch (Exception ex)
{
RainOpsLog.Log($"[{Name}] UpdateConfig Error: {ex.Message}");
}
}
/// <summary>
/// 重置配置为默认值
/// </summary>
public void ResetConfig()
{
_config = new CdkRedeemConfig();
}
/// <summary>
/// 释放资源,取消订阅
/// </summary>
public void Dispose()
{
Program.OnRconMessageReceived -= OnRconMessage;
}
/// <summary>
/// 处理RCON消息回调
/// </summary>
/// <param name="msg">消息内容</param>
private async void OnRconMessage(string msg)
{
if (!_config.Enabled) return;
try
{
// 格式 1: ChatMessage: [SteamID] Name : message (旧版/标准 RCON)
var match = Regex.Match(msg, @"ChatMessage: \[(?<steamId>\d+)\] (?<name>.+) : (?<content>.+)");
// 格式 2: [ChatChannel] [Online IDs:EOS: ... steam: SteamID] Name : message (新版/详细 RCON)
if (!match.Success)
{
match = Regex.Match(msg, @"\[Chat.+?\] \[Online IDs:EOS: .+? steam: (?<steamId>\d+)\]\s+(?<name>.+?) : (?<content>.+)");
}
if (!match.Success) return;
string steamId = match.Groups["steamId"].Value;
string content = match.Groups["content"].Value.Trim();
// 逻辑: 检查内容是否符合 CDK 格式 (以 CDK 开头, 长度 16)
if (content.Length == 16 && content.StartsWith("CDK", StringComparison.OrdinalIgnoreCase))
{
// 调用服务进行兑换
var (success, message) = await CdkService.RedeemCdkAsync(content, steamId);
// 发送响应
SendResponse(steamId, message);
}
}
catch (Exception ex)
{
RainOpsLog.Log($"[{Name}] Error: {ex.Message}");
}
}
/// <summary>
/// 发送响应消息给玩家
/// </summary>
/// <param name="steamId">玩家SteamID</param>
/// <param name="message">消息内容</param>
private void SendResponse(string steamId, string message)
{
string cmd = _config.Method switch
{
"AdminBroadcast" => $"AdminBroadcast {message}",
_ => $"AdminWarn {steamId} {message}"
};
// 发送命令到 RCON
_ = SendRconCommand(cmd);
}
/// <summary>
/// 发送RCON命令
/// </summary>
/// <param name="cmd">命令内容</param>
private async Task SendRconCommand(string cmd)
{
if (Program.Client != null)
{
await Program.Client.SendCommandAsync(cmd);
}
}
}
}