C#:
using System;
using Oxide.Game.Rust.Cui;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
using CompanionServer;
using Oxide.Ext.Discord;
using Oxide.Ext.Discord.Attributes;
using Oxide.Ext.Discord.Entities.Activities;
using Oxide.Ext.Discord.Entities.Messages;
using Oxide.Ext.Discord.Entities.Channels;
using Oxide.Ext.Discord.Entities.Guilds;
using Oxide.Ext.Discord.Entities.Gatway;
using Oxide.Ext.Discord.Entities.Gatway.Events;
using Oxide.Ext.Discord.Entities.Messages.Embeds;
using Oxide.Ext.Discord.Entities.Permissions;
using Oxide.Ext.Discord.Entities;
using Oxide.Ext.Discord.Entities.Gatway.Commands;
using System.Text.RegularExpressions;
using Oxide.Ext.Discord.Builders.MessageComponents;
using Oxide.Ext.Discord.Entities.Interactions.MessageComponents;
using Oxide.Ext.Discord.Entities.Interactions;
using Oxide.Ext.Discord.Entities.Users;
using Oxide.Core.Libraries.Covalence;
using ru = Oxide.Game.Rust;
using ConVar;
namespace Oxide.Plugins {
[Info("NOTIFI BOT (DS and TG)", "WOLF#4002", "1.01.0")]
class WBot : RustPlugin {
void OnPlayerConnected(BasePlayer player) {
if (!DB.ContainsKey(player.userID)) {
PlayerInfo NewUser = new PlayerInfo() {
DisplayName = player.displayName, SteamID = player.userID, telegram = null, discord = 0,
}
;
DB.Add(player.userID, NewUser);
OnServerSave();
}
var User = DB[player.userID];
OnServerSave();
}
void OnServerSave() {
Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject($"{Name}/{Title}", DB);
}
private Dictionary<ulong, PlayerInfo> DB = new Dictionary<ulong, PlayerInfo>();
private class PlayerInfo {
public string DisplayName;
public ulong SteamID;
public string telegram;
public ulong discord;
}
class DISCORD {
[JsonProperty("Enable? |||| Включить?")]
public bool enable;
[JsonProperty("Cooldown for sending |||| Кд на отправку")]
public float cooldown;
[JsonProperty("Token (https://discordapp.com/developers/applications) |||| Токен бота (https://discordapp.com/developers/applications)")]
public string token;
[JsonProperty("Channel ID, where the player will take the code to confirm the profile |||| ID канала, гле игрок будет брать код, для подтверджения профиля")]
public string channel;
[JsonProperty("Info text |||| Дискорд канал с получением кода - текст")]
public string channeltext;
[JsonProperty("Info text - line color on the left |||| Дискорд канал с получением кода - цвет линии слева (https://gist.github.com/thomasbnt/b6f455e2c7d743b796917fa3c205f812#file-code_colors_discordjs-md)")]
public uint channelcolor;
[JsonProperty("Text on button |||| Дискорд канал с получением кода - кнопка")]
public string channelbutton;
[JsonProperty("Reply after button click |||| Дискорд канал с получением кода - ответ")]
public string channelex;
[JsonProperty("Don't touch this field |||| Дискорд канал с получением кода - ID сообщения (не трогаем! сам заполнится!)")]
public string channelmessageid;
}
class TELEGRAM {
[JsonProperty("Enable? |||| Включить?")]
public bool enable;
[JsonProperty("Cooldown for sending |||| Кд на отправку")]
public float cooldown;
[JsonProperty("Bot tag |||| Тэг бота")]
public string bottag;
[JsonProperty("Token |||| Токен")]
public string token;
}
private class Configuration {
[JsonProperty("Discord |||| Оповещание в дискорд")]
public DISCORD discord;
[JsonProperty("Telegram |||| Оповещание в телеграм")]
public TELEGRAM telegram;
public static Configuration Generate() {
return new Configuration {
discord = new DISCORD {
cooldown = 6f, enable = true, token = "MTA2OTI3Njk2MTIxOTgxMzQwNg.GzeFQ9.AJtEEtJr4VUhztcdA_EFQJy4boq8c_4IScZU3g", channel = "1044272341980565594", channelbutton = "Get code \n|||| \nПолучить код", channelex = "\nYour code: {code} \n|||| \nВаш код: {code}", channelmessageid = "", channeltext = "Enter the received code in the integration menu for raid alerts.\nChat command /raid\nEnter it in the game itself, not in the discord! \n|||| \nВведите полученый код в меню интеграции дискорда с игровым профилем.\nЧат команда /raid\nВводить в самой игре, а не в дискорде!", channelcolor = 15277667
}
, telegram = new TELEGRAM {
token = "", cooldown = 6f, enable = true, bottag = "@WOLF_bot"
}
,
}
;
}
}
private static Configuration Settings;
protected override void LoadConfig() {
base.LoadConfig();
try {
Settings = Config.ReadObject<Configuration>();
Puts("Config Load");
}
catch {
PrintWarning($"Error reading config, creating one new config!");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig() => Settings = Configuration.Generate();
protected override void SaveConfig() => Config.WriteObject(Settings);
private void Unload() {
CloseClient();
}
private void OnServerInitialized() {
LoadData();
On();
}
void LoadData() {
SaveConfig();
if (!string.IsNullOrEmpty(Settings.discord.token)) CreateClient();
else Debug.LogError("WBOT - TOKEN FOR DISCORD BOT IS NULL!\nWBOT - Не указан токен для Discord бота!");
Debug.Log(">>WBOT<< OK!");
}
#region DISCORD
private string RANDOMNUM() => UnityEngine.Random.Range(1000, 99999).ToString();
private Dictionary<ulong, string> DISCORDCODES = new Dictionary<ulong, string>();
private readonly DiscordSettings _discordSettings = new DiscordSettings();
private DiscordGuild _guild;
[DiscordClient]
DiscordClient Client;
private void CreateClient() {
_discordSettings.ApiToken = Settings.discord.token;
_discordSettings.Intents = GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.Guilds | GatewayIntents.GuildMembers;
_discordSettings.LogLevel = Ext.Discord.Logging.DiscordLogLevel.Error;
Client.Connect(_discordSettings);
timer.Once(5f, () => {
if (Client == null) {
CreateClient();
Debug.Log("Discord reconnecting in 5 sec...");
}
else {
DiscordChannel channel;
if (!_guild.Channels.TryGetValue(new Snowflake(Settings.discord.channel), out channel)) {
Debug.Log("CHANNEL NOT FOUND! ({_guild.Channels.Count}).\nКАНАЛ НЕ СУЩЕСТВУЕТ! ({_guild.Channels.Count})");
return;
}
var embeds = new List<DiscordEmbed> {
new DiscordEmbed {
Color = new DiscordColor(Settings.discord.channelcolor), Description = Settings.discord.channeltext
}
}
;
var components = CreateComponents(Settings.discord.channelbutton);
if (!string.IsNullOrEmpty(Settings.discord.channelmessageid)) {
channel.GetChannelMessage(Client, new Snowflake(Settings.discord.channelmessageid), message => {
message.Embeds = embeds;
message.Components.Clear();
message.Components = components;
message.EditMessage(Client);
}
, error => {
if (error.HttpStatusCode == 404) {
Debug.Log("all ok");
channel?.CreateMessage(Client, new MessageCreate {
Embeds = embeds, Components = components
}
, message => {
Settings.discord.channelmessageid = message.Id;
SaveConfig();
}
);
}
}
);
}
else {
channel?.CreateMessage(Client, new MessageCreate {
Embeds = embeds, Components = components
}
, message => {
Settings.discord.channelmessageid = message.Id;
SaveConfig();
}
);
}
}
}
);
}
private void OnDiscordInteractionCreated(DiscordInteraction interaction) {
if (interaction.Type != InteractionType.MessageComponent) {
return;
}
if (!interaction.Data.ComponentType.HasValue || interaction.Data.ComponentType.Value != MessageComponentType.Button || interaction.Data.CustomId != $"{Name}_{ConVar.Server.ip}_{ConVar.Server.port}") {
return;
}
DiscordUser user = interaction.User ?? interaction.Member?.User;
HandleAcceptLinkButton(interaction, user);
}
private void HandleAcceptLinkButton(DiscordInteraction interaction, DiscordUser user) {
string num;
if (!DISCORDCODES.TryGetValue(user.Id.Id, out num)) {
num = DISCORDCODES[user.Id.Id] = RANDOMNUM();
}
string linkMessage = Formatter.ToPlaintext(Settings.discord.channelex.Replace("{code}", num));
interaction.CreateInteractionResponse(Client, new InteractionResponse {
Type = InteractionResponseType.ChannelMessageWithSource, Data = new InteractionCallbackData {
Content = linkMessage, Flags = MessageFlags.Ephemeral
}
}
);
}
private void OnDiscordGatewayReady(GatewayReadyEvent ready) {
_guild = ready.Guilds.FirstOrDefault().Value;
Debug.Log($"DISCORD BOT CONNECTED TO ID{_guild.Id}.\nDISCORD БОТ АВТОРИЗОВАН НА СЕРВЕРЕ ID{_guild.Id}.");
}
private void CloseClient() {
if (Client != null) Client.Disconnect();
}
private void CREATECHANNEL(string dsid, string text) {
Snowflake ss = new Snowflake(dsid);
if (!_guild.Members.Any(x => x.Value.User.Id == ss)) return;
_guild.Members.First(x => x.Value.User.Id == ss).Value.User.SendDirectMessage(Client, new MessageCreate {
Content = text
}
);
}
private void SENDMESSAGE(string dsid, string text) {
DiscordChannel channel = _guild.GetChannel(dsid);
if (channel != null) {
channel?.CreateMessage(Client, text);
}
else {
CREATECHANNEL(dsid, text);
}
}
public List<ActionRowComponent> CreateComponents(string button) {
MessageComponentBuilder builder = new MessageComponentBuilder();
builder.AddActionButton(ButtonStyle.Success, button, $"{Name}_{ConVar.Server.ip}_{ConVar.Server.port}", false);
return builder.Build();
}
private readonly List<Regex> _regexTags = new List<Regex> {
new Regex("<color=.+?>", RegexOptions.Compiled), new Regex("<size=.+?>", RegexOptions.Compiled)
}
;
private readonly List<string> _tags = new List<string> {
"</color>", "`", "</size>", "<i>", "</i>", "<b>", "</b>"
}
;
private string STRIP(string original) {
if (string.IsNullOrEmpty(original)) {
return string.Empty;
}
foreach (string tag in _tags) {
original = original.Replace(tag, "");
}
foreach (Regex regexTag in _regexTags) {
original = regexTag.Replace(original, "");
}
return original;
}
private DiscordChannel GetChannel(string id) {
return _guild.Channels.FirstOrDefault(x => x.Key.ToString() == id).Value;
}
#endregion
#region API TELEGRAM
private void GetRequestTelegram(string reciverID, string msg, BasePlayer player = null, bool accept = false) => webrequest.Enqueue($"https://api.telegram.org/bot" + Settings.telegram.token + "/sendMessage?chat_id=" + reciverID + "&text=" + Uri.EscapeDataString(msg), null, (code2, response2) => ServerMgr.Instance.StartCoroutine(GetCallbackTelegram(code2, response2, reciverID, player, accept)), this);
private IEnumerator GetCallbackTelegram(int code, string response, string id, BasePlayer player = null, bool accept = false) {
if (player == null || response == null) yield break;
if (code == 401) {
Debug.LogError("[WBOT] Telegram token not valid!");
}
else if (code == 200) {
if (!response.Contains("error_code")) {
ALERT aLERT;
if (alerts.TryGetValue(player.userID, out aLERT)) {
aLERT.telegramcooldown = DateTime.Now.AddMinutes(1);
}
else {
alerts.Add(player.userID, new ALERT {
telegramcodecooldown = DateTime.Now.AddMinutes(1)
}
);
}
var storage = DB[player.userID];
storage.telegram = id;
OnServerSave();
//write[player.userID] = "";
// OpenMenu(player, false);
}
}
else {
//SendError(player, "telegramuseridnotfound");
}
yield break;
}
#endregion
class ALERT {
public DateTime discordcooldown;
public DateTime telegramcooldown;
public DateTime telegramcodecooldown;
}
private static Dictionary<ulong, ALERT> alerts = new Dictionary<ulong, ALERT>();
List<ulong> block = new List<ulong>();
void BotAlert(ulong ID, string text) {
string IDstring = ID.ToString();
ALERT alert;
if (!alerts.TryGetValue(ID, out alert)) {
alerts.Add(ID, new ALERT());
alert = alerts[ID];
}
var storage = DB[ID];
#region ОПОВЕЩЕНИЕ В DISCORD
if (Settings.discord.enable && !block.Contains(ID) && !string.IsNullOrEmpty(Settings.discord.token) && alert.discordcooldown < DateTime.Now) {
if (storage.discord != 0UL) {
Snowflake ss = new Snowflake(storage.discord);
if (!_guild.Members.Any(x => x.Value.User.Id == ss)) return;
_guild.Members.First(x => x.Value.User.Id == ss).Value.User.SendDirectMessage(Client, new MessageCreate {
Content = $"@\n{text}"
}
, error : err => {
if (err.DiscordError.Code == 50007) {
block.Add(ID);
}
}
);
alert.discordcooldown = DateTime.Now.AddSeconds(Settings.discord.cooldown);
}
}
#endregion
#region ОПОВЕЩЕНИЕ В ТЕЛЕГРАМ
if (Settings.telegram.enable && !string.IsNullOrEmpty(Settings.telegram.token) && alert.telegramcooldown < DateTime.Now) {
if (!string.IsNullOrEmpty(storage.telegram)) {
GetRequestTelegram(storage.telegram, text);
alert.telegramcooldown = DateTime.Now.AddSeconds(Settings.telegram.cooldown);
}
}
#endregion
}
[ChatCommand("test")]
void TEST(BasePlayer player) {
BotAlert(player.userID, "zalupa");
}
[ChatCommand("raid")]
void RD(BasePlayer player) {
player.SendConsoleCommand("chat.say /menu");
player.SendConsoleCommand("menu choose 6");
player.SendConsoleCommand("chat.say /notifi");
}
[ChatCommand("notifi")]
void comdc(BasePlayer player, string command, string[] args) {
if (player == null) return;
if (args.Length == 0) {
OpenRaid(player);
return;
}
/*switch (args[0].ToLower())
{
case "ds":
Puts("work");
if (args.Length < 2)
SendReply(player, "Help Add");
else
DC(player, args[1].ToLower());
Puts(args[1].ToLower());
return;
case "tg":
return;
}*/
}
[ConsoleCommand("DIS")]
void cmdN(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null || arg.Args.Length == 0) return;
var code = arg.Args[0];
DC(player, code);
}
void DC(BasePlayer player, string text) {
ulong user = DISCORDCODES.FirstOrDefault(x => x.Value == text).Key;
if (user == 0) {
WNot?.Call("Notifi", player, $"{Title}", $"ERROR CODE\n[ {text} ]");
return;
}
var storage = DB[player.userID];
storage.discord = user;
OnServerSave();
DISCORDCODES.Remove(user);
Puts($"{user} {text}");
BotAlert(player.userID, $"WELCOM TO {ConVar.Server.hostname}\nconnect {ConVar.Server.ip}:{ConVar.Server.port}");
OpenRaid(player);
}
[PluginReference]
Plugin ImageLibrary, WNot;
void On() {
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Name}/{Title}")) DB = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerInfo>>($"{Name}/{Title}");
foreach (BasePlayer player in BasePlayer.activePlayerList) {
OnPlayerConnected(player);
}
ImageLibrary.Call("AddImage", "https://rustplugins.top/api/image/menu/active.png", "p1");
ImageLibrary.Call("AddImage", "https://rustplugins.top/api/image/menu/not.png", "p2");
timer.Every(5, () => UpdateStatus());
}
private static string Raid = "UIRaid";
void OpenRaid(BasePlayer player) {
CuiHelper.DestroyUi(player, Raid);
var container = new CuiElementContainer();
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Image = {
Color = "0 0 0 0", //Material = "assets/content/ui/uibackgroundblur.mat"
}
, CursorEnabled = true
}
, "WOLFS", Raid);
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "0.48 1"
}
, Image = {
Color = "0 0 0 0", //Material = "assets/content/ui/uibackgroundblur.mat"
}
, CursorEnabled = true
}
, Raid, "DS");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.52 0", AnchorMax = "1 1"
}
, Image = {
Color = "0 0 0 0", //Material = "assets/content/ui/uibackgroundblur.mat"
}
, CursorEnabled = true
}
, Raid, "TG");
container.Add(new CuiElement {
Parent = "DS", Components = {
new CuiTextComponent {
Color = "0.86 0.77 0.67 1", Text = "DISCORD NOTIFI", Align = TextAnchor.MiddleCenter, FontSize = 30
}
, new CuiRectTransformComponent {
AnchorMin = "0 0.8", AnchorMax = "1 1"
}
, new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "1 1"
}
}
}
);
int num = 0;
var storage = DB[player.userID];
if (Settings.discord.enable && !string.IsNullOrEmpty(Settings.discord.token)) {
if (storage.discord == 0UL) {
container.Add(new CuiElement {
Parent = "DS", Name = "DSP", Components = {
new CuiRawImageComponent {
Png = (string) ImageLibrary.Call("GetImage", "p1")
}
, new CuiRectTransformComponent {
AnchorMin = "0.25 0.7", AnchorMax = "0.75 0.8"
}
,
}
}
);
container.Add(new CuiElement {
Parent = "DSP", Name = "DSP" + ".Input", Components = {
new CuiImageComponent {
Color = "0.16 0.34 0.49 0"
}
, new CuiRectTransformComponent {
AnchorMin = "0.12 0.14", AnchorMax = "0.92 0.86"
}
, // new CuiOutlineComponent{Distance = "5.5 5.5", Color = "0.5 1 1 1"}
}
}
);
container.Add(new CuiElement {
Parent = "DSP" + ".Input", Name = "DSP" + ".Input.Current", Components = {
new CuiInputFieldComponent {
FontSize = 16, Align = TextAnchor.MiddleCenter, Command = "DIS", Text = "CODE", Color = "1.00 0.53 0.53 0.5"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "1 1"
}
}
}
);
}
else {
container.Add(new CuiElement {
Parent = "DS", Name = "DSP", Components = {
new CuiRawImageComponent {
Png = (string) ImageLibrary.Call("GetImage", "p2")
}
, new CuiRectTransformComponent {
AnchorMin = "0.25 0.7", AnchorMax = "0.75 0.8"
}
,
}
}
);
container.Add(new CuiElement {
Parent = "DSP", Components = {
new CuiTextComponent {
Color = "0.00 1.00 0.25 0.2", Text = "CONNECTED", Align = TextAnchor.MiddleCenter, FontSize = 20
}
, new CuiRectTransformComponent {
AnchorMin = "0.12 0.14", AnchorMax = "0.92 0.86"
}
, new CuiOutlineComponent {
Color = "0 0 0 1", Distance = "1 1"
}
}
}
);
}
num++;
}
/*if (Settings.telegram.enable && !string.IsNullOrEmpty(Settings.telegram.token))
{
if (!string.IsNullOrEmpty(storage.telegram))
{
container.Add(new CuiElement
{
Parent = Raid,
Name = Raid + ".Inpu",
Components =
{
new CuiImageComponent { Color = "0.16 0.34 0.49 0.80"},
new CuiRectTransformComponent { AnchorMin = "0.2385417 0.4777631", AnchorMax = "0.7458333 0.521279" },
new CuiOutlineComponent{Distance = "5.5 5.5", Color = "0.5 1 1 0.5"}
}
});
container.Add(new CuiElement
{
Parent = Raid + ".Inpu",
Name = Raid + ".Input.Curren",
Components =
{
new CuiInputFieldComponent { FontSize = 16, Align = TextAnchor.MiddleCenter, Command = "tg", Text = "code", Color = "1 1 0 1"},
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" },
}
});
}
else
{
container.Add(new CuiElement
{
Parent = Raid,
Components =
{
new CuiTextComponent {Text = "CONNECTED", Align = TextAnchor.MiddleCenter, FontSize = 30},
new CuiRectTransformComponent { AnchorMin = "0 0.5", AnchorMax = "1 0.6" },
new CuiOutlineComponent { Color = "0 1 0 0.5", Distance = "2 2" }
}
});
}
num++;
}*/
CuiHelper.AddUi(player, container);
}
private int statusIndex = -1;
private void UpdateStatus() {
try {
var index = 1;
Client.Bot.UpdateStatus(new UpdatePresenceCommand {
Activities = new List<DiscordActivity> {
new DiscordActivity {
Name = $"Online {BasePlayer.activePlayerList.Count().ToString()} / {ConVar.Server.maxplayers.ToString()}", Type = ActivityType.Watching
}
}
}
);
statusIndex = index;
}
catch (Exception err) {
LogToFile(Name, $"{err}", this);
}
}
}
}