C#:
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("AuthMe", "", "1.5.6")]
public class AuthMe : RustPlugin
{
[JsonProperty("Информация об игроках")]
private static Dictionary<ulong, DataAuthorize> _dataAuthorizes = new Dictionary<ulong, DataAuthorize>();
[JsonProperty("Слой с интерфейсом")] private static readonly string Layer = "UI.Login";
private readonly Dictionary<string, string> _cacheHexColors = new Dictionary<string, string>();
[ConsoleCommand("auth")]
private void CmdAuthConsole(ConsoleSystem.Arg arg)
{
BasePlayer player;
if (!ParsePlayer(arg, out player))
return;
if (!_dataAuthorizes.ContainsKey(player.userID))
PlayerInit(player);
if (!arg.HasArgs() || arg.ArgsStr.Length < 6 || !Regex.Match(arg.ArgsStr, "^[А-Яа-яA-Za-z0-9\\s]+$").Success)
{
player.SendConsoleCommand($"echo {GetMessageLanguage("Registration.EmptyPassword", player.UserIDString)}");
return;
}
var password = arg.ArgsStr;
var dataAuthorize = _dataAuthorizes[player.userID];
if (dataAuthorize.IsAuthed)
return;
if (dataAuthorize.Player == null)
dataAuthorize.Player = player;
if (string.IsNullOrEmpty(dataAuthorize.Password))
{
player.SendConsoleCommand($"echo {GetMessageLanguage("Registration.Successful", player.UserIDString).Replace("{0}", password)}");
dataAuthorize.Password = password;
}
else if (password == dataAuthorize.Password)
{
player.SendConsoleCommand($"echo {GetMessageLanguage("Authorized.Successful", player.UserIDString)}");
dataAuthorize.authAttempts = 0;
player.SetPlayerFlag(BasePlayer.PlayerFlags.ChatMute, false);
player.SetPlayerFlag(BasePlayer.PlayerFlags.VoiceMuted, false);
player.SetPlayerFlag(BasePlayer.PlayerFlags.NoSprint, false);
}
if (password != dataAuthorize.Password)
{
player.SendConsoleCommand($"echo {GetMessageLanguage("Authorized.BadPassword", player.UserIDString)}");
++dataAuthorize.authAttempts;
if (dataAuthorize.authAttempts > 3)
{
dataAuthorize.authAttempts = 0;
player.Kick("Слишком много попыток ввода пароля.");
}
return;
}
dataAuthorize.IsAuthed = true;
dataAuthorize.AuthPlayer();
}
private void ForceAuthorization(BasePlayer player, bool timeout = false)
{
if (player == null)
return;
var buffer = _dataAuthorizes[player.userID];
if(timeout)
{
buffer.Timer.Destroy();
player.Kick("Время на ввод пароля истекло!");
return;
}
if (buffer.IsAuthed)
return;
try
{
if (string.IsNullOrEmpty(buffer.Password))
{
timer.Once(3, () => player.SendConsoleCommand($"echo {GetMessageLanguage("Help.Registration", player.UserIDString).Replace("{0}", ParseIp(player.net.connection.ipaddress))}"));
buffer.Timer = timer.Once(120, () => ForceAuthorization(player, true));
return;
}
player.SetPlayerFlag(BasePlayer.PlayerFlags.ChatMute, true);
player.SetPlayerFlag(BasePlayer.PlayerFlags.VoiceMuted, true);
player.SetPlayerFlag(BasePlayer.PlayerFlags.NoSprint, true);
timer.Once(3, () => player.SendConsoleCommand($"echo {GetMessageLanguage("Help.Authorization", player.UserIDString).Replace("{0}", ParseIp(player.net.connection.ipaddress))}"));
player.Teleport(buffer.LastPosition);
buffer.Timer = timer.Once(120, () => ForceAuthorization(player, true));
}
catch { }
}
private void InitPlayers()
{
foreach (var player in BasePlayer.activePlayerList)
PlayerInit(player);
}
#region Messages
private void LoadMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Authorized.Ip"] = "<color=#AADC80>(АВТОРИЗАЦИЯ)</color> Вы автоматически <color=#AADC80>авторизовались</color>",
["Registration.EmptyPassword"] = "<color=red>[Регистрация]</color> <color=white>Пароль должен быть не менее 6 символов и состоять из следующих символов:</color> <color=grey>А-я A-z 0-9</color>",
["Registration.Successful"] = "<color=red>[Регистрация]</color> <color=white>Вы успешно зарегистрировались на сервере!</color>\n" +
"<color=red>[Регистрация]</color> <color=white>Ваш пароль:</color> <color=#AADC80>{0}</color>",
["Authorized.Successful"] = "<color=#AADC80>[Авторизация]</color> <color=white>Вы успешно авторизовались на сервере!</color>",
["Authorized.BadPassword"] = "<color=#AADC80>[Авторизация]</color> <color=white>Вы ввели не корректный пароль, попробуйте ещё раз!</color>" +
"<color=#AADC80>[Авторизация]</color> <color=white>Используйте:</color> <color=red>auth [ваш пароль]</color>",
["Registration.Need"] = "Зарегистрируйтесь",
["Authorized.Need"] = "Авторизуйтесь",
["Help.Info"] = "Откройте консоль (F1) для ввода пароля",
["Help.Registration"] =
"<color=red>[Регистрация]</color> <color=white>Приветствуем! Ваш аккаунт не зарегистрирован на сервере!</color>\n" +
"<color=red>[Регистрация]</color> <color=white>После успешного ввода пароля, данный IP (</color><color=grey>{0}</color><color=white>) будет привязан к аккаунту</color>\n" +
"<color=red>[Регистрация]</color> <color=white>Используйте: </color><color=red>auth [пароль]</color> <color=grey>(Не менее 6 символов, разрешенные символы: А-я A-z 0-9)</color>",
["Help.Authorization"] = "<color=#AADC80>[Авторизация]</color> <color=white>Приветствуем! Ваш аккаунт зарегистрирован на сервере!</color>\n" +
"<color=#AADC80>[Авторизация]</color> <color=white>После успешного ввода пароля, данный IP (</color><color=grey>{0}</color><color=white>) будет привязан к аккаунту</color>\n" +
"<color=#AADC80>[Авторизация]</color> <color=white>Используйте: </color><color=red>auth [пароль]</color>"
}, this);
}
#endregion
private void PlayerInit(BasePlayer player)
{
var IP = ParseIp(player.net.connection.ipaddress);
if (!_dataAuthorizes.ContainsKey(player.userID))
{
var dataAuthorize = new DataAuthorize
{
ListAuthedIps = new List<string>(),
LastPosition = player.transform.position,
IsAuthed = false,
Player = player
};
DataAuthorize.AddPlayerToData(player.userID, dataAuthorize);
}
else
{
var dataAuthorize = _dataAuthorizes[player.userID];
dataAuthorize.LastPosition = player.transform.position;
dataAuthorize.IsAuthed = false;
if (dataAuthorize.ListAuthedIps.Contains(IP))
{
dataAuthorize.IsAuthed = true;
player.ChatMessage(GetMessageLanguage("Authorized.Ip", player.UserIDString).Replace("{0}", IP));
return;
}
}
ForceAuthorization(player);
DrawInterface(player);
}
private void DrawInterface(BasePlayer player)
{
CuiHelper.DestroyUi(player, Layer);
var container = new CuiElementContainer();
var action = string.IsNullOrEmpty(_dataAuthorizes[player.userID].Password)
? GetMessageLanguage("Registration.Need", player.UserIDString)
: GetMessageLanguage("Authorized.Need", player.UserIDString);
#region CuiElements
container.Add(new CuiPanel
{
FadeOut = 2f,
CursorEnabled = true,
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
Image = { FadeIn = 2f, Color = HexToRustFormat("#141414") }
}, "Overlay", Layer);
container.Add(new CuiButton
{
FadeOut = 2f,
RectTransform = { AnchorMin = "0.3347656 0.4388889", AnchorMax = "0.6652344 0.5611111" },
Text =
{
FadeIn = 2f, Text = "", FontSize = 32, Font = "robotocondensed-regular.ttf",
Align = TextAnchor.MiddleCenter
},
Button = { FadeIn = 2f, Color = HexToRustFormat("#525252") }
}, Layer, Layer + ".Hide");
container.Add(new CuiLabel
{
FadeOut = 2f,
RectTransform = { AnchorMin = "0 0.3", AnchorMax = "1 1" },
Text =
{
FadeIn = 2f, Text = action, FontSize = 38, Font = "robotocondensed-regular.ttf",
Align = TextAnchor.MiddleCenter,
Color = HexToRustFormat("#d2e9ff"),
}
}, Layer + ".Hide", Layer + ".Hide1");
container.Add(new CuiLabel
{
FadeOut = 2f,
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.5" },
Text =
{
FadeIn = 2f, Text = GetMessageLanguage("Help.Info", player.UserIDString), FontSize = 22,
Font = "robotocondensed-regular.ttf",
Align = TextAnchor.MiddleCenter,
Color = HexToRustFormat("#d2e9ff")
}
}, Layer + ".Hide", Layer + ".Hide2");
#endregion
CuiHelper.AddUi(player, container);
}
private class DataAuthorize
{
[JsonIgnore] public BasePlayer Player;
[JsonIgnore] public bool IsAuthed;
[JsonIgnore] public Vector3 LastPosition;
[JsonProperty("Авторизованные IP адреса")]
public List<string> ListAuthedIps;
[JsonProperty("Пароль пользователя")] public string Password;
[JsonIgnore] public Timer Timer;
[JsonIgnore] public int authAttempts;
public void AuthPlayer()
{
if (Timer != null && !Timer.Destroyed)
Timer.Destroy();
string ip = ParseIp(Player.net.connection.ipaddress);
if (!ListAuthedIps.Contains(ip))
ListAuthedIps.Add(ip);
DestroyUi();
}
private void DestroyUi()
{
CuiHelper.DestroyUi(Player, Layer + ".Hide2");
CuiHelper.DestroyUi(Player, Layer + ".Hide1");
CuiHelper.DestroyUi(Player, Layer + ".Hide");
CuiHelper.DestroyUi(Player, Layer);
}
public static void AddPlayerToData(ulong steamid, DataAuthorize dataAuthorize)
{
_dataAuthorizes.Add(steamid, dataAuthorize);
}
}
#region Hooks
private void Init()
{
LoadData();
LoadMessages();
InitPlayers();
}
private void OnServerSave()
{
SaveData();
}
private void Unload()
{
SaveData();
}
private object OnServerCommand(ConsoleSystem.Arg arg)
{
BasePlayer player;
if (arg?.Player() == null)
return null;
if (!ParsePlayer(arg, out player))
return false;
if (!_dataAuthorizes.ContainsKey(player.userID))
return false;
var buffer = _dataAuthorizes[player.userID];
if (!buffer.IsAuthed && arg.cmd.namefull.ToLower() != "global.auth")
return false;
return null;
}
private void OnPlayerInit(BasePlayer player)
{
if (player.IsReceivingSnapshot())
{
timer.Once(1f, () => OnPlayerInit(player));
return;
}
PlayerInit(player);
}
#endregion
#region Data
private static void SaveData()
{
Interface.Oxide.DataFileSystem.WriteObject("AuthMe/Users", _dataAuthorizes);
}
private void LoadData()
{
_dataAuthorizes = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, DataAuthorize>>("AuthMe/Users");
}
#endregion
#region Helper
private static string ParseIp(string input)
{
if (input.Contains(":"))
return input.Split(':')[0];
return input;
}
private string GetMessageLanguage(string key, string userId)
{
return lang.GetMessage(key, this, userId);
}
private string HexToRustFormat(string hex)
{
if (string.IsNullOrEmpty(hex)) hex = "#FFFFFFFF";
if (_cacheHexColors.ContainsKey(hex))
return _cacheHexColors[hex];
var str = hex.Trim('#');
if (str.Length == 6)
str += "FF";
var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
var a = byte.Parse(str.Substring(6, 2), NumberStyles.HexNumber);
Color color = new Color32(r, g, b, a);
var textColor = string.Format("{0:F2} {1:F2} {2:F2} {3:F2}", color.r, color.g, color.b, color.a);
_cacheHexColors.Add(hex, textColor);
return textColor;
}
private bool ParsePlayer(ConsoleSystem.Arg arg, out BasePlayer basePlayer)
{
basePlayer = null;
if (arg.connection.connected == false)
return false;
var player = arg.Player();
if (player == null)
return false;
basePlayer = player;
return true;
}
#endregion
}
}