C#:
using Oxide.Core.Plugins;
using Oxide.Core;
using System;
using System.Text;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using ConVar;
namespace Oxide.Plugins
{
[Info("SkinNight", "https://topplugin.ru/", "0.0.5")]
[Description("Самый лучший пионер https://topplugin.ru/")]
class SkinNight : RustPlugin
{
#region Vars
public Dictionary<ulong, double> VotesPlayer = new Dictionary<ulong, double>();
bool VoteActive = false;
#endregion
#region Reference
[PluginReference] Plugin ImageLibrary, IQChat;
bool CanTake(BasePlayer player) => !player.inventory.containerMain.IsFull() || !player.inventory.containerBelt.IsFull();
public string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary?.Call("GetImage", shortname, skin);
public bool AddImage(string url, string shortname, ulong skin = 0) => (bool)ImageLibrary?.Call("AddImage", url, shortname, skin);
#endregion
#region Configuration
private static Configuration config = new Configuration();
private class Configuration
{
[JsonProperty("Сколько минимум игроков должно быть на сервере для запуска голосования")]
public int VotePlayerCount;
[JsonProperty("Во сколько начинать голосование (игровое время)")]
public int TimeVoteCount;
[JsonProperty("Какое время устанавливать в случае пропуска ночи")]
public int TimeSetDay;
[JsonProperty("Раз в сколько секунд можно вернуть голос")]
public int CooldownVote;
[JsonProperty("Настройка интерфейса")]
public SettingUI Interface = new SettingUI();
internal class SettingUI
{
[JsonProperty("Иконка для кнопки дня(png)")]
public string IconDay;
[JsonProperty("Иконка для кнопки ночи(png)")]
public string IconNight;
}
public static Configuration GetNewConfiguration()
{
return new Configuration
{
VotePlayerCount = 10,
TimeVoteCount = 18,
TimeSetDay = 12,
CooldownVote = 30,
Interface = new SettingUI
{
IconDay = "https://i.imgur.com/QQq8i8C.png",
IconNight = "https://i.imgur.com/3Wpn1iY.png"
}
};
}
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
}
catch
{
PrintWarning("Ошибка #237" + $"чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
LoadDefaultConfig();
}
NextTick(SaveConfig);
}
protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Metods
public bool CanVote()
{
if (BasePlayer.activePlayerList.Count >= config.VotePlayerCount)
if (TOD_Sky.Instance.Cycle.Hour >= config.TimeVoteCount)
return true;
return false;
}
public bool CanVoteUser(BasePlayer player)
{
if (VotesPlayer.ContainsKey(player.userID))
return true;
return false;
}
public void VoteProcess()
{
int Average = BasePlayer.activePlayerList.Count / 2;
if(VotesPlayer.Count >= Average)
{
TOD_Sky.Instance.Cycle.Hour = config.TimeSetDay;
SendChat(lang.GetMessage("VOTE_NIGHT", this));
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
{
var p = BasePlayer.activePlayerList[i];
CuiHelper.DestroyUi(p, VOTE_PARENT);
}
VoteActive = false;
}
}
public void VoteStart()
{
if (VoteActive) return;
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
{
var p = BasePlayer.activePlayerList[i];
UI_VoteShow(p);
}
SendChat(lang.GetMessage("VOTE_START", this));
timer.Once(120, () =>
{
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
{
var p = BasePlayer.activePlayerList[i];
CuiHelper.DestroyUi(p, VOTE_PARENT);
}
SendChat(lang.GetMessage("VOTE_DAY", this));
VoteActive = false;
});
VoteActive = true;
}
#endregion
#region Hooks
private void Unload()
{
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
{
var p = BasePlayer.activePlayerList[i];
CuiHelper.DestroyUi(p, VOTE_PARENT);
}
}
private void OnServerInitialized()
{
AddImage(config.Interface.IconDay, "DayButton");
AddImage(config.Interface.IconNight, "NightButton");
timer.Every(30f, () =>
{
if (CanVote())
VoteStart();
});
}
#endregion
#region UI
public static string VOTE_PARENT = "VOTE_PARENT_SHOWUI";
void UI_VoteShow(BasePlayer player)
{
CuiElementContainer container = new CuiElementContainer();
CuiHelper.DestroyUi(player, VOTE_PARENT);
string Icon = CanVoteUser(player) ? "DayButton" : "NightButton";
container.Add(new CuiElement
{
Parent = "Overlay",
Name = VOTE_PARENT,
Components =
{
new CuiRawImageComponent { Png = GetImage(Icon) },
new CuiRectTransformComponent { AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-455 10", OffsetMax = "-390 70" }
}
});
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "0 0",OffsetMin = "-30 -10", OffsetMax = "100 9" },
Text = { Text = "<b>Пропуск ночи</b>", Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter, FontSize = 14 }
}, VOTE_PARENT);
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Button = { Command = "vote", Color = "0 0 0 0"},
Text = { Text = "", Color = HexToRustFormat("#FFBBB0FF"), Align = TextAnchor.MiddleCenter }
}, VOTE_PARENT);
CuiHelper.AddUi(player, container);
}
#endregion
#region Command
[ConsoleCommand("vote")]
void VoteCommand(ConsoleSystem.Arg arg)
{
BasePlayer player = arg.Player();
if (!CanVoteUser(player))
VotesPlayer.Add(player.userID, (config.CooldownVote + CurrentTime()));
else
{
if (VotesPlayer[player.userID] <= CurrentTime())
VotesPlayer.Remove(player.userID);
else
{
SendPlayer(player,String.Format(lang.GetMessage("VOTE_COOLDOWN", this), config.CooldownVote, VotesPlayer[player.userID] - CurrentTime()));
return;
}
}
UI_VoteShow(player);
VoteProcess();
SendPlayer(player,lang.GetMessage("VOTE_ACCESS", this));
}
[ChatCommand("day")]
void StartVoteDay(BasePlayer player)
{
if(player.IsAdmin)
VoteStart();
}
#endregion
#region Lang
private new void LoadDefaultMessages()
{
PrintWarning("Языковой файл загружается...");
Dictionary<string, string> Lang = new Dictionary<string, string>
{
["VOTE_START"] = "<size=14>Голосование за пропуск ночи началось!</size>",
["VOTE_DAY"] = "<size=14>Голосование закончено!\nНочь не будет пропущена</size>",
["VOTE_NIGHT"] = "<size=14>Голосование закончено!\nНочь пропущена</size>",
["VOTE_ACCESS"] = "<size=14>Ваш голос принят!</size>",
["VOTE_COOLDOWN"] = "<size=14>Вы можете изменить голос обратно раз в {0} секунд!\nОсталось {1} секунд</size>",
};
lang.RegisterMessages(Lang, this);
PrintWarning("Языковой файл загружен успешно");
}
#endregion
#region Helps
static DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
static double CurrentTime() => DateTime.UtcNow.Subtract(epoch).TotalSeconds;
private static string HexToRustFormat(string hex)
{
if (string.IsNullOrEmpty(hex))
{
hex = "#FFFFFFFF";
}
var str = hex.Trim('#');
if (str.Length == 6)
str += "FF";
if (str.Length != 8)
{
throw new Exception(hex);
throw new InvalidOperationException("Cannot convert a wrong format.");
}
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);
return string.Format("{0:F2} {1:F2} {2:F2} {3:F2}", color.r, color.g, color.b, color.a);
}
public void SendChat(string Message, Chat.ChatChannel channel = Chat.ChatChannel.Global)
{
if (IQChat)
IQChat?.Call("API_ALERT", Message);
else
{
for (int i = 0; i < BasePlayer.activePlayerList.Count; i++)
{
var p = BasePlayer.activePlayerList[i];
p.SendConsoleCommand("chat.add", channel, 0, Message);
}
}
}
public void SendPlayer(BasePlayer player,string Message)
{
if (IQChat)
IQChat?.Call("API_ALERT_PLAYER", player, Message);
else player.SendConsoleCommand("chat.add", Chat.ChatChannel.Global, 0, Message);
}
#endregion
}
}