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

209 lines
7.3 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 System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using RainOpsMini.Helpers;
using RainOpsMini.Helpers.RCON;
using RainOpsMini.Models;
namespace RainOpsMini.Plugins
{
public class WelcomePlugin : IPlugin, IDisposable
{
public string Name => "欢迎语插件";
public string Description => "玩家进服欢迎提示VIP使用广播普通玩家使用警告";
public PluginCategory Category => PluginCategory.BasicFunction;
public bool IsEnabled => _config.Enabled;
private WelcomeConfig _config = new WelcomeConfig();
private readonly string _configPath;
private Timer? _timer;
private readonly HashSet<string> _welcomedSteamIds = new HashSet<string>();
private readonly object _lock = new object();
public WelcomePlugin()
{
_configPath = Path.Combine(Environment.CurrentDirectory, "PluginConfig", "WelcomeConfig.json");
LoadConfig();
ApplyConfig();
}
public object GetConfig() => _config;
public void UpdateConfig(JsonElement config)
{
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
_config = JsonSerializer.Deserialize<WelcomeConfig>(config.GetRawText(), options) ?? new WelcomeConfig();
SaveConfig();
ApplyConfig();
}
public void ResetConfig()
{
_config = new WelcomeConfig();
SaveConfig();
ApplyConfig();
}
private void LoadConfig()
{
if (File.Exists(_configPath))
{
try
{
var json = File.ReadAllText(_configPath);
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
_config = JsonSerializer.Deserialize<WelcomeConfig>(json, options) ?? new WelcomeConfig();
}
catch (Exception ex)
{
RainOpsLog.Log($"[WelcomePlugin] Load config failed: {ex.Message}");
}
}
else
{
SaveConfig();
}
}
private void SaveConfig()
{
try
{
var dir = Path.GetDirectoryName(_configPath);
if (dir != null && !Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
var json = JsonSerializer.Serialize(_config, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(_configPath, json);
}
catch (Exception ex)
{
RainOpsLog.Log($"[WelcomePlugin] Save config failed: {ex.Message}");
}
}
private void ApplyConfig()
{
if (_config.Enabled)
{
if (_timer == null)
{
_timer = new Timer(CheckPlayers, null, 5000, 5000); // Check every 5 seconds
}
}
else
{
_timer?.Dispose();
_timer = null;
lock (_lock)
{
_welcomedSteamIds.Clear();
}
}
}
private async void CheckPlayers(object? state)
{
try
{
// 拷贝一份数据,避免线程安全问题
List<PlayerInfo> players;
if (Program.RconCache?.Players != null)
{
players = new List<PlayerInfo>(Program.RconCache.Players);
}
else
{
return;
}
if (players.Count == 0) return;
var currentSteamIds = players.Select(p => p.SteamId).Where(s => !string.IsNullOrEmpty(s)).ToHashSet();
List<PlayerInfo> newPlayers = new List<PlayerInfo>();
lock (_lock)
{
// 移除已经不在服务器的玩家
_welcomedSteamIds.RemoveWhere(id => !currentSteamIds.Contains(id));
// 找出新玩家
foreach (var player in players)
{
if (!string.IsNullOrEmpty(player.SteamId) && !_welcomedSteamIds.Contains(player.SteamId))
{
_welcomedSteamIds.Add(player.SteamId);
var connectTime = RainOpsMini.Helpers.SquadGameLog.LogStorage.Instance.GetPlayerConnectTime(player.SteamId);
if (connectTime != null && Math.Abs((DateTime.Now - connectTime.Value).TotalSeconds) < 3)
{
newPlayers.Add(player);
}
}
}
}
foreach (var player in newPlayers)
{
await ProcessWelcome(player);
}
}
catch (Exception ex)
{
RainOpsLog.Log($"[WelcomePlugin] CheckPlayers error: {ex.Message}");
}
}
private async Task ProcessWelcome(PlayerInfo player)
{
try
{
var vip = VipStorage.GetBySteamId(player.SteamId);
bool isVip = vip != null && vip.ExpiryDate > DateTime.Now;
if (isVip)
{
// VIP/SVIP 欢迎语 - 广播
string message = !string.IsNullOrWhiteSpace(vip!.WelcomeMessage)
? vip.WelcomeMessage
: (vip.Group == "SVIP_RainOpsMini" ? _config.DefaultSvipWelcomeMessage : _config.DefaultVipWelcomeMessage);
if (!string.IsNullOrWhiteSpace(message))
{
message = message.Replace("{Name}", player.Name);
// AdminBroadcast <Message>
await Program.Client.SendCommandAsync($"AdminBroadcast {message}");
RainOpsLog.Log($"[WelcomePlugin] VIP Welcome broadcast for {player.Name}: {message}");
}
}
else
{
// 普通玩家欢迎语 - 警告
if (_config.GeneralWelcomeEnabled && !string.IsNullOrWhiteSpace(_config.GeneralWelcomeMessage))
{
string message = _config.GeneralWelcomeMessage.Replace("{Name}", player.Name);
// AdminWarn <SteamId> <Message>
await Program.Client.SendCommandAsync($"AdminWarn {player.SteamId} {message}");
RainOpsLog.Log($"[WelcomePlugin] General Welcome warn for {player.Name}: {message}");
}
}
}
catch (Exception ex)
{
RainOpsLog.Log($"[WelcomePlugin] ProcessWelcome error for {player.Name}: {ex.Message}");
}
}
public void Dispose()
{
_timer?.Dispose();
}
}
}