C#:
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins
{
public class Configuration
{
public string Color { get; set; } = "0.66 0.66 0.66 0.8";
public string IconColor { get; set; } = "1.5 0.8 0.0 0.9";
public string ImageUrl { get; set; } =
"https://i.imgur.com/yyJwtKR.png";
public string SubTextColor { get; set; } = "1 1 1 0.7";
public string TextColor { get; set; } = "1.5 0.8 0.0 0.8";
public string VipStatusId { get; set; } = "vip";
}
[Info("VIP Status", "Doldak", "1.1.1")]
[Description("Shows a custom status message for VIP players")]
public class VIPStatus : RustPlugin
{
private Configuration config;
private Dictionary<string, DateTime> vipPlayers = new Dictionary<string, DateTime>();
private string vipStatusId;
[PluginReference]
Plugin CustomStatusFramework;
[PluginReference]
Plugin ImageLibrary;
[PluginReference]
Plugin TimedPermissions;
protected override void LoadConfig()
{
base.LoadConfig();
config = Config.ReadObject<Configuration>();
vipStatusId = config.VipStatusId;
}
protected override void LoadDefaultConfig()
{
Puts("Creating a new configuration file");
config = new Configuration();
SaveConfig();
}
protected override void SaveConfig()
{
Config.WriteObject(config);
}
private void AddImageFromUrl(string ImageUrl)
{
if (ImageLibrary == null)
{
Puts("ImageLibrary plugin is not loaded.");
return;
}
bool success = ImageLibrary.Call<bool>(
"AddImage",
ImageUrl,
"VIPIMAGE",
0ul,
(Action)
delegate()
{
Puts(
$"Image with ID '{ImageLibrary.Call<string>("GetImage", "VIPIMAGE")}' and ImageLibrary name 'VIPIMAGE' has been added."
);
}
);
if (!success)
{
Puts("Failed to add the image.");
}
}
private void CheckAllPlayers()
{
var permissionsFile = Interface.Oxide.DataFileSystem.ReadObject<JArray>(
"TimedPermissions"
);
foreach (var player in BasePlayer.activePlayerList)
{
UpdateVIPStatus(player, permissionsFile);
}
}
private void ClearVIPStatus(BasePlayer player)
{
if (CustomStatusFramework.Call<bool>("HasStatus", player, vipStatusId))
{
CustomStatusFramework.Call("ClearStatus", player, vipStatusId);
}
}
[ConsoleCommand("vipstatus.refresh")]
private void ConsoleCmdRefreshVIPStatus(ConsoleSystem.Arg arg)
{
BasePlayer player = arg.Player();
if (player != null && !player.IsAdmin)
{
SendReply(arg, "You do not have permission to use this command.");
return;
}
var permissionsFile = Interface.Oxide.DataFileSystem.ReadObject<JArray>(
"TimedPermissions"
);
if (player != null)
{
UpdateVIPStatus(player, permissionsFile);
SendReply(arg, "VIP status refreshed for the calling player.");
}
else
{
foreach (var onlinePlayer in BasePlayer.activePlayerList)
{
UpdateVIPStatus(onlinePlayer, permissionsFile);
}
SendReply(arg, "VIP status refreshed for all online players.");
}
}
private string GetVIPExpireDate(BasePlayer player, JArray permissionsFile)
{
var playerData = permissionsFile.FirstOrDefault(
x => x["Id"] != null && x["Id"].ToString() == player.UserIDString
);
if (
playerData != null
&& playerData["Groups"] != null
&& playerData["Groups"].Any(x => x["Value"].ToString() == vipStatusId)
)
{
var vipGroup = playerData["Groups"].FirstOrDefault(
x => x["Value"].ToString() == vipStatusId
);
if (vipGroup != null && vipGroup["ExpireDate"] != null)
{
var expireDate = DateTime.Parse(vipGroup["ExpireDate"].ToString());
vipPlayers[player.UserIDString] = expireDate;
return expireDate.ToString("dd.MM");
}
}
return "";
}
private void LoadDefaultMessages()
{
lang.RegisterMessages(
new Dictionary<string, string>
{
["VIPStatusText"] = "VIP STATUS",
["UntilText"] = "until {0}"
},
this
);
}
private void OnGroupRemoved(string userId, string groupName)
{
if (groupName == vipStatusId)
{
BasePlayer player = BasePlayer.FindByID(ulong.Parse(userId));
if (player != null)
{
ClearVIPStatus(player);
}
}
}
private void OnPlayerInit(BasePlayer player)
{
var permissionsFile = Interface.Oxide.DataFileSystem.ReadObject<JArray>(
"TimedPermissions"
);
UpdateVIPStatus(player, permissionsFile);
}
private void OnServerInitialized()
{
LoadDefaultMessages();
CheckAllPlayers();
//puts("Watchdog loaded");
timer.Every(60f, CheckAllPlayers);
timer.Every(60f, () => RefreshVIPStatusForAllPlayers());
AddImageFromUrl(config.ImageUrl);
}
private void RefreshVIPStatusForAllPlayers()
{
var permissionsFile = Interface.Oxide.DataFileSystem.ReadObject<JArray>(
"TimedPermissions"
);
foreach (var player in BasePlayer.activePlayerList)
{
ShowVIPStatus(player, permissionsFile);
}
}
private void ShowVIPStatus(BasePlayer player, JArray permissionsFile)
{
List<string> statusList = CustomStatusFramework.Call<List<string>>(
"GetStatusList",
player
);
var expireDate = GetVIPExpireDate(player, permissionsFile);
if (!String.IsNullOrEmpty(expireDate))
{
string vipStatusText = lang.GetMessage("VIPStatusText", this, player.UserIDString);
string untilText = lang.GetMessage("UntilText", this, player.UserIDString);
if (!statusList.Contains(vipStatusId))
{
CustomStatusFramework.Call(
"SetStatus",
player,
vipStatusId,
config.Color,
vipStatusText,
config.TextColor,
string.Format(untilText, expireDate),
config.SubTextColor,
"VIPIMAGE",
config.IconColor
);
}
else
{
CustomStatusFramework.Call(
"UpdateStatus",
player,
vipStatusId,
config.Color,
vipStatusText,
config.TextColor,
string.Format(untilText, expireDate),
config.SubTextColor,
"VIPIMAGE",
config.IconColor
);
}
CustomStatusFramework.Call("RefreshStatus", player, vipStatusId);
}
}
private void Unload()
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
ClearVIPStatus(player);
}
}
private void UpdateVIPStatus(BasePlayer player, JArray permissionsFile)
{
if (CustomStatusFramework == null)
{
return;
}
if (TimedPermissions == null)
{
return;
}
bool isPlayerVIP = permission.UserHasGroup(player.UserIDString, vipStatusId);
if (isPlayerVIP)
{
var expireDate = GetVIPExpireDate(player, permissionsFile);
if (!String.IsNullOrEmpty(expireDate))
{
ShowVIPStatus(player, permissionsFile);
if (vipPlayers.ContainsKey(player.UserIDString)) { }
else { }
}
else
{
// Der Spieler ist in der VIP-Gruppe, aber nicht in der permissionsFile.
// Zeige den VIP-Status ohne Ablauftext an.
string vipStatusText = lang.GetMessage(
"VIPStatusText",
this,
player.UserIDString
);
CustomStatusFramework.Call(
"SetStatus",
player,
vipStatusId,
config.Color,
vipStatusText,
config.TextColor,
"",
config.SubTextColor,
"VIPIMAGE",
config.IconColor
);
CustomStatusFramework.Call("RefreshStatus", player, vipStatusId);
}
}
else
{
ClearVIPStatus(player);
if (vipPlayers.ContainsKey(player.UserIDString))
{
vipPlayers.Remove(player.UserIDString);
}
}
CustomStatusFramework.Call("RefreshStatus", player, vipStatusId);
}
}
}