C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Requires: Coroutines
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins
{
[Info("Name Changer", "birthdates", "1.0.1")]
[Description("Listen for profile name changes")]
public class NameChanger : CovalencePlugin
{
#region Hooks
private void OnServerInitialized()
{
timer.Every(_config.CheckInterval, CheckProfiles);
}
#endregion
#region Variables
/// <summary>
/// The link for Steam profile's as XML
/// </summary>
private const string ProfileURL = "https://steamcommunity.com/profiles/{0}?xml=1";
/// <summary>
/// The regex that captures the name of a XML profile
/// </summary>
private Regex NameRegex { get; } = new Regex("(?<=<steamID><!\\[CDATA\\[).*(?=]]>)");
#endregion
#region Core Logic
/// <summary>
/// Asynchronously loop through all connected players and check for name changes
/// </summary>
private void CheckProfiles()
{
var coroutine = Coroutines.Instance.LoopListAsynchronously(this, new Action<IPlayer>(CheckProfile),
new List<IPlayer>(covalence.Players.Connected), 0.05f, completePerTick: 3, id: "ProfileCheck");
Coroutines.Instance.StartCoroutine(coroutine);
}
/// <summary>
/// Asynchronously enqueue a web request to check a player's Steam profile name
/// </summary>
/// <param name="player">Target name</param>
private void CheckProfile(IPlayer player)
{
webrequest.Enqueue(string.Format(ProfileURL, player.Id), string.Empty,
(code, response) => HandleProfile(player, code, response), this);
}
/// <summary>
/// Handle the web request's response from <see cref="CheckProfile" />
/// </summary>
/// <param name="player">Target player</param>
/// <param name="code">Response code</param>
/// <param name="response">Response data</param>
private void HandleProfile(IPlayer player, int code, string response)
{
// See if Steam response was valid
if (code != 200)
{
PrintError("Steam servers did not give code 200: {0} ({1})", response, code);
return;
}
// Try match name
var result = NameRegex.Match(response);
if (!result.Success)
{
PrintError("Failed to retrieve name for: {0} ({1})", player.Name, player.Id);
return;
}
// Rename
var name = result.Value;
if (player.Name.Equals(name)) return;
// Notify
foreach (var target in covalence.Players.Connected)
{
var msg = lang.GetMessage("UserNameChanged", this, target.Id);
if (string.IsNullOrEmpty(msg)) break;
target.Message(string.Format(msg, player.Name, name));
}
player.Rename(name);
player.Name = name;
}
#endregion
#region Configuration & Localization
private ConfigFile _config;
protected override void LoadConfig()
{
base.LoadConfig();
_config = Config.ReadObject<ConfigFile>();
if (_config == null) LoadDefaultConfig();
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
{"UserNameChanged", "{0} has changed their name to {1}"}
}, this);
}
protected override void LoadDefaultConfig()
{
_config = ConfigFile.DefaultConfig();
PrintWarning("Default configuration has been loaded.");
}
protected override void SaveConfig()
{
Config.WriteObject(_config);
}
private class ConfigFile
{
[JsonProperty("Check Interval (seconds)")]
public float CheckInterval { get; set; }
public static ConfigFile DefaultConfig()
{
return new ConfigFile
{
CheckInterval = 30f
};
}
}
#endregion
}
}