C#:
using Oxide.Core.Plugins;
using UnityEngine;
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using Oxide.Game.Rust.Cui;
using Newtonsoft.Json.Converters;
using System.Text.RegularExpressions;
using System.Linq;
using Oxide.Core;
using System.IO;
using System;
namespace Oxide.Plugins
{
[Info("MBMainMenu", "Baryy_Allenn", "1.0.0")]
[Description("Открывает главное меню по команде /info")]
public class MBMainMenu : RustPlugin
{
[PluginReference] private Plugin ImageLibrary, MBCoins, Economics, ServerRewards, MBCalendar, MBCommands, MBPrivileges, MBCraft, MBReward;
private ImageUI imageUI = new ImageUI();
private ConfigData configData;
private Dictionary<ulong, double> playTime = new();
private Dictionary<ulong, DateTime> sessionStart = new();
private bool isAirdropActive = false;
private bool isCargoActive = false;
private bool isChinookActive = true;
private bool isBradleyActive = false;
private bool isHelicopterActive = false;
private int joiningPlayersCount = 0;
#region Config
private class ConfigData
{
[JsonProperty("Тип економіки (Economics, ServerRewards, MBCoins)")]
[JsonConverter(typeof(StringEnumConverter))]
public EconomySystem EconomyType { get; set; } = EconomySystem.MBCoins;
[JsonProperty("Максимальний баланс для заповнення полоски")]
public float MaxBalance { get; set; } = 500f;
[JsonProperty("Назва сервера")]
public string NameServer = "MB-UA-RUST";
[JsonProperty("Посилання на сайт")]
public string WebsiteServer = "freedom-ua-rust.com";
// [JsonProperty("QR Code на сайт")]
// public string QrWebsiteUrl = "https://i.ibb.co/gZmXsk6v/image-removebg-preview-21.png";
[JsonProperty("Посилання на Discord")]
public string DiscordServer = "discord.gg/bv6uMXx5";
// [JsonProperty("QR Code на Discord")]
// public string QrDiscordUrl = "https://i.ibb.co/p67XVZyS/qrcode-removebg-preview.png";
[JsonProperty("Посилання на TikTok")]
public string TikTokServer = "tiktok.com/@freedom.ua.rust";
// [JsonProperty("QR Code на TikTok")]
// public string QrTikTokUrl = "https://i.ibb.co/BVSDYpS4/qrcode-1-removebg-preview.png";
}
public enum EconomySystem
{
None,
Economics,
ServerRewards,
MBCoins
}
protected override void LoadConfig()
{
base.LoadConfig();
configData = Config.ReadObject<ConfigData>();
SaveConfig();
}
protected override void SaveConfig()
{
Config.WriteObject(configData, true);
}
protected override void LoadDefaultConfig()
{
configData = new ConfigData();
}
#endregion
void Init()
{
LoadConfig();
// imageUI = new ImageUI();
// imageUI.DownloadImages();
}
void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
{
CuiHelper.DestroyUi(player, "MBMainMenu_UI");
CuiHelper.DestroyUi(player, "MBWebsite_UI");
CuiHelper.DestroyUi(player, "MBDiscord_UI");
CuiHelper.DestroyUi(player, "MBTikTok_UI");
CuiHelper.DestroyUi(player, "MBPlyment_UI");
}
imageUI?.UnloadImages();
}
private void OnServerInitialized()
{
isAirdropActive = BaseNetworkable.serverEntities.Any(ent => ent?.ShortPrefabName == "supply_drop");
isCargoActive = BaseNetworkable.serverEntities.Any(ent => ent is CargoShip);
isHelicopterActive = BaseNetworkable.serverEntities.Any(ent => ent is PatrolHelicopterAI);
isChinookActive = BaseNetworkable.serverEntities.Any(ent => ent is CH47HelicopterAIController);
isBradleyActive = BaseNetworkable.serverEntities.Any(ent => ent?.ShortPrefabName == "bradleyapc");
PrintWarning($"[MBMainMenu] Сервер запущен:\n" +
$"- Airdrop: {isAirdropActive}\n" +
$"- Cargo: {isCargoActive}\n" +
$"- Heli: {isHelicopterActive}\n" +
$"- Chinook: {isChinookActive}\n" +
$"- Bradley: {isBradleyActive}");
// Обновление количества входящих игроков
timer.Every(1f, () =>
{
var queue = ServerMgr.Instance.connectionQueue;
joiningPlayersCount = queue.joining.Count;
});
// 🧠 Восстановление таймера для уже подключённых игроков
foreach (var player in BasePlayer.activePlayerList)
{
if (player != null && player.IsConnected)
{
if (!playTime.ContainsKey(player.userID))
playTime[player.userID] = LoadPlayTime(player.userID);
if (!sessionStart.ContainsKey(player.userID))
sessionStart[player.userID] = DateTime.UtcNow;
}
}
// Автоматическое сохранение отыгранного времени каждые 5 минут
timer.Every(300f, () =>
{
foreach (var kvp in sessionStart)
{
ulong userID = kvp.Key;
DateTime joinTime = kvp.Value;
double sessionSeconds = (DateTime.UtcNow - joinTime).TotalSeconds;
double total = sessionSeconds;
if (playTime.TryGetValue(userID, out var saved))
total += saved;
SavePlayTime(userID, total);
}
});
imageUI = new ImageUI();
imageUI.DownloadImages();
}
private readonly Regex Regex = new Regex(@"<avatarFull><!\[CDATA\[(.*)\]\]></avatarFull>");
private void GetAvatar(string userId, Action<string> callback)
{
if (callback == null) return;
try
{
webrequest.Enqueue($"http://steamcommunity.com/profiles/{userId}?xml=1", null, (code, response) =>
{
if (code != 200 || response == null) return;
var avatar = Regex.Match(response).Groups[1].ToString();
if (string.IsNullOrEmpty(avatar)) return;
callback.Invoke(avatar);
}, this);
}
catch (Exception e)
{
PrintError($"[MBMainMenu] Ошибка загрузки аватарки: {e.Message}");
}
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null || !player.userID.IsSteamId()) return;
GetAvatar(player.UserIDString, avatarUrl =>
{
ImageLibrary?.Call("AddImage", avatarUrl, $"avatar_{player.UserIDString}");
});
sessionStart[player.userID] = DateTime.UtcNow;
// Загрузи общее время, если не загружено
if (!playTime.ContainsKey(player.userID))
playTime[player.userID] = LoadPlayTime(player.userID);
ShowIntroImage(player); // ← Добавлено
}
private double LoadPlayTime(ulong userID)
{
var data = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, double>>("MBSystem/MBMainMenu/PlayTime");
return data.TryGetValue(userID, out var value) ? value : 0;
}
private void SavePlayTime(ulong userID, double time)
{
var path = "MBSystem/MBMainMenu/PlayTime";
var data = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, double>>(path);
data[userID] = time;
Interface.Oxide.DataFileSystem.WriteObject(path, data);
}
private void OnPlayerDisconnected(BasePlayer player, string reason)
{
if (player == null) return;
if (sessionStart.TryGetValue(player.userID, out var startTime))
{
double sessionSeconds = (DateTime.UtcNow - startTime).TotalSeconds;
playTime[player.userID] += sessionSeconds;
SavePlayTime(player.userID, playTime[player.userID]);
}
sessionStart.Remove(player.userID);
}
private double GetPlayerBalance(BasePlayer player)
{
switch (configData.EconomyType)
{
case EconomySystem.Economics:
return (double)(Economics?.Call("Balance", player.UserIDString) ?? 0.0);
case EconomySystem.ServerRewards:
return (int)(ServerRewards?.Call("CheckPoints", player.userID) ?? 0);
case EconomySystem.MBCoins:
return Convert.ToDouble(MBCoins?.Call("GetPlayerBalance", (ulong)player.userID) ?? 0.0);
default:
return 0.0;
}
}
private void OnEntitySpawned(BaseEntity entity)
{
if (entity?.ShortPrefabName == "supply_drop")
{
isAirdropActive = true;
PrintWarning("[MBMainMenu] Airdrop ЗАСПАВНИЛСЯ → isAirdropActive = true");
}
if (entity is CargoShip)
{
isCargoActive = true;
PrintWarning("[MBMainMenu] CargoShip ЗАСПАВНИЛСЯ → isCargoActive = true");
}
if (entity is CH47HelicopterAIController)
{
isChinookActive = true;
PrintWarning($"[MBMainMenu] Chinook ПРИБЫЛ → isChinookActive = {isChinookActive}");
}
if (entity.GetComponent<PatrolHelicopterAI>() != null)
{
isHelicopterActive = true;
PrintWarning("[MBMainMenu] Helicopter ПРИБЫЛ → isHelicopterActive = true");
}
if (entity?.ShortPrefabName == "bradleyapc")
{
isBradleyActive = true;
PrintWarning("[MBMainMenu] Bradley ЗАСПАВНИЛСЯ → isBradleyActive = true");
}
}
private void OnEntityKill(BaseEntity entity)
{
if (entity?.ShortPrefabName == "supply_drop")
{
timer.Once(0.1f, () =>
{
isAirdropActive = BaseNetworkable.serverEntities.Any(ent => ent?.ShortPrefabName == "supply_drop");
});
}
if (entity is CargoShip)
{
timer.Once(0.1f, () =>
{
isCargoActive = BaseNetworkable.serverEntities.Any(ent => ent is CargoShip);
PrintWarning($"[MBMainMenu] CargoShip УНИЧТОЖЕН → isCargoActive = {isCargoActive}");
});
}
if (entity is CH47HelicopterAIController)
{
timer.Once(0.1f, () =>
{
isChinookActive = BaseNetworkable.serverEntities.Any(ent => ent is CH47HelicopterAIController);
PrintWarning($"[MBMainMenu] Chinook УНИЧТОЖЕН → isChinookActive = {isChinookActive}");
});
}
if (entity.GetComponent<PatrolHelicopterAI>() != null)
{
timer.Once(0.1f, () =>
{
isHelicopterActive = BaseNetworkable.serverEntities.OfType<BaseEntity>().Any(ent => ent.GetComponent<PatrolHelicopterAI>() != null);
PrintWarning($"[MBMainMenu] Helicopter УНИЧТОЖЕН → isHelicopterActive = {isHelicopterActive}");
});
}
if (entity?.ShortPrefabName == "bradleyapc")
{
timer.Once(0.1f, () =>
{
isBradleyActive = BaseNetworkable.serverEntities.Any(ent => ent?.ShortPrefabName == "bradleyapc");
PrintWarning($"[MBMainMenu] Bradley УНИЧТОЖЕН → isBradleyActive = {isBradleyActive}");
});
}
}
[ChatCommand("zxc")]
private void Cmdhghjtk(BasePlayer player, string command, string[] args)
{
ShowIntroImage(player);
}
private void ShowIntroImage(BasePlayer player)
{
CuiHelper.DestroyUi(player, "MBMainMenu_IntroUI");
var container = new CuiElementContainer();
string imageId = imageUI?.GetImage("MBWelcome_One_Os");
if (string.IsNullOrEmpty(imageId))
{
PrintWarning("[MBMainMenu] Intro image not loaded");
return;
}
container.Add(new CuiElement
{
Name = "MBMainMenu_IntroUI",
Parent = "Overlay",
Components =
{
new CuiRawImageComponent
{
Png = imageId,
Color = "1 1 1 0", // полная непрозрачность картинки
Sprite = "assets/content/textures/generic/fulltransparent.tga"
},
new CuiRectTransformComponent
{
AnchorMin = "0 0.5",
AnchorMax = "1 1"
}
}
});
CuiHelper.AddUi(player, container);
timer.Once(0.5f, () =>
{
CuiHelper.DestroyUi(player, "MBMainMenu_IntroUI");
});
}
#region MainMenu
private void ShowMainMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "MBMainMenu_UI");
var container = new CuiElementContainer();
// Корневая панель
string root = container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
CursorEnabled = true
}, "Overlay", "MBMainMenu_UI");
// Затемнённый фон
string backgroundPanel = container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0.7", Material = "assets/content/ui/uibackgroundblur.mat" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
CursorEnabled = true
}, root);
// Центральная панель поверх картинки
string centerFonPanel = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0" },
RectTransform = {
AnchorMin = "0.5 0.5",
AnchorMax = "0.5 0.5",
OffsetMin = "-438 -265", // ширина 800, высота 600
OffsetMax = "440 265"
},
CursorEnabled = true
}, root);
container.Add(new CuiElement
{
Parent = centerFonPanel,
Components =
{
new CuiRawImageComponent
{
Png = (string)ImageLibrary.Call("GetImage", $"avatar_{player.UserIDString}"),
},
new CuiRectTransformComponent
{
AnchorMin = "0.329 0.898", AnchorMax = "0.3712 0.968"
}
}
});
// ====== Онлайн-полоска до картинки ======
string barAnchorMin = "0.36 0.55"; // нижний левый угол
string barAnchorMax = "0.936 0.58"; // верхний правый угол
float online = BasePlayer.activePlayerList.Count;
float maxPlayers = ConVar.Server.maxplayers;
float percentOnline = Mathf.Clamp01(online / Mathf.Max(maxPlayers, 1));
// Расчёт ширины полосы
string[] minParts = barAnchorMin.Split(' ');
string[] maxParts = barAnchorMax.Split(' ');
float xMin = float.Parse(minParts[0], System.Globalization.CultureInfo.InvariantCulture);
float xMax = float.Parse(maxParts[0], System.Globalization.CultureInfo.InvariantCulture);
float yMin = float.Parse(minParts[1], System.Globalization.CultureInfo.InvariantCulture);
float yMax = float.Parse(maxParts[1], System.Globalization.CultureInfo.InvariantCulture);
float width = xMax - xMin;
// Фон полоски
container.Add(new CuiPanel
{
Image = { Color = "0 0 0 1" },
RectTransform = { AnchorMin = barAnchorMin, AnchorMax = barAnchorMax }
}, centerFonPanel, "OnlineBarBackground_Os");
// Заполнение онлайном
container.Add(new CuiPanel
{
Image = { Color = "1.00 1.00 0.00 1.00" },
RectTransform = {
AnchorMin = $"{xMin.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)} {yMin.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)}",
AnchorMax = $"{(xMin + width * percentOnline).ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)} {yMax.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)}"
}
}, centerFonPanel);
// 🔄 Получение баланса игрока
float balance = (float)GetPlayerBalance(player);
float maxBalance = configData.MaxBalance;
float fillPercent = Mathf.Clamp01(balance / maxBalance);
// ⚙️ Положение полосы
string barMin = "0.713 0.927";
string barMax = "0.772 0.94";
// 🟥 Фон полосы
container.Add(new CuiPanel
{
Image = { Color = "0 0 0 1" },
RectTransform = { AnchorMin = barMin, AnchorMax = barMax }
}, centerFonPanel);
// 📏 Расчёт ширины
string[] barMinSplit = barMin.Split(' ');
string[] barMaxSplit = barMax.Split(' ');
float xStartBar = float.Parse(barMinSplit[0], System.Globalization.CultureInfo.InvariantCulture);
float xEndBar = float.Parse(barMaxSplit[0], System.Globalization.CultureInfo.InvariantCulture);
float yMinBar = float.Parse(barMinSplit[1], System.Globalization.CultureInfo.InvariantCulture);
float yMaxBar = float.Parse(barMaxSplit[1], System.Globalization.CultureInfo.InvariantCulture);
float widthBar = xEndBar - xStartBar;
// ✅ Заполненная часть полоски
container.Add(new CuiPanel
{
Image = { Color = "0.2 0.8 0.2 1" }, // зелёная
RectTransform = {
AnchorMin = $"{xStartBar.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)} {yMinBar.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)}",
AnchorMax = $"{(xStartBar + widthBar * fillPercent).ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)} {yMaxBar.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture)}"
}
}, centerFonPanel);
// 🔽 1.Фон-картинка поверх затемнения, под панелью
string imageId = imageUI?.GetImage("MBWelcome_One_Os"); // получаем ID изображения
if (!string.IsNullOrEmpty(imageId))
{
container.Add(new CuiElement
{
Name = CuiHelper.GetGuid(),
Parent = root,
Components =
{
new CuiRawImageComponent
{
Png = imageId
},
new CuiRectTransformComponent
{
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-558 -314", OffsetMax = "558 315" // по размеру как центр.панель, или на весь экран если нужно
}
}
});
}
// Кнопка "Закрыть"
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Close = "MBMainMenu_UI" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "", FontSize = 0 }
}, root);
// Центральная панель поверх картинки
string centerPanel = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0" },
RectTransform = {
AnchorMin = "0.5 0.5",
AnchorMax = "0.5 0.5",
OffsetMin = "-438 -265", // ширина 800, высота 600
OffsetMax = "440 265"
},
CursorEnabled = true
}, root);
string rawTime = MBReward?.Call<string>("GetTimeToReward", player) ?? "N/A";
string timeToReward = Msg("MB_Reward_Time", player.UserIDString, rawTime);
container.Add(new CuiLabel
{
Text = {
Text = timeToReward,
FontSize = 8,
Align = TextAnchor.MiddleCenter,
Color = "1 1 1 0.5"
},
RectTransform = {
AnchorMin = "0.703 0.899", AnchorMax = "0.782 0.92"
}
}, centerPanel);
// Панель-фон
container.Add(new CuiPanel
{
Image = { Color = "0.67 0.87 0.80 0" }, // Темно-сірий прозорий фон
RectTransform = { AnchorMin = "0.703 0.899", AnchorMax = "0.782 0.92" }
}, centerPanel);
// 🧾 Текст с балансом над полоской
container.Add(new CuiLabel
{
Text = { Text = $"MB: {balance}", FontSize = 10, Align = TextAnchor.MiddleCenter, Color = "1 1 1 0.6", },
RectTransform = { AnchorMin = "0.713 0.945", AnchorMax = "0.772 0.97" }
}, centerPanel);
int joining = joiningPlayersCount; // ✅ Реальные подключающиеся
int queueCount = 0; // <-- Подставь реальное значение, если у тебя есть очередь
// Онлайн
container.Add(new CuiLabel
{
Text = { Text = $"{Msg("MB_Online", player.UserIDString)}: {online}", FontSize = 12, Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.7", Font = "robotocondensed-regular.ttf" },
RectTransform = { AnchorMin = "0.376 0.499", AnchorMax = "0.47 0.54" }
}, centerPanel);
// Максимум
container.Add(new CuiLabel
{
Text = { Text = $"{Msg("MB_Max", player.UserIDString)}: {maxPlayers}", FontSize = 12, Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.7", Font = "robotocondensed-regular.ttf" },
RectTransform = { AnchorMin = "0.856 0.499", AnchorMax = "0.936 0.54" }
}, centerPanel);
// Заходят
container.Add(new CuiLabel
{
Text = { Text = $"{Msg("MB_Joining", player.UserIDString)}: {joining}", FontSize = 12, Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.7", Font = "robotocondensed-regular.ttf" },
RectTransform = { AnchorMin = "0.535 0.499", AnchorMax = "0.64 0.54" }
}, centerPanel);
// Очередь
container.Add(new CuiLabel
{
Text = { Text = $"{Msg("MB_Queue", player.UserIDString)}: {queueCount}", FontSize = 12, Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.7", Font = "robotocondensed-regular.ttf" },
RectTransform = { AnchorMin = "0.696 0.499", AnchorMax = "0.79 0.54" }
}, centerPanel);
// Назва сервера
container.Add(new CuiLabel
{
Text = { Text = configData.NameServer, FontSize = 18, Color = "1 1 1 0.9", Align = TextAnchor.MiddleLeft, },
RectTransform = { AnchorMin = "0.3605 0.59", AnchorMax = "0.6 0.639" }
}, centerPanel);
// Назва сайта
container.Add(new CuiLabel
{
Text = { Text = configData.WebsiteServer, FontSize = 10, Color = "1 1 1 0.9", Align = TextAnchor.MiddleLeft, },
RectTransform = { AnchorMin = "0.58 0.915", AnchorMax = "0.64 0.955" }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.34 0.76", AnchorMax = "0.8 0.85" },
Text = { Text = Msg("MB_Hello_Player", player.userID.ToString()), Color = "1 1 1 0.9", Align = TextAnchor.MiddleLeft, FontSize = 30 }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.34 0.7", AnchorMax = "0.9 0.77" },
Text = { Text = Msg("MB_Hello_Player_2", player.userID.ToString()), Color = "1 1 1 0.9", Align = TextAnchor.MiddleLeft, FontSize = 25, Font = "permanentmarker.ttf" }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.343 0.395", AnchorMax = "0.6 0.455" },
Text = { Text = Msg("MB_Events", player.userID.ToString()), Color = "1 1 1 0.5", Align = TextAnchor.MiddleLeft, FontSize = 15, Font = "permanentmarker.ttf" }
}, centerPanel);
container.Add(new CuiLabel
{
Text = { Text = Msg("MB_Close_Menu", player.userID.ToString()), FontSize = 13, Color = "1 1 1 0.4", Align = TextAnchor.MiddleCenter },
RectTransform = { AnchorMin = "0.2 -0.06", AnchorMax = "0.8 -0.02" }
}, centerPanel);
string airdropImageId = imageUI.GetImage(isAirdropActive ? "Airdrop_On" : "Airdrop_Off");
if (!string.IsNullOrEmpty(airdropImageId))
{
container.Add(new CuiElement
{
Parent = centerPanel,
Components =
{
new CuiRawImageComponent { Png = airdropImageId, Sprite = "assets/content/textures/generic/fulltransparent.tga" },
new CuiRectTransformComponent { AnchorMin = "0.341 0.217", AnchorMax = "0.41 0.385" }
}
});
}
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.341 0.25", AnchorMax = "0.41 0.31" },
Text = { Text = Msg("MB_Airdrop", player.userID.ToString()), Color = "1 1 1 0.5", Align = TextAnchor.UpperCenter, FontSize = 9, Font = "robotocondensed-regular.ttf" }
}, centerPanel);
string cargoImageId = imageUI.GetImage(isCargoActive ? "Cargo_On" : "Cargo_Off");
if (!string.IsNullOrEmpty(cargoImageId))
{
container.Add(new CuiElement
{
Parent = centerPanel,
Components =
{
new CuiRawImageComponent { Png = cargoImageId, Sprite = "assets/content/textures/generic/fulltransparent.tga" },
new CuiRectTransformComponent { AnchorMin = "0.4199 0.217", AnchorMax = "0.489 0.385" }
}
});
}
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.4199 0.25", AnchorMax = "0.489 0.31" },
Text = { Text = Msg("MB_Cargo", player.userID.ToString()), Color = "1 1 1 0.5", Align = TextAnchor.UpperCenter, FontSize = 9, Font = "robotocondensed-regular.ttf" }
}, centerPanel);
string chinookImageId = imageUI.GetImage(isChinookActive ? "Chinook_On" : "Chinook_Off");
if (!string.IsNullOrEmpty(chinookImageId))
{
container.Add(new CuiElement
{
Parent = centerPanel, // Или "MBMenuPanel", если ты использовал эту панель
Components =
{
new CuiRawImageComponent { Png = chinookImageId, Sprite = "assets/content/textures/generic/fulltransparent.tga" },
new CuiRectTransformComponent { AnchorMin = "0.4992 0.217", AnchorMax = "0.568 0.385" }
}
});
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.4992 0.25", AnchorMax = "0.568 0.31" },
Text = { Text = Msg("MB_Chinook", player.userID.ToString()), Color = "1 1 1 0.5", Align = TextAnchor.UpperCenter, FontSize = 9, Font = "robotocondensed-regular.ttf" }
}, centerPanel);
}
string heliImageId = imageUI.GetImage(isHelicopterActive ? "Heli_On" : "Heli_Off");
if (!string.IsNullOrEmpty(heliImageId))
{
container.Add(new CuiElement
{
Parent = centerPanel,
Components =
{
new CuiRawImageComponent { Png = heliImageId, Sprite = "assets/content/textures/generic/fulltransparent.tga" },
new CuiRectTransformComponent { AnchorMin = "0.6582 0.217", AnchorMax = "0.7265 0.385" }
}
});
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.6582 0.25", AnchorMax = "0.7265 0.31" },
Text = { Text = Msg("MB_Heli", player.userID.ToString()), Color = "1 1 1 0.5", Align = TextAnchor.UpperCenter, FontSize = 9, Font = "robotocondensed-regular.ttf" }
}, centerPanel);
}
string bradleyImageId = imageUI.GetImage(isBradleyActive ? "Bradley_On" : "Bradley_Off");
if (!string.IsNullOrEmpty(bradleyImageId))
{
container.Add(new CuiElement
{
Parent = centerPanel,
Components =
{
new CuiRawImageComponent { Png = bradleyImageId, Sprite = "assets/content/textures/generic/fulltransparent.tga" },
new CuiRectTransformComponent { AnchorMin = "0.5788 0.217", AnchorMax = "0.6473 0.385" }
}
});
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.5788 0.25", AnchorMax = "0.6473 0.31" },
Text = { Text = Msg("MB_Bradley", player.userID.ToString()), Color = "1 1 1 0.5", Align = TextAnchor.UpperCenter, FontSize = 9, Font = "robotocondensed-regular.ttf" }
}, centerPanel);
}
int hour = Mathf.FloorToInt(TOD_Sky.Instance.Cycle.Hour);
int minute = Mathf.FloorToInt((TOD_Sky.Instance.Cycle.Hour - hour) * 60);
string timeString = $"{hour:D2}:{minute:D2}";
// Заголовок (полупрозрачный)
container.Add(new CuiLabel
{
Text = { Text = Msg("MB_Time", player.UserIDString) + ":", FontSize = 12, Align = TextAnchor.MiddleRight, Color = "1 1 1 0.5" },
RectTransform = { AnchorMin = "0.81 0.59", AnchorMax = "0.9 0.623" }
}, centerPanel);
// Время (чисто белый)
container.Add(new CuiLabel
{
Text = { Text = timeString, FontSize = 12, Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.8" },
RectTransform = { AnchorMin = "0.904 0.59", AnchorMax = "0.935 0.623" }
}, centerPanel);
DateTime lastGlobalWipe = (DateTime)(MBCalendar?.Call("GetLastGlobalWipeDate") ?? DateTime.Now);
TimeSpan ago = DateTime.Now - lastGlobalWipe;
int days = ago.Days;
int hours = ago.Hours;
int minutes = ago.Minutes;
string agoText = Msg("MB_GlobalWipeAgo", player.UserIDString, days, hours, minutes);
string exactDate = $"{lastGlobalWipe:dd.MM.yyyy} {Msg("MB_At_1700", player.UserIDString)}";
// Текст: "Відбувся глобал вайп X дн Y год Z хв тому"
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.785 0.29", AnchorMax = "0.94 0.36" },
Text = { Text = agoText, FontSize = 15, Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.9", Font = "robotocondensed-regular.ttf" }
}, centerPanel);
// Точна дата: "23.05.2025 в 17:00"
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.785 0.26", AnchorMax = "0.94 0.285" },
Text = { Text = exactDate, FontSize = 11, Align = TextAnchor.MiddleLeft, Color = "1 1 1 0.6", Font = "robotocondensed-regular.ttf" }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.745 0.213", AnchorMax = "0.955 0.255" },
Text = { Text = Msg("MB_Calendar_Text", player.userID.ToString()), Color = "1 1 1 0.3", Align = TextAnchor.UpperCenter, FontSize = 9, Font = "robotocondensed-regular.ttf" }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.378 0.93", AnchorMax = "0.5 0.96" },
Text = {
Text = $"{player.displayName}",
FontSize = 11,
Align = TextAnchor.MiddleLeft,
Color = "1 1 1 0.4"
}
}, centerPanel);
double totalSeconds = playTime.TryGetValue(player.userID, out var savedTime) ? savedTime : 0;
if (sessionStart.TryGetValue(player.userID, out var joinTime))
totalSeconds += (DateTime.UtcNow - joinTime).TotalSeconds;
TimeSpan ts = TimeSpan.FromSeconds(totalSeconds);
string playedText = $"{(int)ts.TotalHours}h {ts.Minutes}m";
container.Add(new CuiLabel
{
Text = {
Text = Msg("MB_PlayedTime", player.UserIDString, playedText),
FontSize = 10,
Align = TextAnchor.MiddleLeft,
Color = "1 1 1 0.3"
},
RectTransform = { AnchorMin = "0.378 0.905", AnchorMax = "0.5 0.93" }
}, centerPanel);
// // Панель-фон
// container.Add(new CuiPanel
// {
// Image = { Color = "0.67 0.87 0.80 0.2" }, // Темно-сірий прозорий фон
// RectTransform = { AnchorMin = "0.378 0.905", AnchorMax = "0.5 0.93" }
// }, centerPanel);
container.Add(new CuiButton
{
Button = {
Command = "mbmainmenu.opencalendar",
Color = "0.2 0.6 0.3 0"
},
RectTransform = { AnchorMin = "0.745 0.213", AnchorMax = "0.955 0.385" }
}, centerPanel);
container.Add(new CuiButton
{
Button = {
Command = "mbmainmenu.openprivileges",
Color = "0.2 0.6 0.3 0"
},
RectTransform = { AnchorMin = "0.34 0.033", AnchorMax = "0.425 0.125" },
}, centerPanel);
container.Add(new CuiButton
{
Button = {
Command = "mbmainmenu.opencommands",
Color = "0.2 0.6 0.3 0"
},
RectTransform = { AnchorMin = "0.448 0.033", AnchorMax = "0.535 0.125" },
}, centerPanel);
container.Add(new CuiButton
{
Button = {
Command = "mbmainmenu.opencraft",
Color = "0.2 0.6 0.3 0"
},
RectTransform = { AnchorMin = "0.558 0.033", AnchorMax = "0.645 0.125" },
}, centerPanel);
container.Add(new CuiButton
{
Button = {
Command = "mbmainmenu.opensite",
Color = "0.2 0.6 0.3 0"
},
RectTransform = { AnchorMin = "0.548 0.915", AnchorMax = "0.647 0.955" },
}, centerPanel);
container.Add(new CuiButton
{
Button = {
Command = "mbmainmenu.opendiscord",
Color = "0.2 0.6 0.3 0"
},
RectTransform = { AnchorMin = "0.826 0.91", AnchorMax = "0.86 0.956" },
}, centerPanel);
container.Add(new CuiButton
{
Button = {
Command = "mbmainmenu.opentiktok",
Color = "0.2 0.6 0.3 0"
},
RectTransform = { AnchorMin = "0.87 0.91", AnchorMax = "0.9 0.956" },
}, centerPanel);
// container.Add(new CuiButton
// {
// Button = {
// Command = "mbmainmenu.openplument",
// Color = "0.2 0.6 0.3 0"
// },
// RectTransform = { AnchorMin = "0.673 0.89", AnchorMax = "0.805 0.973" },
// }, centerPanel);
// // Панель-фон
// container.Add(new CuiPanel
// {
// Image = { Color = "0.67 0.87 0.80 0.2" }, // Темно-сірий прозорий фон
// RectTransform = { AnchorMin = "0.673 0.89", AnchorMax = "0.805 0.973" }
// }, centerPanel);
CuiHelper.AddUi(player, container);
}
#endregion
#region WebsiteMenu
private void ShowWebsiteMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "MBWebsite_UI");
var container = new CuiElementContainer();
string root = container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
CursorEnabled = true
}, "Overlay", "MBWebsite_UI");
string backgroundPanel = container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0.5", Material = "assets/content/ui/uibackgroundblur.mat" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
CursorEnabled = true
}, root);
string imageId = imageUI?.GetImage("MBWebsite_Banner");
if (!string.IsNullOrEmpty(imageId))
{
container.Add(new CuiElement
{
Name = CuiHelper.GetGuid(),
Parent = root,
Components =
{
new CuiRawImageComponent { Png = imageId },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-125 -200", OffsetMax = "125 200" }
}
});
}
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Close = "MBWebsite_UI" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "", FontSize = 0 }
}, root);
string centerPanel = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0" },
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-125 -200", OffsetMax = "125 210"
},
CursorEnabled = true
}, root);
// Назва сайта
container.Add(new CuiElement
{
Parent = centerPanel,
Components =
{
new CuiInputFieldComponent { Text = configData.WebsiteServer, Color = "1 1 1 0.8", Align = TextAnchor.MiddleCenter, FontSize = 13},
new CuiRectTransformComponent { AnchorMin = "0.165 0.15", AnchorMax = "0.831 0.21" }
}
});
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.165 0.04", AnchorMax = "0.831 0.12" },
Text = { Text = Msg("MB_CTRL+C", player.userID.ToString()), Color = "1 1 1 0.4", Align = TextAnchor.MiddleCenter, FontSize = 12 }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.31 0.255", AnchorMax = "0.685 0.31" },
Text = { Text = Msg("MB_Select_text", player.userID.ToString()), Color = "0.00 1.00 0.00 1.00", Align = TextAnchor.MiddleCenter, FontSize = 12 }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.165 0.315", AnchorMax = "0.831 0.425" },
Text = { Text = Msg("MB_Scan_QR", player.userID.ToString()), Color = "1 1 1 0.4", Align = TextAnchor.MiddleCenter, FontSize = 12 }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.165 0.87", AnchorMax = "0.831 0.94" },
Text = { Text = Msg("MB_Website", player.userID.ToString()), Color = "1 1 1 0.8", Align = TextAnchor.MiddleCenter, FontSize = 20 }
}, centerPanel);
// container.Add(new CuiElement
// {
// Parent = centerPanel,
// Components =
// {
// new CuiRawImageComponent
// {
// Url = configData.QrWebsiteUrl,
// Sprite = "assets/content/textures/generic/fulltransparent.tga",
// FadeIn = 1f
// },
// new CuiRectTransformComponent
// {
// AnchorMin = "0.21 0.465", AnchorMax = "0.785 0.811"
// }
// }
// });
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Close = "MBWebsite_UI" },
RectTransform = { AnchorMin = "0.925 0.93", AnchorMax = "0.98 0.965" },
Text = { Text = "", FontSize = 0 }
}, centerPanel);
// // Панель-фон
// container.Add(new CuiPanel
// {
// Image = { Color = "0.67 0.87 0.80 0.3" }, // Темно-сірий прозорий фон
// RectTransform = { AnchorMin = "0.925 0.93", AnchorMax = "0.98 0.965" }
// }, centerPanel);
CuiHelper.AddUi(player, container);
}
#endregion
#region DiscordMenu
private void ShowDiscordMenu(BasePlayer player)
{
CuiHelper.DestroyUi(player, "MBDiscord_UI");
var container = new CuiElementContainer();
string root = container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
CursorEnabled = true
}, "Overlay", "MBDiscord_UI");
string backgroundPanel = container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0.5", Material = "assets/content/ui/uibackgroundblur.mat" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
CursorEnabled = true
}, root);
string imageId = imageUI?.GetImage("MBDiscord_Banner");
if (!string.IsNullOrEmpty(imageId))
{
container.Add(new CuiElement
{
Name = CuiHelper.GetGuid(),
Parent = root,
Components =
{
new CuiRawImageComponent { Png = imageId },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-125 -200", OffsetMax = "125 200" }
}
});
}
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Close = "MBDiscord_UI" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "", FontSize = 0 }
}, root);
string centerPanel = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0" },
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-125 -200", OffsetMax = "125 210"
},
CursorEnabled = true
}, root);
// Назва сайта
container.Add(new CuiElement
{
Parent = centerPanel,
Components =
{
new CuiInputFieldComponent { Text = configData.DiscordServer, Color = "1 1 1 0.8", Align = TextAnchor.MiddleCenter, FontSize = 13},
new CuiRectTransformComponent { AnchorMin = "0.165 0.15", AnchorMax = "0.831 0.21" }
}
});
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.165 0.04", AnchorMax = "0.831 0.12" },
Text = { Text = Msg("MB_CTRL+C", player.userID.ToString()), Color = "1 1 1 0.4", Align = TextAnchor.MiddleCenter, FontSize = 12 }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.31 0.255", AnchorMax = "0.685 0.31" },
Text = { Text = Msg("MB_Select_text", player.userID.ToString()), Color = "0.00 1.00 0.00 1.00", Align = TextAnchor.MiddleCenter, FontSize = 12 }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.165 0.315", AnchorMax = "0.831 0.425" },
Text = { Text = Msg("MB_Scan_QR", player.userID.ToString()), Color = "1 1 1 0.4", Align = TextAnchor.MiddleCenter, FontSize = 12 }
}, centerPanel);
container.Add(new CuiLabel
{
RectTransform = { AnchorMin = "0.165 0.87", AnchorMax = "0.831 0.94" },
Text = { Text = Msg("MB_Discord", player.userID.ToString()), Color = "1 1 1 0.8", Align = TextAnchor.MiddleCenter, FontSize = 20 }
}, centerPanel);
// container.Add(new CuiElement
// {
// Parent = centerPanel,
// Components =
// {
// new CuiRawImageComponent
// {
// Url = configData.QrDiscordUrl,
// ... [Code preview truncated due to length. Full source in attached file] ...