C#:
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Oxide.Core;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
namespace Oxide.Plugins
{
[Info("WelcomeTop", "https://topplugin.ru/", "2.0.1")]
[Description("Welcome Information Panel for Server")]
class WelcomeTop : RustPlugin
{
#region Fields
[PluginReference] private Plugin ImageLibrary;
private const string Layer = "WelcomePanelUI";
#endregion
#region Data
private static PluginData _data;
private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, _data);
private void LoadData()
{
try
{
_data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_data == null) _data = new PluginData();
}
private class PluginData
{
public List<ulong> Users = new List<ulong>();
}
#endregion
#region Config
private static ConfigData config;
private class ConfigData
{
[JsonProperty(PropertyName = "Показать панель один раз?")]
public bool introduce;
[JsonProperty(PropertyName = "Настройка логотипа")]
public LogoSettings logo;
[JsonProperty(PropertyName = "Настройка кнопки закрытия")]
public CloseSettings close;
[JsonProperty("Настройка меню")]
public List<MenuSettings> menu;
}
private class LogoSettings
{
[JsonProperty(PropertyName = "Включено??")]
public bool enabled;
[JsonProperty(PropertyName = "Ссылка на логотип URL")]
public string logoUrl;
}
private class MenuSettings
{
[JsonProperty(PropertyName = "Ссылка на иконку")]
public string menuIcon;
[JsonProperty(PropertyName = "Текст кнопки")]
public string menuBTtext;
[JsonProperty(PropertyName = "Текст заголовка")]
public string TitleText;
[JsonProperty(PropertyName = "Размер заголовка")]
public int fSize;
[JsonProperty(PropertyName = "Текст")]
public List<string> description;
}
private class CloseSettings
{
[JsonProperty(PropertyName = "Отображать кнопку закрытия только на последней странице?")]
public bool closePage;
[JsonProperty(PropertyName = "Текст на кнопке закрытия")]
public string closeText;
[JsonProperty(PropertyName = "Размер шрифта")]
public int fSize;
}
private ConfigData GetDefaultConfig()
{
return new ConfigData
{
introduce = true,
logo = new LogoSettings
{
enabled = true,
logoUrl = "https://s2.wampi.ru/2020/07/25/uixpro-logo1.png"
},
close = new CloseSettings
{
closePage = true,
closeText = "Я прочитал все, что указано здесь",
fSize = 16
},
menu = new List<MenuSettings>
{
new MenuSettings
{
menuIcon = "https://s2.wampi.ru/2020/07/25/uixpro-logo1.png",
menuBTtext = "Информация 1",
TitleText = "",
fSize = 26,
description = new List<string>
{
"<b><color=#b0fa66>Добро пожаловать на TopPlugin.ru, пожалуйста, прочитайте это перед тем как играть.</color></b>",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
}
},
new MenuSettings
{
menuIcon = "https://s2.wampi.ru/2020/07/25/uixpro-logo1.png",
menuBTtext = "Информация 2",
TitleText = "",
fSize = 26,
description = new List<string>
{
"<b><color=#b0fa66>Добро пожаловать на TopPlugin.ru, пожалуйста, прочитайте это перед тем как играть.</color></b>",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабл",
}
},
new MenuSettings
{
menuIcon = "https://s2.wampi.ru/2020/07/25/uixpro-logo1.png",
menuBTtext = "Информация 3",
TitleText = "",
fSize = 26,
description = new List<string>
{
"<b><color=#b0fa66>Добро пожаловать на TopPlugin.ru, пожалуйста, прочитайте это перед тем как играть.</color></b>",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабла",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабла",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабла",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабла",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабла",
"<color=#b0fa66>■</color> блаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблаблабла",
}
}
}
};
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<ConfigData>();
if (config == null)
{
LoadDefaultConfig();
}
}
catch
{
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig()
{
PrintError("Configuration file is corrupt(or not exists), creating new one!");
config = GetDefaultConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Hooks
private void OnServerInitialized()
{
PrintWarning(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
PrintWarning($" {Name} v{Version} loading");
if (!ImageLibrary)
{
PrintError(" Install plugin: 'ImageLibrary'");
Interface.Oxide.UnloadPlugin(Title);
return;
}
PrintWarning($" Plugin loaded - OK");
PrintWarning(" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
LoadData();
if (config.logo.enabled) ImageLibrary.Call("AddImage", config.logo.logoUrl, "WelcomePanelLogo");
for (int i = 0; i < config.menu.Count; i++)
ImageLibrary.Call("AddImage", config.menu[i].menuIcon, $"WelcomePanelImage.{i}");
}
void OnPlayerConnected(BasePlayer player)
{
if (player == null || player.IsNpc) return;
if (player.IsReceivingSnapshot || player.IsSleeping())
{
timer.In(1f, () => OnPlayerConnected(player));
return;
}
if (config.introduce && !_data.Users.Contains(player.userID))
{
InitializeUI(player);
_data.Users.Add(player.userID);
SaveData();
}
else if (!config.introduce)
{
InitializeUI(player);
}
}
#endregion
#region Commands
[ChatCommand("info")]
private void CmdChatInfo(BasePlayer player, string command, string[] args)
{
InitializeUI(player);
}
[ChatCommand("info")]
private void CmdChatHelp(BasePlayer player, string command, string[] args)
{
InitializeUI(player);
}
[ConsoleCommand("welcomemenu")]
private void CmdConsole(ConsoleSystem.Arg args)
{
BasePlayer player = args.Player();
if (player == null || !args.HasArgs(1)) return;
switch (args.Args[0].ToLower())
{
case "page":
{
int page = 0;
if (!args.HasArgs(2) || !int.TryParse(args.Args[1], out page)) return;
EffectNetwork.Send(new Effect("assets/prefabs/weapons/semi auto rifle/effects/dryfire.prefab", player.transform.position, Vector3.zero), player.net.connection);
InitializeUI(player, page);
}
break;
}
return;
}
#endregion
#region Interface
private void InitializeUI(BasePlayer player, int page = 0)
{
var container = new CuiElementContainer();
var list = config.menu[page];
var yCoord = 2;
container.Add(new CuiPanel //ФОН ИНФО-ПАНЕЛИ
{
CursorEnabled = true,
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-500 -240", OffsetMax = "500 280" },
Image = { Color = HexToCuiColor("#202020C9"), Material = "assets/content/ui/uibackgroundblur.mat" },
}, "Overlay", Layer + ".Blur");
container.Add(new CuiButton //ФОНОНОВОЕ ЗАКРЫТИЕ
{
RectTransform = { AnchorMin = "-1 -1", AnchorMax = "1.3 1.3", OffsetMax = "0 0" },
Button = { Color = "0.1 0.1 0.1 0.3", Close = Layer + ".Blur" },
Text = { Text = "" }
}, Layer + ".Blur", Layer);
container.Add(new CuiPanel //ФОН КНОПОК
{
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-500 -130", OffsetMax = "-268 270" },
Image = { Color = "0.8 0.8 0.8 0.0" }
}, Layer + ".Blur", Layer);
container.Add(new CuiPanel //ФОН МЕНЮ
{
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-270 -260", OffsetMax = "500 210" },
Image = { Color = "0.8 0.8 0.8 0.0" }
}, Layer + ".Blur", Layer);
if (config.logo.enabled)
container.Add(new CuiElement
{
Parent = Layer,
Components =
{
new CuiRawImageComponent { Png = (string) ImageLibrary.Call("GetImage", "WelcomePanelLogo") },
new CuiRectTransformComponent { AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-80 5", OffsetMax = "80 35" },
}
});
for (int i = 0; i < config.menu.Count; i++)
{
container.Add(new CuiButton //КНОПКИ МЕНЮ
{
RectTransform = { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"-217 {yCoord - 39}", OffsetMax = $"0 {yCoord -2}" },
Button = { Color = page == i? "0.5 0.5 0.5 0.03" : //цвет активный
"0.8 0.8 0.8 0.03", //цвет обычный
Command = $"welcomemenu page {i}", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat" },
Text = { Text = config.menu[i].menuBTtext, FontSize = 16, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf" }
}, Layer, Layer + $".Btn.{i}");
yCoord -= 43;
container.Add(new CuiElement
{
Parent = Layer + $".Btn.{i}",
Components =
{
new CuiRawImageComponent { Png = (string) ImageLibrary.Call("GetImage", $"WelcomePanelImage.{i}"), Color = "0 0 0 0" },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 3", OffsetMax = "-5 -3" },
}
});
}
container.Add(new CuiButton //ЗАГОЛОВОК
{
RectTransform = { AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-385 0", OffsetMax = "385 50" },
Button = { Color = "0.8 0.8 0.8 0.00", Close = Layer + ".Blur" },
Text = { Text = string.Join("\n", list.TitleText), FontSize = list.fSize, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf" }
}, Layer);
container.Add(new CuiLabel //ОПИСАНИЕ
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "20 0", OffsetMax = "-20 -10" },
Text = { Text = string.Join("\n", list.description), FontSize = 16, Align = TextAnchor.UpperLeft, Font = "robotocondensed-regular.ttf" }
}, Layer);
if (!config.close.closePage || (config.close.closePage && page == config.menu.Count - 1))
{
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-603 13", OffsetMax = "-384 52" },
Button = { Color = "0.8 0.8 0.8 0.03", Close = Layer + ".Blur", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat" },
Text = { Text = config.close.closeText, FontSize = config.close.fSize, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf" }
}, Layer, Layer + ".Btn.Close");
}
CuiHelper.DestroyUi(player, Layer + ".Blur");
CuiHelper.AddUi(player, container);
}
#endregion
#region Helper
private static string HexToCuiColor(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 $"{color.r:F2} {color.g:F2} {color.b:F2} {color.a:F2}";
}
#endregion
}
}