C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using UnityEngine.Networking;
using System;
using Oxide.Core;
using ConVar;
using Oxide.Core.Database;
using Newtonsoft.Json;
using UnityEngine;
using System.Text.RegularExpressions;
using System.Text;
using Object = System.Object;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace Oxide.Plugins {
[Info("IQPermissions", "Mercury", "1.8.32")]
[Description("Extended privilege granting system")]
public class IQPermissions : RustPlugin {
private void Unload() {
_.InformationPrivilagesUser.RemoveParametresUnload();
WriteData();
if (coroutineMigration != null) {
ServerMgr.Instance.StopCoroutine(coroutineMigration);
coroutineMigration = null;
}
if (RoutineQueue != null) {
foreach (KeyValuePair<UInt64, Coroutine> keyValuePair in RoutineQueue.Where(r => r.Value != null)) ServerMgr.Instance.StopCoroutine(keyValuePair.Value);
RoutineQueue.Clear();
}
InterfaceBuilder.DestroyAll();
if (_imageUI != null) {
_imageUI.UnloadImages();
_imageUI = null;
}
sqlLibrary.CloseDb(sqlConnection);
_.IsFullLoaded = false;
_ = null;
}
private Boolean TryParseTimeSpan(String source, out TimeSpan timeSpan) {
Int32 seconds = 0, minutes = 0, hours = 0, days = 0;
Match s = new Regex(@"(\d+?)s", RegexOptions.IgnoreCase).Match(source);
Match m = new Regex(@"(\d+?)m", RegexOptions.IgnoreCase).Match(source);
Match h = new Regex(@"(\d+?)h", RegexOptions.IgnoreCase).Match(source);
Match d = new Regex(@"(\d+?)d", RegexOptions.IgnoreCase).Match(source);
if (s.Success) seconds = Convert.ToInt32(s.Groups[1].ToString());
if (m.Success) minutes = Convert.ToInt32(m.Groups[1].ToString());
if (h.Success) hours = Convert.ToInt32(h.Groups[1].ToString());
if (d.Success) days = Convert.ToInt32(d.Groups[1].ToString());
source = source.Replace(seconds + "s", string.Empty);
source = source.Replace(minutes + "m", string.Empty);
source = source.Replace(hours + "h", string.Empty);
source = source.Replace(days + "d", string.Empty);
if (!String.IsNullOrEmpty(source) || (!s.Success && !m.Success && !h.Success && !d.Success)) {
timeSpan = default(TimeSpan);
return false;
}
timeSpan = new TimeSpan(days, hours, minutes, seconds);
return true;
}
private String Format(Int32 units, String form1, String form2, String form3) {
var tmp = units % 10;
if (units >= 5 && units <= 20 || tmp >= 5 && tmp <= 9) return $"{units}{form1}";
if (tmp >= 2 && tmp <= 4) return $"{units}{form2}";
return $"{units}{form3}";
}
private String GetDescription(String UserID, TypeAlert typeAlert, String ReplaceKey, String DataExpired) {
String Lang = typeAlert == TypeAlert.Add ? GetLang("DESCRIPTION_ALERT_ADD", UserID, ReplaceKey) : typeAlert == TypeAlert.Expired ? GetLang("DESCRIPTION_ALERT_EXPIRED", UserID, ReplaceKey) : typeAlert == TypeAlert.Alert ? GetLang("DESCRIPTION_ALERT_INFO", UserID, ReplaceKey, DataExpired) : String.Empty;
return Lang;
}
private static String GetIcon(TypeAlert typeAlert) {
Configuration.InterfaceConfiguration Interfaces = config.InterfaceSetting;
String Icon = typeAlert == TypeAlert.Add ? "UI_ICON_PRIVILAGE_ADD" : typeAlert == TypeAlert.Expired ? "UI_ICON_PRIVILAGE_EXPIRED" : typeAlert == TypeAlert.Alert ? "UI_ICON_PRIVILAGE_ALERT" : String.Empty;
return _imageUI.GetImage(Icon);
}
private String GetLanguageNamePrivilage(BasePlayer player, String Key, TypeData type) {
String ReplaceKey = String.Empty;
switch (type) {
case TypeData.Permission : {
if (config.PermissionList.ContainsKey(Key)) {
ReplaceKey = lang.GetLanguage(player.UserIDString) == "ru" ? config.PermissionList[Key].RussianName : config.PermissionList[Key].EnglishName;
return ReplaceKey;
}
break;
}
case TypeData.Group : if (config.GroupList.ContainsKey(Key)) {
ReplaceKey = lang.GetLanguage(player.UserIDString) == "ru" ? config.GroupList[Key].RussianName : config.GroupList[Key].EnglishName;
return ReplaceKey;
}
break;
}
return null;
}
private class ImageUI {
private const String _path = "IQSystem/IQPermissions/Images/";
private const String _printPath = "data/" + _path;
private readonly Dictionary<String, ImageData> _images = new() {
{
"UI_BACKGROUND_PANEL", new ImageData()
}
, {
"UI_ICON_PRIVILAGE_ADD", new ImageData()
}
, {
"UI_ICON_PRIVILAGE_ALERT", new ImageData()
}
, {
"UI_ICON_PRIVILAGE_EXPIRED", new ImageData()
}
,
}
;
private enum ImageStatus {
NotLoaded, Loaded, Failed
}
private class ImageData {
public ImageStatus Status = ImageStatus.NotLoaded;
public string Id {
get;
set;
}
}
public string GetImage(string name) {
ImageData image;
if (_images.TryGetValue(name, out image) && image.Status == ImageStatus.Loaded) return image.Id;
return null;
}
public void DownloadImage() {
KeyValuePair<string, ImageData>? image = null;
foreach (KeyValuePair<string, ImageData> img in _images) {
if (img.Value.Status == ImageStatus.NotLoaded) {
image = img;
break;
}
}
if (image != null) {
ServerMgr.Instance.StartCoroutine(ProcessDownloadImage(image.Value));
}
else {
List<String> failedImages = new List<string>();
foreach (KeyValuePair<String, ImageData> img in _images) {
if (img.Value.Status == ImageStatus.Failed) {
failedImages.Add(img.Key);
}
}
if (failedImages.Count > 0) {
String images = String.Join(", ", failedImages);
_.PrintError(LanguageEn ? $"Failed to load the following images: {images}.Perhaps you did not upload them to the '{_printPath}' folder.\nDownloaded image - https://drive.google.com/drive/folders/1vfRDKpMtDoBkOaTeFrcLGUXTi-6AOS26?usp=sharing" : $"Не удалось загрузить следующие изображения: {images}.Возможно, вы не загрузили их в папку '{_printPath}'.\nСкачать можно тут - https://drive.google.com/drive/folders/1vfRDKpMtDoBkOaTeFrcLGUXTi-6AOS26?usp=sharing");
Interface.Oxide.UnloadPlugin(_.Name);
}
else {
_.Puts(LanguageEn ? $"{_images.Count} images downloaded successfully!" : $"{_images.Count} изображений успешно загружено!");
_interface = new InterfaceBuilder();
_.SQL_OpenConnection();
_.timer.Every(1f, () => _.InformationPrivilagesUser.TrackerExpireds());
_.IsFullLoaded = true;
_.timer.Every(300f, () => _.WriteData());
}
}
}
public void UnloadImages() {
foreach (KeyValuePair<string, ImageData> item in _images) if(item.Value.Status == ImageStatus.Loaded) if (item.Value?.Id != null) FileStorage.server.Remove(uint.Parse(item.Value.Id), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID);
_images?.Clear();
}
private IEnumerator ProcessDownloadImage(KeyValuePair<string, ImageData> image) {
string url = $"file://{Interface.Oxide.DataDirectory}/{_path}{image.Key}.png";
using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(url)) {
yield return www.SendWebRequest();
if (www.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError) {
image.Value.Status = ImageStatus.Failed;
}
else {
Texture2D tex = DownloadHandlerTexture.GetContent(www);
image.Value.Id = FileStorage.server.Store(tex.EncodeToPNG(), FileStorage.Type.png, CommunityEntity.ServerInstance.net.ID).ToString();
image.Value.Status = ImageStatus.Loaded;
UnityEngine.Object.DestroyImmediate(tex);
}
DownloadImage();
}
}
}
private static InterfaceBuilder _interface;
private void DeleteDatabase(String UserID, TypeData typeData, String Key) {
if (sqlConnection == null) return;
String Permission = typeData == TypeData.Permission ? Key : String.Empty;
String Group = typeData == TypeData.Group ? Key : String.Empty;
String sqlQuery = typeData == TypeData.Permission ? $"DELETE FROM `{config.GeneralSettings.MySQLSetting.TableName}` WHERE `steamid` = @0 AND `permission` = @1" : $"DELETE FROM `{config.GeneralSettings.MySQLSetting.TableName}` WHERE `steamid` = @0 AND`group` = @1";
Sql deleteCommand = Oxide.Core.Database.Sql.Builder.Append(sqlQuery, UserID, typeData == TypeData.Permission ? Permission : Group);
sqlLibrary.Delete(deleteCommand, sqlConnection, rowsAffected => {
Puts(LanguageEn ? "The user's information was deleted in the database" : "В БД была удалена информация пользователя");
}
);
}
private static Int64 ToEpochTime(DateTime dateTime) {
DateTime date = dateTime.ToLocalTime();
Int64 ticks = date.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks;
Int64 ts = ticks / TimeSpan.TicksPerSecond;
return ts;
}
[ConsoleCommand("addgroup")]
private void AddGroup_ConsoleCommand(ConsoleSystem.Arg arg) {
if (arg == null) return;
if(arg.Player() != null) if(!arg.Player().IsAdmin) return;
if (arg.Args == null || arg.Args.Length < 3 ) {
arg.ReplyWith(LanguageEn ? "Syntax error, use: addgroup Steam64ID Group Time(1d/1h/1m/1s)\nПример : addgroup 7656119728278887930 vip 1d" : "Ошибка синтаксиса, используйте : addgroup Steam64ID Group Time(1d/1h/1m/1s)\nПример : addgroup 76561197235887930 vip 1d");
return;
}
UInt64 userID;
if (!UInt64.TryParse(arg.Args[0], out userID)) {
arg.ReplyWith(LanguageEn ? "You have specified an incorrect Steam64ID player!" : "Вы указали неккоректный Steam64ID игрока!");
return;
}
String Group = arg.Args[1];
if (!config.GroupList.ContainsKey(Group)) {
arg.ReplyWith(LanguageEn ? "The group you specified do not exist!" : "Группа которую вы указали - не существуют!");
return;
}
TimeSpan duration;
if (!TryParseTimeSpan(arg.Args[2], out duration)) {
arg.ReplyWith(LanguageEn ? "You specified an incorrect time, use 1d/1h/1m/1s!" : "Вы указали неккоректное время, используйте 1d/1h/1m/1s!");
return;
}
DateTime ThisTime = InformationPrivilagesUser.GetExpiredPermissionData(Group, userID, TypeData.Group) + duration;
InformationPrivilagesUser.SetParametres(Group, userID, ThisTime, TypeData.Group);
}
[ConsoleCommand("grantperm")]
private void GrantPerm_ConsoleCommand(ConsoleSystem.Arg arg) {
if (arg == null) return;
if(arg.Player() != null) if(!arg.Player().IsAdmin) return;
if (arg.Args == null || arg.Args.Length < 3 ) {
arg.ReplyWith(LanguageEn ? "Syntax error, use: grantperm Steam64ID Permission Time(1d/1h/1m/1s)\nExample : grantperm 76561182789787930 iqchat.vip 1d" : "Ошибка синтаксиса, используйте : grantperm Steam64ID Permission Time(1d/1h/1m/1s)\nПример : grantperm 76561182789787930 iqchat.vip 1d");
return;
}
UInt64 userID;
if (!UInt64.TryParse(arg.Args[0], out userID)) {
arg.ReplyWith(LanguageEn ? "You have specified an incorrect Steam64ID player!" : "Вы указали неккоректный Steam64ID игрока!");
return;
}
String Permission = arg.Args[1];
if (!config.PermissionList.ContainsKey(Permission)) {
arg.ReplyWith(LanguageEn ? "The permission you specified do not exist!" : "Права которые вы указали - не существуют!");
return;
}
TimeSpan duration;
if (!TryParseTimeSpan(arg.Args[2], out duration)) {
arg.ReplyWith(LanguageEn ? "You specified an incorrect time, use 1d/1h/1m/1s!" : "Вы указали неккоректное время, используйте 1d/1h/1m/1s!");
return;
}
DateTime ThisTime = InformationPrivilagesUser.GetExpiredPermissionData(Permission, userID, TypeData.Permission) + duration;
InformationPrivilagesUser.SetParametres(Permission, userID, ThisTime, TypeData.Permission);
}
private void Request(String url, String payload, Action<Int32> callback = null) {
Dictionary<String, String> header = new Dictionary<String, String>();
header.Add("Content-Type", "application/json");
webrequest.Enqueue(url, payload, (code, response) => {
if (code != 200 && code != 204) {
if (response != null) {
try {
JObject json = JObject.Parse(response);
if (code == 429) {
Single seconds = Single.Parse(Math.Ceiling((Double)(Int32)json["retry_after"] / 1000).ToString());
}
else {
PrintWarning($" Discord rejected that payload! Responded with \"{json["message"].ToString()}\" Code: {code}");
}
}
catch {
PrintWarning($"Failed to get a valid response from discord! Error: \"{response}\" Code: {code}");
}
}
else {
PrintWarning($"Discord didn't respond (down?) Code: {code}");
}
}
try {
callback?.Invoke(code);
}
catch (Exception ex) {
}
}
, this, RequestMethod.POST, header);
}
[ConsoleCommand("grant.group")]
private void AddGroup_TwoConsoleCommand(ConsoleSystem.Arg arg) => AddGroup_ConsoleCommand(arg);
private void Init() {
_ = this;
ReadData();
}
private String GetLeftTime(DateTime dateExpired, String userID) {
System.TimeSpan DiffTime = dateExpired.Subtract(DateTime.Now);
String LeftTime = _.FormatTime(TimeSpan.FromSeconds(DiffTime.TotalSeconds), userID);
return LeftTime;
}
public String FormatTime(TimeSpan time, String UserID) {
String Result = String.Empty;
String Days = GetLang("TITLE_FORMAT_DAYS", UserID);
String Hourse = GetLang("TITLE_FORMAT_HOURSE", UserID);
String Minutes = GetLang("TITLE_FORMAT_MINUTES", UserID);
String Seconds = GetLang("TITLE_FORMAT_SECONDS", UserID);
if (time.Days != 0) Result += $"{Format(time.Days, Days, Days, Days)} ";
if (time.Hours != 0) Result += $"{Format(time.Hours, Hourse, Hourse, Hourse)} ";
if (time.Minutes != 0) Result += $"{Format(time.Minutes, Minutes, Minutes, Minutes)} ";
if (time.Days == 0 && time.Hours == 0 && time.Minutes == 0 && time.Seconds != 0) Result = $"{Format(time.Seconds, Seconds, Seconds, Seconds)} ";
return Result;
}
[PluginReference]
Plugin IQChat, UAlertSystem;
[ConsoleCommand("perm.users")]
private void GetInfoPerm_ConsoleCommand(ConsoleSystem.Arg arg) {
if (arg == null) return;
if(arg.Player() != null) if(!arg.Player().IsAdmin) return;
if (arg.Args == null || arg.Args.Length < 1) {
arg.ReplyWith(LanguageEn ? "Syntax error, use: perm.users Permission" : "Ошибка синтаксиса, используйте : perm.users Permission");
return;
}
String Permission = arg.Args[0];
if (!config.PermissionList.ContainsKey(Permission)) {
arg.ReplyWith(LanguageEn ? "The permission you specified do not exist!" : "Права которые вы указали - не существуют!");
return;
}
Dictionary<UInt64, DateTime> GetPlayers = InformationPrivilagesUser.GePlayerList(Permission, TypeData.Permission);
String PlayerList = GetPlayers == null ? String.Empty : GetPlayers.Aggregate(String.Empty, (current, Players) => current + $"- ID : {Players.Key} | Expired : {GetLeftTime(Players.Value, Players.Key.ToString())}\n");
String Information = LanguageEn ? $"Total with active privileges ({Permission}) found {GetPlayers.Count} players\n{PlayerList}" : $"Всего с активной привилегий ({Permission}) найдено {GetPlayers.Count} игроков\n{PlayerList}";
arg.ReplyWith(Information);
}
private void PreLoadedPlugin() {
_imageUI = new ImageUI();
_imageUI.DownloadImage();
}
private String SQL_Query_InsertUser() {
String InserUser = $"INSERT INTO `{config.GeneralSettings.MySQLSetting.TableName}`" + "(`steamid`, `permission`, `group`, `data_expired`) VALUES ('{0}','{1}','{2}','{3}')";
return InserUser;
}
private void ReadData() {
OldPlayers = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<List<UInt64>>("IQSystem/IQPermissions/OldPlayers");
if (sqlConnection != null) return;
InformationPrivilagesUser = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<StructureData>("IQSystem/IQPermissions/Permissions");
}
private void OnPlayerConnected(BasePlayer player) {
MigrationPrivilage(player);
SetupAutoPrivilages(player);
if (!config.AlertConfigurations.UseAlertedGroup && !config.AlertConfigurations.UseAlertedPermission) return;
player.Invoke(() => {
if (!RoutineQueue.ContainsKey(player.userID)) RoutineQueue.Add(player.userID, ServerMgr.Instance.StartCoroutine(JoinedAlertPlayer(player)));
else RoutineQueue[player.userID] = ServerMgr.Instance.StartCoroutine(JoinedAlertPlayer(player));
}
, 10f);
}
[JsonProperty(LanguageEn ? "Information about privileges" : "Информация о привилегиях")]
private StructureData InformationPrivilagesUser = new StructureData();
[ConsoleCommand("migration.grant")]
private void GrantMigration(ConsoleSystem.Arg arg) {
if (arg.Player() != null) return;
coroutineMigration = ServerMgr.Instance.StartCoroutine(MigrationGrant());
}
[ConsoleCommand("revoke.permission")]
private void RevokePerm_TwoConsoleCommand(ConsoleSystem.Arg arg) => RevokePerm_ConsoleCommand(arg);
private IEnumerator JoinedAlertPlayer(BasePlayer player) {
if (config.AlertConfigurations.UseAlertedPermission) {
foreach (KeyValuePair<String, Dictionary<UInt64, DateTime>> userPermission in InformationPrivilagesUser.UserPermissions.Where(userPermission => userPermission.Value.ContainsKey(player.userID) && config.AlertConfigurations.PermissionsListAlerted.Contains(userPermission.Key)).Where(userPermission => ((userPermission.Value[player.userID] - DateTime.Now).Days + 1) <= config.AlertConfigurations.DayAlerted)) {
AlertPlayer(player.userID, TypeAlert.Alert, userPermission.Key, TypeData.Permission, $"{GetLeftTime(userPermission.Value[player.userID], player.UserIDString)}");
yield return CoroutineEx.waitForSeconds(config.AlertConfigurations.TimeAlert + 2f);
}
}
if (config.AlertConfigurations.UseAlertedGroup) {
foreach (KeyValuePair<String, Dictionary<UInt64, DateTime>> userGroup in InformationPrivilagesUser.UserGrpups.Where(userGroup => userGroup.Value.ContainsKey(player.userID) && config.AlertConfigurations.GrpupListAlerted.Contains(userGroup.Key)).Where(userGroup => ((userGroup.Value[player.userID] - DateTime.Now).Days + 1) <= config.AlertConfigurations.DayAlerted)) {
AlertPlayer(player.userID, TypeAlert.Alert, userGroup.Key, TypeData.Group, $"{GetLeftTime(userGroup.Value[player.userID], player.UserIDString)}");
yield return CoroutineEx.waitForSeconds(config.AlertConfigurations.TimeAlert + 2f);
}
}
// CuiHelper.DestroyUi(player, InterfaceBuilder.UI_POOPUP_PANEL);
if (RoutineQueue == null) yield break;
if (!RoutineQueue.ContainsKey(player.userID)) yield break;
if (RoutineQueue[player.userID] != null) ServerMgr.Instance.StopCoroutine(RoutineQueue[player.userID]);
RoutineQueue.Remove(player.userID);
}
[ConsoleCommand("user.groups")]
private void GetUserGroups_ConsoleCommand(ConsoleSystem.Arg arg) {
if (arg == null) return;
if(arg.Player() != null) if(!arg.Player().IsAdmin) return;
if (arg.Args == null || arg.Args.Length < 1) {
arg.ReplyWith(LanguageEn ? "Syntax error, use: user.groups Steam64ID" : "Ошибка синтаксиса, используйте : user.groups Steam64ID");
return;
}
UInt64 userID;
if (!UInt64.TryParse(arg.Args[0], out userID)) {
arg.ReplyWith(LanguageEn ? "You have specified an incorrect Steam64ID player!" : "Вы указали неккоректный Steam64ID игрока!");
return;
}
Dictionary<String, DateTime> GetParametres = InformationPrivilagesUser.GetParametresUser(userID, TypeData.Group);
String PermsList = GetParametres == null ? String.Empty : GetParametres.Aggregate(String.Empty, (current, keyValuePair) => current + $"- {keyValuePair.Key} | Expired : {keyValuePair.Value}\n");
String Information = LanguageEn ? $"Active Player Privileges {userID} ({GetParametres.Count} pieces(/s))\n{PermsList}" : $"Активные привилегии игрока {userID} ({GetParametres.Count} штук(/и))\n{PermsList}";
arg.ReplyWith(Information);
}
private void InserDatabase(String UserID, TypeData typeData, String Key, DateTime dateExpired) {
if (sqlConnection == null) return;
String Permission = typeData == TypeData.Permission ? Key : String.Empty;
String Group = typeData == TypeData.Group ? Key : String.Empty;
String sqlQuery = typeData == TypeData.Permission ? $"UPDATE {config.GeneralSettings.MySQLSetting.TableName} SET `steamid` = @0, `permission` = @1,`group` = @2,`data_expired` = @3 WHERE `steamid` = @0 AND `permission` = @1" : $"UPDATE {config.GeneralSettings.MySQLSetting.TableName} SET `steamid` = @0, `permission` = @1,`group` = @2,`data_expired` = @3 WHERE `steamid` = @0 AND`group` = @2";
Sql updateCommand = Oxide.Core.Database.Sql.Builder.Append(sqlQuery, UserID, Permission, Group, dateExpired.ToString());
sqlLibrary.Update(updateCommand, sqlConnection, rowsAffected => {
if (rowsAffected <= 0) {
String Query = String.Format(SQL_Query_InsertUser(), UserID, Permission, Group, dateExpired.ToString());
Sql sql = Sql.Builder.Append(Query);
sqlLibrary.Insert(sql, sqlConnection, rowsAffecteds => {
Puts(LanguageEn ? "A new user has been added to the database" : "В БД был внесен новый пользователь");
}
);
}
else Puts(LanguageEn ? "The data for the user has been updated in the database" : "В БД были обновлены данные для пользователя");
}
);
}
private IEnumerator MigrationTimePrivilage() {
if (!Interface.Oxide.DataFileSystem.ExistsDatafile("Timeprivileges")) {
Puts(LanguageEn ? "Timeprivileges file - does not exist, migration is not possible" : "Файла Timeprivileges - не существует, миграция невозможна");
yield break;
}
Puts(LanguageEn ? "Starting the migration from the plugin TimePrivilage -> IQPermissions (This may take some time, depending on the number of entries)" : "Запускаем миграцию из плагина TimePrivilage -> IQPermissions (Это может занять некоторое время, в зависимости от количество записей)");
Dictionary<String, StructureTimePrivilage> dataFile = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<String, StructureTimePrivilage>>("Timeprivileges");
foreach (KeyValuePair<String, StructureTimePrivilage> timePrivilage in dataFile) {
UInt64 userID;
if (!UInt64.TryParse(timePrivilage.Key, out userID)) continue;
foreach (KeyValuePair<String, String> Permissions in timePrivilage.Value.permissions) {
DateTime Time = Convert.ToDateTime(Permissions.Value);
InformationPrivilagesUser.SetParametres(Permissions.Key, userID, Time, TypeData.Permission);
yield return CoroutineEx.waitForSeconds(0.15f);
}
foreach (KeyValuePair<String, String> Groups in timePrivilage.Value.groups) {
DateTime Time = Convert.ToDateTime(Groups.Value);
InformationPrivilagesUser.SetParametres(Groups.Key, userID, Time, TypeData.Group);
yield return CoroutineEx.waitForSeconds(0.15f);
}
yield return CoroutineEx.waitForSeconds(0.25f);
}
Interface.Oxide.UnloadPlugin("TimePrivilage");
Puts(LanguageEn ? "Migration is complete, TimePrivilege has been unloaded! (Don't forget to remove the TimePrivilage for stable operation)" : "Миграция завершена, TimePrivilage был выгружен! (Не забудьте удалить TimePrivilage для стабильной работы)");
if (coroutineMigration != null) {
ServerMgr.Instance.StopCoroutine(coroutineMigration);
coroutineMigration = null;
}
}
private void OnPermissionRegistered(String name, Plugin owner) => NewPermissionRegistered(name);
public String GetLang(String LangKey, String userID = null, params Object[] args) {
sb.Clear();
if (args == null) return lang.GetMessage(LangKey, this, userID);
sb.AppendFormat(lang.GetMessage(LangKey, this, userID), args);
return sb.ToString();
}
public class GrantData {
public Dictionary<String, Dictionary<String, Int64>> Group = new Dictionary<String, Dictionary<String, Int64>>();
public Dictionary<String, Dictionary<String, Int64>> Permission = new Dictionary<String, Dictionary<String, Int64>>();
}
public class Authors {
public String name {
get;
set;
}
public String url {
get;
set;
}
public String icon_url {
get;
set;
}
public String proxy_icon_url {
get;
set;
}
public Authors(String name, String url, String icon_url, String proxy_icon_url) {
this.name = name;
this.url = url;
this.icon_url = icon_url;
this.proxy_icon_url = proxy_icon_url;
}
}
private void OnUserPermissionRevoked(String id, String permName) => InformationPrivilagesUser.RemoveParametres(permName, UInt64.Parse(id), TypeData.Permission);
private IEnumerator MigrationTimedPermissions() {
if (!Interface.Oxide.DataFileSystem.ExistsDatafile("TimedPermissions")) {
Puts(LanguageEn ? "TimedPermissions file - does not exist, migration is not possible" : "Файла TimedPermissions - не существует, миграция невозможна");
yield break;
}
Puts(LanguageEn ? "Starting the migration from the plugin TimedPermissions -> IQPermissions (This may take some time, depending on the number of entries)" : "Запускаем миграцию из плагина TimedPermissions -> IQPermissions (Это может занять некоторое время, в зависимости от количество записей)");
List<PlayerInformation> dataFile = Interface.Oxide.DataFileSystem.ReadObject<List<PlayerInformation>>("TimedPermissions");
foreach (PlayerInformation playerInformation in dataFile) {
UInt64 userID;
if(!UInt64.TryParse(playerInformation.Id, out userID)) continue;
foreach (ExpiringAccessValue informationPermission in playerInformation._permissions.Where(x => !x.IsExpired)) {
InformationPrivilagesUser.SetParametres(informationPermission.Value, userID, informationPermission.ExpireDate, TypeData.Permission);
yield return CoroutineEx.waitForSeconds(0.15f);
}
foreach (ExpiringAccessValue playerInformationGroup in playerInformation._groups.Where(x => !x.IsExpired)) {
InformationPrivilagesUser.SetParametres(playerInformationGroup.Value, userID, playerInformationGroup.ExpireDate, TypeData.Group);
yield return CoroutineEx.waitForSeconds(0.15f);
}
yield return CoroutineEx.waitForSeconds(0.25f);
}
Interface.Oxide.UnloadPlugin("TimedPermissions");
Puts(LanguageEn ? "Migration is complete, TimedPermissions has been unloaded! (Don't forget to remove the TimedPermissions for stable operation)" : "Миграция завершена, TimedPermissions был выгружен! (Не забудьте удалить TimedPermissions для стабильной работы)");
if (coroutineMigration != null) {
ServerMgr.Instance.StopCoroutine(coroutineMigration);
coroutineMigration = null;
}
}
private void SetGroup(UInt64 userID, String Group, String DataExpired) {
TimeSpan duration;
if (!TryParseTimeSpan(DataExpired, out duration)) {
PrintError(LanguageEn ? "API : You specified an incorrect time, use 1d/1h/1m/1s!" : "API : Вы указали неккоректное время, используйте 1d/1h/1m/1s!");
return;
}
DateTime ThisTime = InformationPrivilagesUser.GetExpiredPermissionData(Group, userID, TypeData.Group) + duration;
InformationPrivilagesUser.SetParametres(Group, userID, ThisTime, TypeData.Group);
}
private void NewPermissionRegistered(String Permission) {
if(config.PermissionList.ContainsKey(Permission)) return;
String ExampleName = Permission.Substring(Permission.IndexOf('.') + 1).ToUpper();
config.PermissionList.Add(Permission, new Configuration.StructureLanguage(ExampleName, ExampleName));
Puts(LanguageEn ?$"A new permission {Permission} has been added to the configuration file" : $"В конфигурационный файл была добавлена новое право {Permission}");
SaveConfig();
}
[ConsoleCommand("revokegroup")]
private void RemoveGroup_ConsoleCommand(ConsoleSystem.Arg arg) {
if (arg == null) return;
if(arg.Player() != null) if(!arg.Player().IsAdmin) return;
if (arg.Args == null || arg.Args.Length < 2) {
arg.ReplyWith(LanguageEn ? "Syntax error, use: revokegroup Steam64ID Group\nExample : revokegroup 765611972358278930 vip" : "Ошибка синтаксиса, используйте : revokegroup Steam64ID Group\nПример : revokegroup 76561197235887930 vip");
return;
}
UInt64 userID;
if (!UInt64.TryParse(arg.Args[0], out userID)) {
arg.ReplyWith(LanguageEn ? "You have specified an incorrect Steam64ID player!" : "Вы указали неккоректный Steam64ID игрока!");
return;
}
String Group = arg.Args[1];
if (!config.GroupList.ContainsKey(Group)) {
arg.ReplyWith(LanguageEn ? "The group you specified do not exist!" : "Группа которую вы указали - не существуют!");
return;
}
if (!permission.UserHasGroup(userID.ToString(), Group)) {
arg.ReplyWith(LanguageEn ? "The player does not have this group!" : "У игрока отсутствуют данная группа!");
return;
}
if (arg.Args.Length == 3) {
TimeSpan duration;
if (!TryParseTimeSpan(arg.Args[2], out duration)) {
arg.ReplyWith(LanguageEn ? "You specified an incorrect time, use 1d/1h/1m/1s!" : "Вы указали неккоректное время, используйте 1d/1h/1m/1s!");
return;
}
DateTime ThisTime = InformationPrivilagesUser.GetExpiredPermissionData(Group, userID, TypeData.Group) - duration;
InformationPrivilagesUser.RemoveParametres(Group, userID, TypeData.Group, ThisTime);
return;
}
InformationPrivilagesUser.RemoveParametres(Group, userID, TypeData.Group);
}
[ConsoleCommand("revokeperm")]
private void RevokePerm_ConsoleCommand(ConsoleSystem.Arg arg) {
if (arg == null) return;
if(arg.Player() != null) if(!arg.Player().IsAdmin) return;
if (arg.Args == null || arg.Args.Length < 2) {
arg.ReplyWith(LanguageEn ? "Syntax error, use: revokeperm Steam64ID Permission\nExample : revokeperm 765611982785887930 iqchat.vip" : "Ошибка синтаксиса, используйте : revokeperm Steam64ID Permission\nПример : revokeperm 76561197235887930 iqchat.vip");
return;
}
UInt64 userID;
if (!UInt64.TryParse(arg.Args[0], out userID)) {
arg.ReplyWith(LanguageEn ? "You have specified an incorrect Steam64ID player!" : "Вы указали неккоректный Steam64ID игрока!");
return;
}
String Permission = arg.Args[1];
if (!config.PermissionList.ContainsKey(Permission)) {
arg.ReplyWith(LanguageEn ? "The permission you specified do not exist!" : "Права которые вы указали - не существуют!");
return;
}
if (!permission.UserHasPermission(userID.ToString(), Permission)) {
arg.ReplyWith(LanguageEn ? "The player does not have these rights!!" : "У игрока отсутствуют данные права!");
return;
}
if (arg.Args.Length == 3) {
TimeSpan duration;
if (!TryParseTimeSpan(arg.Args[2], out duration)) {
arg.ReplyWith(LanguageEn ? "You specified an incorrect time, use 1d/1h/1m/1s!" : "Вы указали неккоректное время, используйте 1d/1h/1m/1s!");
return;
}
DateTime ThisTime = InformationPrivilagesUser.GetExpiredPermissionData(Permission, userID, TypeData.Permission) - duration;
InformationPrivilagesUser.RemoveParametres(Permission, userID, TypeData.Permission, ThisTime);
return;
}
InformationPrivilagesUser.RemoveParametres(Permission, userID, TypeData.Permission);
}
private enum TypeAlert {
Add, Expired, Alert
}
private void RevokeGroup(UInt64 userID, String Group, String DataExpired = null) {
if (DataExpired != null) {
TimeSpan duration;
if (!TryParseTimeSpan(DataExpired, out duration)) {
PrintError(LanguageEn ? "API : You specified an incorrect time, use 1d/1h/1m/1s!" : "API : Вы указали неккоректное время, используйте 1d/1h/1m/1s!");
return;
}
DateTime ThisTime = InformationPrivilagesUser.GetExpiredPermissionData(Group, userID, TypeData.Group) - duration;
InformationPrivilagesUser.RemoveParametres(Group, userID, TypeData.Group, ThisTime);
return;
}
InformationPrivilagesUser.RemoveParametres(Group, userID, TypeData.Group);
}
private String GetTitle(TypeAlert typeAlert) {
String Lang = typeAlert == TypeAlert.Add ? "TITLE_ALERT_ADD" : typeAlert == TypeAlert.Expired ? "TITLE_ALERT_EXPIRED" : typeAlert == TypeAlert.Alert ? "TITLE_ALERT_INFO" : String.Empty;
return Lang;
}
private void RevokeGroup(UInt64 userID, String Group, DateTime DataExpired = default(DateTime)) => InformationPrivilagesUser.RemoveParametres(Group, userID, TypeData.Group, DataExpired);
private Connection sqlConnection = null;
public class Fields {
public String name {
get;
set;
}
public String value {
get;
set;
}
public bool inline {
get;
set;
}
public Fields(String name, String value, bool inline) {
this.name = name;
this.value = value;
this.inline = inline;
}
}
/// <summary>
/// Обновление
/// - Изменен метод подгрузки привилегий после выгрузки плагина и использования БД, улучшен отклик (для больших БД или в случае долгого ответа от базы)
/// </summary>
private static ImageUI _imageUI;
private void WriteData() {
Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject("IQSystem/IQPermissions/OldPlayers", OldPlayers);
if (sqlConnection != null) return;
Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject("IQSystem/IQPermissions/Permissions", InformationPrivilagesUser);
}
private const Boolean LanguageEn = false;
private Dictionary<String, DateTime> GetGroups(UInt64 userID) => InformationPrivilagesUser.GetParametresUser(userID, TypeData.Group);
internal class StructureData {
[JsonProperty(LanguageEn ? "Information about player permissions" : "Информация о привилегиях игрока")]
public Dictionary<String, Dictionary<UInt64, DateTime>> UserPermissions = new Dictionary<String, Dictionary<UInt64, DateTime>>();
[JsonProperty(LanguageEn ? "Information about player groups" : "Информация о группах игрока")]
public Dictionary<String, Dictionary<UInt64, DateTime>> UserGrpups = new Dictionary<String, Dictionary<UInt64, DateTime>>();
public Dictionary<String, DateTime> GetParametresUser(UInt64 userID, TypeData typeDictonary) {
Dictionary<String, Dictionary<UInt64, DateTime>> selectStructureData = typeDictonary == TypeData.Permission ? UserPermissions : UserGrpups;
Dictionary<String, DateTime> ParametresUser = selectStructureData.Where(structure => structure.Value.ContainsKey(userID)).ToDictionary(structure => structure.Key, structure => structure.Value[userID]);
return ParametresUser;
}
public Dictionary<UInt64, DateTime> GePlayerList(String Key, TypeData typeDictonary) {
Dictionary<String, Dictionary<UInt64, DateTime>> selectStructureData = typeDictonary == TypeData.Permission ? UserPermissions : UserGrpups;
return selectStructureData.ContainsKey(Key) ? selectStructureData[Key] : null;
}
public DateTime GetExpiredPermissionData(String Key, UInt64 userID, TypeData typeDictonary) {
Dictionary<String, Dictionary<UInt64, DateTime>> selectStructureData = typeDictonary == TypeData.Permission ? UserPermissions : UserGrpups;
return selectStructureData.ContainsKey(Key) ? selectStructureData[Key].ContainsKey(userID) ? selectStructureData[Key][userID] : DateTime.Now : DateTime.Now;
}
public void SetParametres(String Key, UInt64 userID, DateTime dateExpired, TypeData typeDictonary, Boolean IsMigration = false) {
Dictionary<String, Dictionary<UInt64, DateTime>> selectStructureData = typeDictonary == TypeData.Permission ? UserPermissions : UserGrpups;
if (!selectStructureData.ContainsKey(Key)) selectStructureData.Add(Key, new Dictionary<UInt64, DateTime>() {
}
);
if (selectStructureData[Key].ContainsKey(userID)) selectStructureData[Key][userID] = dateExpired;
else selectStructureData[Key].Add(userID, dateExpired);
if (typeDictonary == TypeData.Permission) _.permission.GrantUserPermission(userID.ToString(), Key, null);
else _.permission.AddUserGroup(userID.ToString(), Key);
String LeftTime = _.GetLeftTime(dateExpired, userID.ToString());
_.InserDatabase(userID.ToString(), typeDictonary, Key, dateExpired);
_.Puts(LanguageEn ? $"Player {userID} successfully obtained {(typeDictonary == TypeData.Permission ? "permission" : "group")} - {Key} (End date in : {LeftTime})" : $"Игрок {userID} успешно получил {(typeDictonary == TypeData.Permission ? "права" : "группу")} - {Key} (Дата окончания через : {LeftTime})");
if (!IsMigration) {
_.AlertPlayer(userID, TypeAlert.Add, Key, typeDictonary, $"{LeftTime}");
_.LogToFile("LogPermission", $"===> Set - Type : {typeDictonary.ToString()} | Key : {Key} | DataExpired in : {LeftTime}", _);
List<Fields> fields = new List<Fields> {
new Fields("Steam64ID", userID.ToString(), true), new Fields(LanguageEn ? $"Received {(typeDictonary == TypeData.Permission ? "permission" : "group")}" : $"Получил {(typeDictonary == TypeData.Permission ? "права" : "группу")}", Key, true), new Fields(LanguageEn ? "Date Expired in" : $"Дата окончания через", $"{LeftTime}", true),
}
;
_.SendDiscord(fields);
}
}
public void RemoveParametres(String Key, UInt64 userID, TypeData typeDictonary, DateTime timeRevoed = default(DateTime)) {
Dictionary<String, Dictionary<UInt64, DateTime>> selectStructureData = typeDictonary == TypeData.Permission ? UserPermissions : UserGrpups;
if (!selectStructureData.ContainsKey(Key) ) return;
if (timeRevoed == default(DateTime)) {
selectStructureData[Key].Remove(userID);
_.DeleteDatabase(userID.ToString(), typeDictonary, Key);
}
else {
selectStructureData[Key][userID] = timeRevoed;
if (!IsExpiredPermission(Key, userID, typeDictonary)) {
String LeftTime = _.GetLeftTime(timeRevoed, userID.ToString());
_.Puts(LanguageEn ? $"The player has {userID} reduced action time {(typeDictonary == TypeData.Permission ? "permission" : "group")} - {Key} | End date in : {LeftTime}" : $"У игрока {userID} снижено время действия {(typeDictonary == TypeData.Permission ? "права" : "группы")} - {Key} | Дата окончания через : {LeftTime}");
_.LogToFile("LogPermission", $"=====> Remove time - Type : {typeDictonary.ToString()} | Key : {Key}", _);
List<Fields> fieldsRemoveTime = new List<Fields> {
new Fields("Steam64ID", userID.ToString(), true), new Fields(LanguageEn ? $"Reduced action time {(typeDictonary == TypeData.Permission ? "permission" : "group")}" : $"Снижено время дейтсвия {(typeDictonary == TypeData.Permission ? "прав" : "группы")}", Key, true), new Fields(LanguageEn ? "End Date in" : $"Дата окончания через", $"{LeftTime}", true),
}
;
_.SendDiscord(fieldsRemoveTime);
_.InserDatabase(userID.ToString(), typeDictonary, Key, selectStructureData[Key][userID]);
return;
}
selectStructureData[Key].Remove(userID);
_.DeleteDatabase(userID.ToString(), typeDictonary, Key);
}
if (selectStructureData[Key].Count == 0) selectStructureData.Remove(Key);
if (typeDictonary == TypeData.Permission) _.permission.RevokeUserPermission(userID.ToString(), Key);
else _.permission.RemoveUserGroup(userID.ToString(), Key);
_.AlertPlayer(userID, TypeAlert.Expired, Key, typeDictonary, null);
_.Puts(LanguageEn ? $"The player {userID} has run out of {(typeDictonary == TypeData.Permission ? "permission" : "group")} - {Key}" : $"У игрока {userID} {(typeDictonary == TypeData.Permission ? "закончились права" : "закончилась группа")} - {Key}");
_.LogToFile("LogPermission", $"=====> Remove - Type : {typeDictonary.ToString()} | Key : {Key}", _);
List<Fields> fields = new List<Fields> {
new Fields("Steam64ID", userID.ToString(), true), new Fields(LanguageEn ? $"Expired {(typeDictonary == TypeData.Permission ? "permission" : "group")}" : $"{(typeDictonary == TypeData.Permission ? "Закончились права" : "Закончилась группа")}", Key, true),
}
;
_.SendDiscord(fields);
}
public voi
// ... [Code preview truncated due to length. Full source in attached file] ...