C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Oxide.Plugins {
[Info("GalaxyExp", "TopPlugin.Ru", "1.0.1")]
[Description("GalaxyExp")]
class GalaxyExp : RustPlugin {
#region Classes
private class UserData {
public int Exp = 0;
public double NeedToPlay = 0;
public int LowProgress = 0;
}
private class PluginConfig {
[JsonProperty(PropertyName = "Частота проверки выдачи (Не понимаешь не трогаешь)", Order = 7)]
public float CheckTime = 20f;
[JsonProperty(PropertyName = "Раз в сколько секунд выдавать EXP", Order = 6)]
public float TimeEvery = 3600f;
[JsonProperty(PropertyName = "Давать EXP только ночью?", Order = 5)]
public bool GiveNight = true;
[JsonProperty(PropertyName = "Доступ к команде только ночью?", Order = 4)]
public bool CommandNight = false;
[JsonProperty(PropertyName = "Сколько давать EXP", Order = 3)]
public int ExpGiveAmount = 100;
[JsonProperty(PropertyName = "Время ночи ОТ", Order = 3)]
public int NightFrom = 21;
[JsonProperty(PropertyName = "Время ночи ДО", Order = 3)]
public int NightTo = 6;
[JsonProperty(PropertyName = "Список предметов", Order = 2)]
public Dictionary<string, int> LowItems;
}
#endregion
#region Variables
[PluginReference]
Plugin ImageLibrary;
private PluginConfig config;
private Dictionary<ulong, UserData> usersData;
static GalaxyExp instance;
GameObject controller;
string UI_Layer = "UI_GalaxyEXP";
string DataPath = "GalaxyEXP/Data";
Dictionary<string, string> customImages;
#endregion
#region Oxide
private void Init() {
config = Config.ReadObject<PluginConfig>();
}
void OnServerInitialized() {
instance = this;
controller = new GameObject();
PlayersExp component;
if (controller != null) {
component = controller.GetComponent<PlayersExp>();
if (component != null) UnityEngine.Object.Destroy(component);
}
controller.AddComponent<PlayersExp>();
usersData = new Dictionary<ulong, UserData>();
if (Interface.Oxide.DataFileSystem.ExistsDatafile(DataPath)) usersData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, UserData>>(DataPath);
BasePlayer.activePlayerList.ToList().ForEach(p => UpdatePlayerData(p));
customImages = new Dictionary<string, string>() {
["mainback"]
= "https://i.imgur.com/qdHsVX1.png", ["important"] = "https://i.imgur.com/RrYTIjz.png", ["balance"] = "https://i.imgur.com/pjW8aks.png", ["mainblock"] = "https://i.imgur.com/0bM05Zc.png", ["mainlock"] = "https://i.imgur.com/LJuNSpN.png",
}
;
if(ImageLibrary != null) {
customImages.ToList().ForEach(i => AddImage(i.Value));
}
PrintWarning("Plugin loaded! Author: BadMandarin!");
}
void OnPlayerOnPlayerConnected(BasePlayer player) {
if (player == null) return;
if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot)) {
timer.Once(2f, () => OnPlayerOnPlayerConnected(player));
return;
}
if (!player.IsConnected) {
return;
}
UpdatePlayerData(player);
}
void Unload() {
if (controller != null) {
var component = controller.GetComponent<PlayersExp>();
if (component != null) UnityEngine.Object.Destroy(component);
}
Interface.Oxide.DataFileSystem.WriteObject(DataPath, usersData);
PrintWarning("Plugin unloaded! Author: BadMandarin!");
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["OnGive"]
= "[GalaxyRust] Вы получили {0}XP напишите /night чтобы их потратить!", ["CmdBlocked"] = "[GalaxyRust] Данная команда доступна только ночью!", ["NoEXP"] = "[GalaxyRust] У вас недостаточно EXP!", ["ItemTaken"] = "[GalaxyRust] Вы успешно забрали предмет!",
}
, this);
}
#endregion
#region Interface
private void Load_ExpBlock(BasePlayer player) {
if (!usersData.ContainsKey(player.userID)) usersData.Add(player.userID, new UserData());
CuiElementContainer container = new CuiElementContainer() {
{
new CuiPanel {
CursorEnabled = true, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
, Image = {
Color = "0 0 0 0"
}
}
, "Overlay", UI_Layer
}
, {
new CuiElement {
Parent = UI_Layer, Name = UI_Layer + ".Black", Components = {
new CuiImageComponent {
Color = GetColor("#000000", 0.3f), Material = "assets/content/ui/uibackgroundblur.mat"
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
}
}
}
, {
new CuiButton {
RectTransform = {
AnchorMin = $"0 0", AnchorMax = $"1 1",
}
, Button = {
Color = "0 0 0 0", Close = UI_Layer
}
, Text = {
Text = ""
}
}
, UI_Layer
}
, {
new CuiElement {
Parent = UI_Layer, Name = UI_Layer + ".MainBlock", Components = {
new CuiRawImageComponent {
Png = GetImage(GetNameByURL(customImages["mainback"])), Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0.5 0.5", AnchorMax = $"0.5 0.5", OffsetMin = "-530 -170", OffsetMax = "530 220"
}
}
}
}
, {
new CuiElement {
Parent = UI_Layer + ".MainBlock", Name = UI_Layer + ".Imptn", Components = {
new CuiImageComponent {
Color = GetColor("#000000", 0f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 1", AnchorMax = $"1 1", OffsetMin = "0 0", OffsetMax = "0 60"
}
}
}
}
, {
new CuiElement {
Parent = UI_Layer + ".Imptn", Components = {
new CuiRawImageComponent {
Png = GetImage(GetNameByURL(customImages["important"])), Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0.5 0", AnchorMax = $"0.5 1", OffsetMin = "-235 20", OffsetMax = "235 0"
}
}
}
}
, {
new CuiElement {
Parent = UI_Layer + ".Imptn", Components = {
new CuiTextComponent {
Text = $"после нажатия на ячейку, предмет автоматически переместится к вам в инвентарь".ToUpper(), Align = TextAnchor.MiddleCenter, Font = "RobotoCondensed-Regular.ttf", FontSize = 12, Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = "0 0", OffsetMax = "0 -35"
}
}
}
}
, {
new CuiElement {
Parent = UI_Layer, Name = UI_Layer + ".Balance", Components = {
new CuiImageComponent {
Color = GetColor("#000000", 0f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"0 0", OffsetMin = "5 5", OffsetMax = "155 40"
}
}
}
}
, {
new CuiElement {
Parent = UI_Layer + ".Balance", Components = {
new CuiRawImageComponent {
Png = GetImage(GetNameByURL(customImages["balance"])), Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"0 1", OffsetMin = "0 0", OffsetMax = "100 0"
}
,
}
}
}
, {
new CuiElement {
Parent = UI_Layer + ".Balance", Components = {
new CuiTextComponent {
Text = $"{usersData[player.userID].Exp}".ToUpper(), Align = TextAnchor.MiddleLeft, Font = "RobotoCondensed-Bold.ttf", FontSize = 24, Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = "110 0", OffsetMax = "0 0"
}
,
}
}
}
, {
new CuiElement {
Parent = UI_Layer + ".MainBlock", Name = UI_Layer + ".LowBlock", Components = {
new CuiImageComponent {
Color = GetColor("#000000", 0f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 1", AnchorMax = $"0 1", OffsetMin = $"0 -130", OffsetMax = $"0 -30"
}
}
}
}
, {
new CuiElement {
Parent = UI_Layer + ".MainBlock", Name = UI_Layer + ".Text", Components = {
new CuiTextComponent {
Text = $"Вы можете использовать свои XP очки и забрать любой из предметов в ячейке.\nКаждый последующий предмет Вы сможете забрать только после того, как\nоткроете предыдущую ячейку. Каждую ночь Вам будет начисляться 100 XP".ToUpper(), Align = TextAnchor.UpperCenter, Font = "RobotoCondensed-Regular.ttf", FontSize = 14, Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 0", OffsetMin = $"0 -100", OffsetMax = $"0 -10"
}
}
}
}
,
}
;
int d = 0;
int i = 0;
for(int a = 0; a<27; a++) {
container.Add(new CuiElement {
Parent = UI_Layer + ".MainBlock", Name = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiImageComponent {
Color = GetColor("#000000", 0f)
}
, new CuiRectTransformComponent {
AnchorMin = (a > 8 && a <18)?$"1 1" : $"0 1", AnchorMax = (a > 8 && a <18)?$"1 1" : $"0 1", OffsetMin = (a > 8 && a <18) ?$"{-120 - i*115} {-130-d*115}" : $"{20 + i*115} {-130-d*115}", OffsetMax = (a > 8 && a <18) ?$"{-20 - i*115} {-30 -d*115}" : $"{120 + i*115} {-30 -d*115}"
}
}
}
);
if (a == 8 || a == 17) container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiImageComponent {
Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0.5 0", AnchorMax = $"0.5 0", OffsetMin = $"-2 -20", OffsetMax = $"2 5"
}
}
}
);
else if(a != 26 && a != 9) container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiImageComponent {
Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"1 0.5", AnchorMax = $"1 0.5", OffsetMin = $"-5 -2", OffsetMax = $"20 2"
}
}
}
);
if (a == 16) container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiImageComponent {
Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0.5", AnchorMax = $"0 0.5", OffsetMin = $"-20 -2", OffsetMax = $"5 2"
}
}
}
);
if (usersData[player.userID].LowProgress >= a) {
container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiRawImageComponent {
Png = GetImage(GetNameByURL(customImages["mainblock"])), Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = $"0 0", OffsetMax = $"0 0"
}
}
}
);
if (config.LowItems.Count() > a) {
var itm = config.LowItems.ElementAt(a);
container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiRawImageComponent {
Png = GetImage(itm.Key), Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = $"10 10", OffsetMax = $"-10 -10"
}
}
}
);
container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiTextComponent {
Text = $"{itm.Value}", Align = TextAnchor.MiddleCenter, Font = "RobotoCondensed-Bold.ttf", FontSize = 30, Color = GetColor("#FFFFFF", 0.9f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = $"0 0", OffsetMax = $"0 0"
}
}
}
);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Button = {
Color = "0 0 0 0", Command = $"UI_GExpHandle {a}"
}
, Text = {
Text = ""
}
}
, $"{UI_Layer}.LowBlock.{a}");
}
}
else {
if (config.LowItems.Count() > a) {
var itm = config.LowItems.ElementAt(a);
container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiRawImageComponent {
Png = GetImage(itm.Key), Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = $"10 10", OffsetMax = $"-10 -10"
}
}
}
);
}
container.Add(new CuiElement {
Parent = $"{UI_Layer}.LowBlock.{a}", Components = {
new CuiRawImageComponent {
Png = GetImage(GetNameByURL(customImages["mainlock"])), Color = GetColor("#FFFFFF", 1f)
}
, new CuiRectTransformComponent {
AnchorMin = $"0 0", AnchorMax = $"1 1", OffsetMin = $"0 0", OffsetMax = $"0 0"
}
}
}
);
}
i++;
if(i >= 9) {
i = 0;
d++;
}
}
CuiHelper.DestroyUi(player, UI_Layer);
CuiHelper.AddUi(player, container);
}
#endregion
#region Commands
[ConsoleCommand("UI_GExpHandle")]
private void Console_GExpHandle(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (player == null) return;
int item = Int32.Parse(arg.Args[0]);
var i = config.LowItems.ElementAt(item);
if(usersData[player.userID].Exp >= i.Value) {
usersData[player.userID].Exp -= i.Value;
if(item >= usersData[player.userID].LowProgress) usersData[player.userID].LowProgress++;
Item itm = ItemManager.CreateByName(i.Key, 1);
itm.MoveToContainer(player.inventory.containerMain);
SendReply(player, lang.GetMessage("ItemTaken", this));
Load_ExpBlock(player);
}
else {
SendReply(player, lang.GetMessage("NoEXP", this));
}
}
[ChatCommand("night")]
void Chat_Night(BasePlayer player, string command, string[] args) {
if (config.CommandNight) {
if (TOD_Sky.Instance.Cycle.Hour >= TimeSpan.Parse($"{config.NightFrom}:00").TotalHours && TOD_Sky.Instance.Cycle.Hour < TimeSpan.Parse($"{config.NightTo}:00").TotalHours) Load_ExpBlock(player);
else SendReply(player, lang.GetMessage("CmdBlocked", this));
}
else Load_ExpBlock(player);
}
#endregion
#region Utils
private int GetBlockWidth(int itms, int distance, int size) {
return distance * itms + 1 + size * itms;
}
private string GetImage(string name) {
string ID = (string)ImageLibrary?.Call("GetImage", name);
if (ID == "") ID = (string)ImageLibrary?.Call("GetImage", name) ?? ID;
return ID;
}
private void AddImage(string url, string iname = null) {
string name = "";
if (string.IsNullOrEmpty(iname)) name = GetNameByURL(url);
else name = iname;
if (!(bool)ImageLibrary?.Call("HasImage", name)) ImageLibrary.Call("AddImage", url, name);
}
public static string GetColor(string hex, float alpha = 1f) {
var color = ColorTranslator.FromHtml(hex);
var r = Convert.ToInt16(color.R) / 255f;
var g = Convert.ToInt16(color.G) / 255f;
var b = Convert.ToInt16(color.B) / 255f;
return $"{r} {g} {b} {alpha}";
}
private string GetNameByURL(string url) {
var splitted = url.Split('/');
var endUrl = splitted[splitted.Length - 1];
var name = endUrl.Split('.')[0];
return name;
}
private void UpdatePlayerData(BasePlayer player) {
if (!usersData.ContainsKey(player.userID)) usersData.Add(player.userID, new UserData());
usersData[player.userID].NeedToPlay = GetCurrentTime() + config.TimeEvery;
}
private static double GetCurrentTime() {
return new TimeSpan(DateTime.UtcNow.Ticks).TotalSeconds;
}
protected override void LoadDefaultConfig() {
Config.WriteObject(GetDefaultConfig(), true);
}
private PluginConfig GetDefaultConfig() {
return new PluginConfig {
TimeEvery = 3600f, ExpGiveAmount = 100, GiveNight = true, LowItems = new Dictionary<string, int>() {
["shotgun.waterpipe"]
= 200
}
,
}
;
}
#endregion
#region ExpGiver
private class PlayersExp : MonoBehaviour {
bool GiveNight = instance.config.GiveNight;
float CheckTime = instance.config.CheckTime;
int from = instance.config.NightFrom;
int to = instance.config.NightTo;
private void Awake() {
InvokeRepeating(nameof(CheckPlayers), 1f, CheckTime);
}
private void CheckPlayers() {
if (BasePlayer.activePlayerList == null || BasePlayer.activePlayerList.ToList().Count() < 1) return;
if (GiveNight) {
if ((TOD_Sky.Instance.Cycle.Hour >= from && TOD_Sky.Instance.Cycle.Hour <= 24) || TOD_Sky.Instance.Cycle.Hour < to) BasePlayer.activePlayerList.ToList().ForEach(p => GiveExp(p));
}
else BasePlayer.activePlayerList.ToList().ForEach(p => GiveExp(p));
}
private void GiveExp(BasePlayer player) {
UserData data = null;
if (!instance.usersData.TryGetValue(player.userID, out data)) return;
if (data.NeedToPlay > GetCurrentTime()) return;
instance.usersData[player.userID].Exp += instance.config.ExpGiveAmount;
instance.usersData[player.userID].NeedToPlay = GetCurrentTime() + instance.config.TimeEvery;
instance.SendReply(player, instance.lang.GetMessage("OnGive", instance), instance.config.ExpGiveAmount);
}
private void OnDestroy() {
CancelInvoke(nameof(CheckPlayers));
}
}
#endregion
}
}