C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using UnityEngine;
using Oxide.Core.Plugins;
namespace Oxide.Plugins
{
[Info("RTeleportMenu", "King", "1.0.1")]
public class RTeleportMenu : RustPlugin
{
#region [Vars]
[PluginReference] Plugin Clans, NTeleportation, Teleportation, ImageLibrary;
public string Layer = "RTeleportMenu.Layer";
private class ButtonsSettings
{
public string Text;
public string Image;
public string Command;
}
#endregion
#region [Data]
private void LoadData()
{
try
{
data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>("BTeleportMenu");
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (data == null) data = new PluginData();
}
private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject("BTeleportMenu", data);
private class PluginData
{
public Dictionary<ulong, PlayerData> PlayerData = new Dictionary<ulong, PlayerData>();
}
private static PluginData data;
private class PlayerData
{
public bool AutoAccept;
public static PlayerData GetOrAdd(BasePlayer player)
{
return GetOrAdd(player.userID);
}
public static PlayerData GetOrAdd(ulong userId)
{
if (!data.PlayerData.ContainsKey(userId))
data.PlayerData.Add(userId, new PlayerData
{
AutoAccept = true,
});
return data.PlayerData[userId];
}
}
#endregion
#region [Oxide]
private void OnServerInitialized()
{
cmd.AddChatCommand("tpmenu", this, "TeleportUi");
cmd.AddChatCommand("atp", this, "cmdAutoTeleport");
LoadData();
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974267645567046/WBqhQDb.png", "ImageOutpost");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974320665767946/RaT20qi.png", "ImageHome");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974379293745172/fOmlHY5.png", "ImageFriend");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974438978703360/vwxoVtp.png", "ImageCancel");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974496147046430/6uhdOoc.png", "ImageAccept");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974550547169340/MGox6V7.png", "ImageSave");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974598169317376/rPVAdeB.png", "ImageLine");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974654180048966/vU7Zus6.png", "ImageOn");
ImageLibrary?.Call("AddImage", "https://cdn.discordapp.com/attachments/1047082847116210237/1116974707854544956/ahSnWLO.png", "ImageOff");
}
private void Unload()
{
foreach (BasePlayer player in BasePlayer.activePlayerList)
CuiHelper.DestroyUi(player, Layer);
SaveData();
data = null;
}
#endregion
#region [AutoTeleport]
private void CheckTeleport(BasePlayer receiver, BasePlayer caller)
{
var data = PlayerData.GetOrAdd(receiver);
if(data.AutoAccept)
{
if (IsClanMember(caller.userID, receiver.userID))
{
receiver.SendConsoleCommand("chat.say /tpa");
return;
}
}
}
private void OnTeleportRequested(BasePlayer receiver, BasePlayer caller) => CheckTeleport(receiver, caller);
private void cmdAutoTeleport(BasePlayer player)
{
var data = PlayerData.GetOrAdd(player);
if (data.AutoAccept)
{
data.AutoAccept = false;
player.ChatMessage($"Вы включили автоматическое <color=#AAFF81FF>/tpa</color>");
}
else
{
data.AutoAccept = true;
player.ChatMessage($"Вы отключили автоматическое <color=#AAFF81FF>/tpa</color>");
}
return;
}
#endregion
#region [MainUi]
private void TeleportUi(BasePlayer player)
{
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiPanel
{
CursorEnabled = true,
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Image = { Material = "assets/content/ui/uibackgroundblur.mat", Color = "0 0 0 0.77" }
}, "Overlay", Layer);
CuiHelper.DestroyUi(player, Layer);
CuiHelper.AddUi(player, container);
TeleportUiMain(player);
}
private void TeleportUiMain(BasePlayer player)
{
CuiElementContainer container = new CuiElementContainer();
List<ButtonsSettings> buttons = new List<ButtonsSettings>();
var data = PlayerData.GetOrAdd(player);
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Button = { Close = Layer, Color = "0 0 0 0"},
Text = { Text = "" }
}, Layer, Layer + ".Main");
#region [2Buttons]
var setHome = GetGridString(player.transform.position);
container.Add(new CuiElement
{
Parent = Layer + ".Main",
Name = Layer + ".Main" + ".CancelButton",
Components =
{
new CuiRawImageComponent { Png = (string)ImageLibrary?.Call("GetImage", "ImageCancel"), Color = "1 1 1 1"},
new CuiRectTransformComponent { AnchorMin = $"0.5 0.5", AnchorMax = $"0.5 0.5", OffsetMin = $"-96 -27.5", OffsetMax = $"-45 -0.5" },
}
});
container.Add(new CuiElement
{
Parent = Layer + ".Main" + ".CancelButton",
Components =
{
new CuiTextComponent { Text = "Отклонить", Color = "1 1 1 1", FontSize = 9, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf" },
new CuiRectTransformComponent { AnchorMin = "0 0.3", AnchorMax = "1 1" },
new CuiOutlineComponent{Color = "0 0 0 1", Distance = "0.15 0.15"},
}
});
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Command = $"chat.say /tpc" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "" }
}, Layer + ".Main" + ".CancelButton");
container.Add(new CuiElement
{
Parent = Layer + ".Main",
Name = Layer + ".Main" + ".AcceptButton",
Components =
{
new CuiRawImageComponent { Png = (string)ImageLibrary?.Call("GetImage", "ImageAccept"), Color = "1 1 1 1"},
new CuiRectTransformComponent { AnchorMin = $"0.5 0.5", AnchorMax = $"0.5 0.5", OffsetMin = $"-26.5 -30.5", OffsetMax = $"26.5 -1.5" },
}
});
container.Add(new CuiElement
{
Parent = Layer + ".Main" + ".AcceptButton",
Components =
{
new CuiTextComponent { Text = "Принять", Color = "1 1 1 1", FontSize = 9, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf" },
new CuiRectTransformComponent { AnchorMin = "0 0.35", AnchorMax = "1 1" },
new CuiOutlineComponent{Color = "0 0 0 1", Distance = "0.15 0.15"},
}
});
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Command = $"chat.say /tpa" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "" }
}, Layer + ".Main" + ".AcceptButton");
container.Add(new CuiElement
{
Parent = Layer + ".Main",
Name = Layer + ".Main" + ".SaveButton",
Components =
{
new CuiRawImageComponent { Png = (string)ImageLibrary?.Call("GetImage", "ImageSave"), Color = "1 1 1 1"},
new CuiRectTransformComponent { AnchorMin = $"0.5 0.5", AnchorMax = $"0.5 0.5", OffsetMin = $"42 -29.5", OffsetMax = $"96.5 -0.5" },
}
});
container.Add(new CuiElement
{
Parent = Layer + ".Main" + ".SaveButton",
Components =
{
new CuiTextComponent { Text = "Сохранить", Color = "1 1 1 1", FontSize = 9, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf" },
new CuiRectTransformComponent { AnchorMin = "0 0.3", AnchorMax = "1 1" },
new CuiOutlineComponent{Color = "0 0 0 1", Distance = "0.15 0.15"},
}
});
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Command = $"RTeleport_UI /sethome {setHome}", Close = Layer },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "" }
}, Layer + ".Main" + ".SaveButton");
#endregion
#region [AutoTeleportUi]
container.Add(new CuiElement
{
Parent = Layer + ".Main",
Name = Layer + ".Main" + ".ImageLine",
Components =
{
new CuiRawImageComponent { Png = (string)ImageLibrary?.Call("GetImage", "ImageLine"), Color = "1 1 1 1"},
new CuiRectTransformComponent { AnchorMin = $"0.5 0.5", AnchorMax = $"0.5 0.5", OffsetMin = $"-96 -57.5", OffsetMax = $"43.5 -39.5" },
}
});
container.Add(new CuiElement
{
Parent = Layer + ".Main" + ".ImageLine",
Components =
{
new CuiTextComponent { Text = "Автопринятие телепортации:", Color = "1 1 1 1", FontSize = 9, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf" },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" },
new CuiOutlineComponent{Color = "0 0 0 1", Distance = "0.15 0.15"},
}
});
container.Add(new CuiElement
{
Parent = Layer + ".Main",
Name = Layer + ".Main" + ".ImageTeleport",
Components =
{
new CuiRawImageComponent { Png = data.AutoAccept == true ? (string)ImageLibrary?.Call("GetImage", "ImageOff") : (string)ImageLibrary?.Call("GetImage", "ImageOn"), Color = "1 1 1 0.44"},
new CuiRectTransformComponent { AnchorMin = $"0.5 0.5", AnchorMax = $"0.5 0.5", OffsetMin = $"49.5 -57.5", OffsetMax = $"96 -39.5" },
}
});
container.Add(new CuiElement
{
Parent = Layer + ".Main" + ".ImageTeleport",
Components =
{
new CuiTextComponent { Text = data.AutoAccept == true ? "Выкл" : "Вкл", Color = "1 1 1 1", FontSize = 9, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf" },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 0.95" },
new CuiOutlineComponent{Color = "0 0 0 1", Distance = "0.15 0.15"},
}
});
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Command = $"chat.say /atp", Close = Layer },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "" }
}, Layer + ".Main" + ".ImageTeleport");
#endregion
#region [MainButtons]
buttons.Add(new ButtonsSettings
{
Text = $"ГОРОД",
Image = $"ImageOutpost",
Command = $"chat.say /outpost",
});
var homeName = GetHomes(player);
if (homeName.ContainsKey(setHome))
{
var count = homeName.Where(p => p.Key.Contains(setHome)).Count();
setHome = setHome + $"({count})";
}
if (homeName != null && homeName.Count > 0)
{
foreach (var check in homeName)
{
buttons.Add(new ButtonsSettings
{
Text = $"{check.Key}",
Image = $"ImageHome",
Command = $"RTeleport_UI /home {check.Key}",
});
}
}
string clanTag = GetClan(player.userID);
if (!string.IsNullOrEmpty(clanTag))
{
var clanMembers = GetClanMembers(player.userID);
if (clanMembers != null && clanMembers.Count > 0)
{
foreach(var check in clanMembers)
{
var clanMember = covalence.Players.FindPlayerById(check.ToString());
if (clanMember == null) continue;
buttons.Add(new ButtonsSettings
{
Text = $"{clanMember.Name}",
Image = $"ImageFriend",
Command = $"RTeleport_UI /tpr {clanMember.Id}",
});
}
}
}
var page = buttons.Count;
var width = 48.5;
var margin = 8.5f;
var switchs = - (width * page + (page - 1) * margin) / 2f;
foreach (var check in buttons.Select((i, t) => new {A = i, B = t}))
{
container.Add(new CuiElement
{
Parent = Layer + ".Main",
Name = Layer + ".Main" + $".Buttons{check.B}",
Components =
{
new CuiRawImageComponent { Png = (string)ImageLibrary?.Call("GetImage", check.A.Image), Color = "1 1 1 1"},
new CuiRectTransformComponent { AnchorMin = $"0.5 0.5", AnchorMax = $"0.5 0.5", OffsetMin = $"{switchs} 10", OffsetMax = $"{switchs + width} 66.5" }
}
});
container.Add(new CuiElement
{
Parent = Layer + ".Main" + $".Buttons{check.B}",
Components =
{
new CuiTextComponent { Text = check.A.Text, Color = "1 1 1 1", FontSize = 11, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf" },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 0.9" },
new CuiOutlineComponent{Color = "0 0 0 1", Distance = "0.15 0.15"},
}
});
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Button = { Command = check.A.Command, Color = "0 0 0 0"},
Text = { Text = "" }
}, Layer + ".Main" + $".Buttons{check.B}");
if (check.A.Image == "ImageHome")
{
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Command = $"RTeleport_UI /removehome {check.A.Text}", Close = Layer },
RectTransform = { AnchorMin = "0.85 0.85", AnchorMax = "0.85 0.85", OffsetMin = "-12.5 -9", OffsetMax = "4.5 7" },
Text = { Text = "" }
}, Layer + ".Main" + $".Buttons{check.B}");
}
switchs += width + margin;
}
#endregion
CuiHelper.DestroyUi(player, Layer + ".Main");
CuiHelper.AddUi(player, container);
}
#endregion
#region [Func]
[ConsoleCommand("RTeleport_UI")]
private void cmdSendCommand(ConsoleSystem.Arg args)
{
var player = args.Player();
if (player == null) return;
if (args.FullString.Contains("/"))
player.Command("chat.say", args.FullString);
else
player.Command(args.FullString);
}
private string GetGridString(Vector3 position)
{
Vector2 adjPosition = new Vector2((World.Size / 2) + position.x, (World.Size / 2) - position.z);
return $"{NumberToString((int)(adjPosition.x / 150))}{(int)(adjPosition.y / 150)}";
}
private string NumberToString(int number)
{
bool a = number > 26;
Char c = (Char)(65 + (a ? number - 26 : number));
return a ? "A" + c : c.ToString();
}
Dictionary<string, Vector3> GetHomes(BasePlayer player)
{
var a1 = (Dictionary<string, Vector3>)NTeleportation?.Call("API_GetHomes", player) ?? new Dictionary<string, Vector3>();
var a2 = (Dictionary<string, Vector3>)Teleportation?.Call("GetHomes", player.userID) ?? new Dictionary<string, Vector3>();
return a1.Concat(a2).GroupBy(p => p.Key).ToDictionary(p => p.Key, p => p.First().Value);
}
private string GetClan(ulong userID) => Clans?.Call<string>("GetClanOf", userID);
bool IsClanMember(ulong playerid = 1, ulong targetID = 0) => (bool)(Clans?.Call("HasFriend", playerid, targetID) ?? false);
private List<string> GetClanMembers(ulong playerid)
{
if (Clans)
{
var clan = Clans?.Call("RTeleportMenuHook", playerid) as List<string>;
return clan.ToList();
}
return new List<string>();
}
#endregion
}
}