C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Ext.Discord.Builders;
using Oxide.Ext.Discord.Clients;
using Oxide.Ext.Discord.Connections;
using Oxide.Ext.Discord.Constants;
using Oxide.Ext.Discord.Entities;
using Oxide.Ext.Discord.Interfaces;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;
using Random = Oxide.Core.Random;
namespace Oxide.Plugins {
[Info("NSP", "15FPS", "0.0.1")]
[Description("Notification from the server to the player")]
public class NSP : RustPlugin, IDiscordPlugin {
private class DISCORD_CFG {
[JsonProperty("token")]
public string token;
[JsonProperty("server")]
public ulong server;
[JsonProperty("channel")]
public string channel;
[JsonProperty("channeltext")]
public string channeltext;
[JsonProperty("channelbutton")]
public string channelbutton;
[JsonProperty("channelcolor")]
public uint channelcolor;
[JsonProperty("channelmessageid")]
public string channelmessageid;
}
private class ConfigRoot {
[JsonProperty("discord")]
public DISCORD_CFG discord;
public static ConfigRoot Default() {
return new ConfigRoot {
discord = new DISCORD_CFG {
token = "MTQwMzc3MTcxMDE5MjIyNjQxNA.GCJebu.7nU13QBDDSLVcBUR_PnNEt9fByr7vk1KL9TL4s", server = 1131205563699712081, channel = "1294596783317450803", channeltext = "Введите код в игровое меню. Чат: /raid", channelbutton = "Получить код", channelcolor = 14177041, channelmessageid = ""
}
}
;
}
}
private ConfigRoot config;
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<ConfigRoot>();
if (config?.discord == null) throw new Exception("invalid config");
}
catch {
PrintWarning("Config read error — writing default config.");
config = ConfigRoot.Default();
}
SaveConfig();
}
protected override void LoadDefaultConfig() => config = ConfigRoot.Default();
protected override void SaveConfig() => Config.WriteObject(config, true);
private void OnServerInitialized() {
ServerMgr.Instance.StartCoroutine(GetCallback());
timer.Every(3, () => UpdateStatus());
}
private void Unload() {
CloseClient();
}
IEnumerator GetCallback() {
if (!string.IsNullOrEmpty(config.discord.token)) {
if (config.discord.server > 0) CreateClient();
else Debug.LogError("Set up Server ID in config");
}
else Debug.LogError("Не указан токен для Discord бота!");
yield break;
}
void DirectMessage(ulong dsid, string text) {
}
private string RANDOMNUM() => UnityEngine.Random.Range(1000, 99999).ToString();
#region Discord
private Dictionary<ulong, string> DISCORDCODES = new Dictionary<ulong, string>();
private readonly BotConnection _discordSettings = new BotConnection {
Intents = GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.Guilds | GatewayIntents.GuildMembers
}
;
private DiscordGuild _guild;
public DiscordClient Client {
get;
set;
}
private int statusIndex = -1;
private string[] StatusTypes = new string[] {
"Game", "Stream", "Listen", "Watch"
}
;
public List<string> Status = new List<string> {
"{players.online} Online!", "{server.entities} Entities", "{players.sleepers} Sleepers!", "Connect {server.ip}:{server.port}",
}
;
private int GetStatusIndex() {
if (true) return (statusIndex + 1) % Status.Count;
var index = 0;
do index = Random.Range(0, Status.Count - 1);
while (index == statusIndex);
return index;
}
private void UpdateStatus() {
try {
if (Status.Count == 0) return;
var index = GetStatusIndex();
Client.UpdateStatus(new UpdatePresenceCommand {
Activities = new List<DiscordActivity> {
new DiscordActivity {
Name = Format(Status[index]), Type = ActivityType.Game
}
}
}
);
statusIndex = index;
}
catch (Exception err) {
LogToFile("DiscordStatus", $"{err}", this);
}
}
private string Format(string message) {
message = message .Replace("{players.online}", BasePlayer.activePlayerList.Count().ToString()) .Replace("{server.ip}", ConVar.Server.ip) .Replace("{server.port}", ConVar.Server.port.ToString()) .Replace("{server.entities}", BaseNetworkable.serverEntities.Count.ToString()) .Replace("{server.worldsize}", ConVar.Server.worldsize.ToString()) .Replace("{server.seed}", ConVar.Server.seed.ToString()) .Replace("{server.fps}", Performance.current.frameRate.ToString()) .Replace("{server.avgfps}", Convert.ToInt32(Performance.current.frameRateAverage).ToString()) .Replace("{players.queued}", ConVar.Admin.ServerInfo().Queued.ToString()) .Replace("{players.joining}", ConVar.Admin.ServerInfo().Joining.ToString()) .Replace("{players.sleepers}", BasePlayer.sleepingPlayerList.Count.ToString());
return message;
}
private void CreateClient() {
_discordSettings.ApiToken = config.discord.token;
_discordSettings.LogLevel = Ext.Discord.Logging.DiscordLogLevel.Error;
Client.Connect(_discordSettings);
timer.Once(5f, () => {
try {
if (Client == null) {
CreateClient();
Debug.Log("Discord reconnecting in 5 sec...");
}
else {
_guild = Client.Bot.GetGuild(new Snowflake(config.discord.server));
Debug.Log($"DISCORD БОТ АВТОРИЗОВАН НА СЕРВЕРЕ {_guild.Name}.");
DiscordChannel channel;
if (!_guild.Channels.TryGetValue(new Snowflake(config.discord.channel), out channel)) {
Debug.Log($"КАНАЛ НЕ СУЩЕСТВУЕТ! ({_guild.Channels.Count})");
return;
}
var embeds = new List<DiscordEmbed> {
new DiscordEmbed {
Color = new DiscordColor(config.discord.channelcolor), Author = new EmbedAuthor(config.discord.channeltext, "", "https://i.imgur.com/dBxxGTn.jpeg"), Footer = new EmbedFooter(Author = ConVar.Server.hostname + $" ({ConVar.Server.ip}:{ConVar.Server.port})"), Image = new EmbedImage(ConVar.Server.headerimage)
}
}
;
var components = CreateComponents(config.discord.channelbutton);
if (!string.IsNullOrEmpty(config.discord.channelmessageid) && ulong.TryParse(config.discord.channelmessageid, out ulong num) && num < 9223372036854775807) {
channel.GetMessage(Client, new Snowflake(config.discord.channelmessageid)).Then(message => {
message.Edit(Client, new MessageUpdate {
Embeds = embeds, Components = components
}
);
}
).Catch(error => {
DiscordCreateMessage(channel, embeds, components);
}
);
}
else {
DiscordCreateMessage(channel, embeds, components);
}
}
}
catch {
}
}
);
}
private void DiscordCreateMessage(DiscordChannel channel, List<DiscordEmbed> embeds, List<ActionRowComponent> components) {
var promise = channel?.CreateMessage(Client, new MessageCreate {
Embeds = embeds, Components = components
}
).Then(message => {
config.discord.channelmessageid = message.Id;
SaveConfig();
}
);
}
[HookMethod(DiscordExtHooks.OnDiscordInteractionCreated)]
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 channelex = "Ваш код: {code}";
string num;
if (!DISCORDCODES.TryGetValue(user.Id.Id, out num)) {
num = DISCORDCODES[user.Id.Id] = RANDOMNUM();
}
string linkMessage = Formatter.ToPlaintext(channelex.Replace("{code}", num));
interaction.CreateResponse(Client, new InteractionResponse {
Type = InteractionResponseType.ChannelMessageWithSource, Data = new InteractionCallbackData {
Content = linkMessage, Flags = MessageFlags.Ephemeral, Tts = true
}
}
);
}
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
}
}