C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core.Plugins;
using UnityEngine;
using Facepunch;
using Oxide.Ext.Discord;
using Oxide.Ext.Discord.Attributes;
using Oxide.Core.Libraries.Covalence;
using Oxide.Ext.Discord.Builders;
using Oxide.Ext.Discord.Entities;
using Oxide.Ext.Discord.Entities.Activities;
using Oxide.Ext.Discord.Entities.Channels;
using Oxide.Ext.Discord.Entities.Gatway;
using Oxide.Ext.Discord.Entities.Gatway.Commands;
using Oxide.Ext.Discord.Entities.Gatway.Events;
using Oxide.Ext.Discord.Entities.Guilds;
using Oxide.Ext.Discord.Entities.Messages;
using Oxide.Ext.Discord.Entities.Messages.Embeds;
using Oxide.Ext.Discord.Entities.Users;
using Oxide.Ext.Discord.Entities.Permissions;
using Oxide.Ext.Discord.Logging;
namespace Oxide.Plugins
{
[Info("Rustcord", "Kirollos & OuTSMoKE", "3.0.1")]
[Description("Complete game server monitoring through discord.")]
internal class Rustcord : RustPlugin
{
[PluginReference] Plugin PrivateMessages, BetterChatMute, Clans, AdminChat, DiscordAuth, AdminHammer, AdminRadar, Vanish, RaidableBases;
[DiscordClient] private DiscordClient _client;
private Settings _settings;
private int? _channelCount;
private Snowflake _botId;
private UpdatePresenceCommand DiscordPresence = new UpdatePresenceCommand
{
Activities = new List<DiscordActivity>
{
new DiscordActivity
{
Type = ActivityType.Game,
Name = "Rustcord Initializing..."
}
}
};
private Timer StatusTimer = null;
private class Settings
{
[JsonProperty(PropertyName = "General Settings")]
public GeneralSettings General { get; set; }
[JsonProperty(PropertyName = "Discord to Game Settings")]
public DiscordSideSettings DiscordSide { get; set; }
[JsonProperty(PropertyName = "Rust Logging Settings")]
public GameLogSettings GameLog { get; set; }
[JsonProperty(PropertyName = "Plugin Logging Settings")]
public PluginLogSettings PluginLog { get; set; }
[JsonProperty(PropertyName = "Discord Output Formatting")]
public OutputSettings OutputFormat { get; set; }
[JsonProperty(PropertyName = "Logging Exclusions")]
public ExcludedSettings Excluded { get; set; }
[JsonProperty(PropertyName = "Filter Settings")]
public FilterSettings Filters { get; set; }
[JsonProperty(PropertyName = "Discord Logging Channels")]
public List<Channel> Channels { get; set; }
[JsonProperty(PropertyName = "Discord Command Role Assignment (Empty = All roles can use command.)")]
public Dictionary<string, List<string>> Commandroles { get; set; }
public class Channel
{
[JsonProperty(PropertyName = "Discord Channel ID #")]
public Snowflake Channelid { get; set; }
[JsonProperty(PropertyName = "Channel Flags")]
public List<string> perms { get; set; }
[JsonProperty(PropertyName = "Custom: Words/Phrases to Log")]
public List<string> CustomFilter { get; set; }
}
}
public class GeneralSettings
{
[JsonProperty(PropertyName = "API Key (Bot Token)")]
public string Apikey { get; set; }
[JsonProperty(PropertyName = "Auto Reload Plugin")]
public bool AutoReloadPlugin { get; set; }
[JsonProperty(PropertyName = "Auto Reload Time (Seconds)")]
public int AutoReloadTime { get; set; }
[JsonProperty(PropertyName = "Enable Bot Status")]
public bool EnableBotStatus { get; set; }
[JsonProperty(PropertyName = "In-Game Report Command")]
public string ReportCommand { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
[DefaultValue(DiscordLogLevel.Info)]
[JsonProperty(PropertyName = "Discord Extension Log Level (Verbose/Debug/Info/Warning/Error/Exception/Off)")]
public DiscordLogLevel ExtensionDebugging { get; set; } = DiscordLogLevel.Info;
}
public class DiscordSideSettings
{
[JsonProperty(PropertyName = "Discord Command Prefix")]
public string Commandprefix { get; set; }
[JsonProperty(PropertyName = "Discord to Game Chat: Icon (Steam ID)")]
public ulong GameChatIconSteamID { get; set; }
[JsonProperty(PropertyName = "Discord to Game Chat: Tag")]
public string GameChatTag { get; set; }
[JsonProperty(PropertyName = "Discord to Game Chat: Tag Color (Hex)")]
public string GameChatTagColor { get; set; }
[JsonProperty(PropertyName = "Discord to Game Chat: Player Name Color (Hex)")]
public string GameChatNameColor { get; set; }
[JsonProperty(PropertyName = "Discord to Game Chat: Message Color (Hex)")]
public string GameChatTextColor { get; set; }
}
public class GameLogSettings
{
[JsonProperty(PropertyName = "Enable Logging: Player Chat")]
public bool LogChat { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Joins & Quits")]
public bool LogJoinQuits { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Deaths")]
public bool LogDeaths { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Vehicle Spawns (Heli/APC/Plane/Ship)")]
public bool LogVehicleSpawns { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Crate Drops (Hackable/Supply)")]
public bool LogCrateDrops { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Usergroup Changes")]
public bool LogUserGroups { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Permission Changes")]
public bool LogPermissions { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Kicks & Bans")]
public bool LogKickBans { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Player Name Changes")]
public bool LogNameChanges { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Server Commands (Gestures/Note Edits)")]
public bool LogServerCommands { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Server Messages (Give/Item Spawns)")]
public bool LogServerMessages { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Player F7 Reports")]
public bool LogF7Reports { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Team Changes")]
public bool LogTeams { get; set; }
[JsonProperty(PropertyName = "Enable Logging: RCON Connections")]
public bool LogRCON { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Spectates")]
public bool LogSpectates { get; set; }
[JsonProperty(PropertyName = "Enable Custom Logging")]
public bool EnableCustomLogging { get; set; }
}
public class PluginLogSettings
{
[JsonProperty(PropertyName = "Enable Logging: AdminHammer")]
public bool LogPluginAdminHammer { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Admin Radar")]
public bool LogPluginAdminRadar { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Better Chat Mute")]
public bool LogPluginBetterChatMute { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Clans")]
public bool LogPluginClans { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Discord Auth")]
public bool LogPluginDiscordAuth { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Private Messages")]
public bool LogPluginPrivateMessages { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Raidable Bases")]
public bool LogPluginRaidableBases { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Sign Artist")]
public bool LogPluginSignArtist { get; set; }
[JsonProperty(PropertyName = "Enable Logging: Vanish")]
public bool LogPluginVanish { get; set; }
}
public class OutputSettings
{
[JsonProperty(PropertyName = "Output Type: Bans (Simple/Embed)")]
public string OutputTypeBans { get; set; }
[JsonProperty(PropertyName = "Output Type: Bug Report (Simple/Embed)")]
public string OutputTypeBugs { get; set; }
[JsonProperty(PropertyName = "Output Type: Deaths (Simple/Embed/DeathNotes)")]
public string OutputTypeDeaths { get; set; }
[JsonProperty(PropertyName = "Output Type: F7 Reports (Simple/Embed)")]
public string OutputTypeF7Report { get; set; }
[JsonProperty(PropertyName = "Output Type: Join/Quit (Simple/Embed)")]
public string OutputTypeJoinQuit { get; set; }
[JsonProperty(PropertyName = "Output Type: Join Player Info (Admin Channel) (Simple/Embed)")]
public string OutputTypeJoinAdminChan { get; set; }
[JsonProperty(PropertyName = "Output Type: Kicks (Simple/Embed)")]
public string OutputTypeKicks { get; set; }
[JsonProperty(PropertyName = "Output Type: Note Logging (Simple/Embed)")]
public string OutputTypeNoteLog { get; set; }
[JsonProperty(PropertyName = "Output Type: Player Name Change (Simple/Embed)")]
public string OutputTypeNameChange { get; set; }
[JsonProperty(PropertyName = "Output Type: /Report (Simple/Embed)")]
public string OutputTypeReports { get; set; }
[JsonProperty(PropertyName = "Output Type: Teams (Simple/Embed)")]
public string OutputTypeTeams { get; set; }
[JsonProperty(PropertyName = "Output Type (Plugin): Admin Hammer (Simple/Embed)")]
public string OutputTypeAdminHammer { get; set; }
[JsonProperty(PropertyName = "Output Type (Plugin): Admin Radar (Simple/Embed)")]
public string OutputTypeAdminRadar { get; set; }
[JsonProperty(PropertyName = "Output Type (Plugin): Better Chat Mute (Simple/Embed)")]
public string OutputTypeBetterChatMute { get; set; }
[JsonProperty(PropertyName = "Output Type (Plugin): Clans (Simple/Embed)")]
public string OutputTypeClans { get; set; }
[JsonProperty(PropertyName = "Output Type (Plugin): Private Messages (Simple/Embed)")]
public string OutputTypePMs { get; set; }
[JsonProperty(PropertyName = "Output Type (Plugin): Raidable Bases (Simple/Embed)")]
public string OutputTypeRaidableBases { get; set; }
[JsonProperty(PropertyName = "Output Type (Plugin): Vanish (Simple/Embed)")]
public string OutputTypeVanish { get; set; }
}
public class ExcludedSettings
{
[JsonProperty(PropertyName = "Exclude Listed Groups From log_groups")]
public List<string> LogExcludeGroups { get; set; }
[JsonProperty(PropertyName = "Exclude Listed Permissions From log_perms")]
public List<string> LogExcludePerms { get; set; }
}
public class FilterSettings
{
[JsonProperty(PropertyName = "Chat Filter: Replacement Word")]
public string FilteredWord { get; set; }
[JsonProperty(PropertyName = "Chat Filter: Words to Filter")]
public List<string> FilterWords { get; set; }
}
enum CacheType
{
OnPlayerChat = 0,
OnPlayerConnected = 1,
OnPlayerDisconnected = 2,
OnPlayerJoin = 3
}
Dictionary<CacheType, Dictionary<BasePlayer, Dictionary<string, string>>> cache = new Dictionary<CacheType, Dictionary<BasePlayer, Dictionary<string, string>>>();
private string rbdiff;
Dictionary<string, string> GetPlayerCache(BasePlayer player, string message, CacheType type)
{
switch (type)
{
case CacheType.OnPlayerChat:
{
Dictionary<string, string> dict;
if (!cache[CacheType.OnPlayerChat].TryGetValue(player, out dict))
{
cache[CacheType.OnPlayerChat].Add(player, dict = new Dictionary<string, string>
{
["playername"] = player.displayName,
["message"] = message,
["playersteamid"] = player.UserIDString
});
}
dict["playername"] = player.displayName;
dict["message"] = message;
dict["playersteamid"] = player.UserIDString;
return dict;
}
case CacheType.OnPlayerConnected:
{
Dictionary<string, string> dict;
if (!cache[CacheType.OnPlayerConnected].TryGetValue(player, out dict))
{
cache[CacheType.OnPlayerConnected].Add(player, dict = new Dictionary<string, string>
{
["playername"] = player.displayName,
["playerip"] = message.Substring(0, message.IndexOf(":")),
["playersteamid"] = player.UserIDString
});
}
dict["playername"] = player.displayName;
dict["playerip"] = message.Substring(0, message.IndexOf(":"));
dict["playersteamid"] = player.UserIDString;
return dict;
}
case CacheType.OnPlayerJoin:
{
Dictionary<string, string> dict;
if (!cache[CacheType.OnPlayerJoin].TryGetValue(player, out dict))
{
cache[CacheType.OnPlayerDisconnected].Add(player, dict = new Dictionary<string, string>
{
["playername"] = player.displayName
});
}
dict["playername"] = player.displayName;
return dict;
}
case CacheType.OnPlayerDisconnected:
default:
{
Dictionary<string, string> dict;
if (!cache[CacheType.OnPlayerDisconnected].TryGetValue(player, out dict))
{
cache[CacheType.OnPlayerDisconnected].Add(player, dict = new Dictionary<string, string>
{
["playername"] = player.displayName,
["reason"] = message,
});
}
dict["playername"] = player.displayName;
dict["reason"] = message;
return dict;
}
}
}
//CONFIG FILE
private Settings GetDefaultSettings()
{
return new Settings
{
General = new GeneralSettings
{
Apikey = "BotToken",
AutoReloadPlugin = false,
AutoReloadTime = 901,
EnableBotStatus = false,
ReportCommand = "report",
ExtensionDebugging = DiscordLogLevel.Info
},
DiscordSide = new DiscordSideSettings
{
Commandprefix = "!",
GameChatIconSteamID = 76561199066612103,
GameChatTag = "[RUSTCORD]",
GameChatTagColor = "#7289DA",
GameChatNameColor = "#55aaff",
GameChatTextColor = "#ffffff",
},
GameLog = new GameLogSettings
{
LogChat = true,
LogJoinQuits = true,
LogDeaths = false,
LogVehicleSpawns = false,
LogCrateDrops = false,
LogUserGroups = false,
LogPermissions = false,
LogKickBans = true,
LogNameChanges = false,
LogServerCommands = false,
LogServerMessages = false,
LogF7Reports = false,
LogTeams = false,
LogRCON = false,
LogSpectates = false,
EnableCustomLogging = false
},
PluginLog = new PluginLogSettings
{
LogPluginAdminHammer = false,
LogPluginAdminRadar = false,
LogPluginBetterChatMute = false,
LogPluginClans = false,
LogPluginDiscordAuth = false,
LogPluginPrivateMessages = false,
LogPluginRaidableBases = false,
LogPluginSignArtist = false,
LogPluginVanish = false
},
OutputFormat = new OutputSettings
{
OutputTypeBans = "Simple",
OutputTypeBugs = "Simple",
OutputTypeDeaths = "Simple",
OutputTypeF7Report = "Simple",
OutputTypeJoinQuit = "Simple",
OutputTypeJoinAdminChan = "Simple",
OutputTypeKicks = "Simple",
OutputTypeNameChange = "Simple",
OutputTypeNoteLog = "Simple",
OutputTypeReports = "Simple",
OutputTypeTeams = "Simple",
OutputTypeAdminHammer = "Simple",
OutputTypeAdminRadar = "Simple",
OutputTypeBetterChatMute = "Simple",
OutputTypeClans = "Simple",
OutputTypePMs = "Simple",
OutputTypeRaidableBases = "Simple",
OutputTypeVanish = "Simple"
},
Channels = new List<Settings.Channel>
{
new Settings.Channel
{
perms = new List<string>
{
"cmd_allow",
"cmd_players",
"cmd_kick",
"cmd_com",
"cmd_mute",
"cmd_unmute",
"msg_join",
"msg_joinlog",
"msg_quit",
"death_pvp",
"msg_chat",
"msg_teamchat",
"game_report",
"game_bug",
"msg_serverinit"
},
CustomFilter = new List<string>
{
"keyword1",
"keyword2"
}
},
new Settings.Channel
{
perms = new List<string>
{
"msg_joinlog",
"game_report",
"game_bug"
},
CustomFilter = new List<string>
{
"keyword1",
"keyword2"
}
}
},
Commandroles = new Dictionary<string, List<string>>
{
{
"players", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
},
{
"mute", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
},
{
"unmute", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
},
{
"kick", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
},
{
"ban", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
},
{
"timeban", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
},
{
"unban", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
},
{
"com", new List<string>()
{
"DiscordRoleName",
"DiscordRoleName2"
}
}
},
Filters = new FilterSettings
{
FilterWords = new List<string>
{
"badword1",
"badword2"
},
FilteredWord = "<censored>",
},
Excluded = new ExcludedSettings
{
LogExcludeGroups = new List<string>
{
"example-group1",
"example-group2"
},
LogExcludePerms = new List<string>
{
"example.permission1",
"example.permission2"
}
},
};
}
protected override void LoadDefaultConfig()
{
PrintWarning("Attempting to create default config...");
Config.Clear();
Config.WriteObject(GetDefaultSettings(), true);
Config.Save();
}
//END CONFIG FILE
private void OnServerInitialized()
{
var reloadtime = _settings.General.AutoReloadTime;
permission.RegisterPermission("rustcord.hidejoinquit", this);
permission.RegisterPermission("rustcord.hidechat", this);
if (_settings.General.AutoReloadPlugin && _settings.General.AutoReloadTime > 59)
{
timer.Every(reloadtime, () => Reload());
}
if (_client != null)
{
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("msg_serverinit"))
{
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, Translate("RUST_OnInitMsg"));
});
}
}
}
}
void OnServerShutdown()
{
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("msg_serverinit"))
{
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, Translate("RUST_OnServerShutdown"));
});
}
}
}
void SubscribeHooks()
{
if (_settings.GameLog.LogChat) Subscribe(nameof(OnPlayerChat));
if (_settings.GameLog.LogJoinQuits)
{
Subscribe(nameof(OnPlayerConnected));
Subscribe(nameof(OnPlayerDisconnected));
}
if (_settings.GameLog.LogDeaths)
{
if (_settings.OutputFormat.OutputTypeDeaths == "DeathNotes") Subscribe(nameof(OnDeathNotice));
if ((_settings.OutputFormat.OutputTypeDeaths == "Simple") || (_settings.OutputFormat.OutputTypeDeaths == "Embed")) Subscribe(nameof(OnPlayerDeath));
}
if (_settings.GameLog.LogVehicleSpawns) Subscribe(nameof(OnEntitySpawned));
if (_settings.GameLog.LogCrateDrops)
{
Subscribe(nameof(OnCrateDropped));
Subscribe(nameof(OnSupplyDropLanded));
}
if (_settings.GameLog.LogUserGroups)
{
Subscribe(nameof(OnGroupCreated));
Subscribe(nameof(OnGroupDeleted));
Subscribe(nameof(OnUserGroupAdded));
Subscribe(nameof(OnUserGroupRemoved));
}
if (_settings.GameLog.LogPermissions)
{
Subscribe(nameof(OnUserPermissionGranted));
Subscribe(nameof(OnGroupPermissionGranted));
Subscribe(nameof(OnUserPermissionRevoked));
Subscribe(nameof(OnGroupPermissionRevoked));
}
if (_settings.GameLog.LogKickBans)
{
Subscribe(nameof(OnUserKicked));
Subscribe(nameof(OnUserBanned));
Subscribe(nameof(OnUserUnbanned));
}
if (_settings.GameLog.LogNameChanges) Subscribe(nameof(OnUserNameUpdated));
if (_settings.GameLog.LogServerMessages) Subscribe(nameof(OnServerMessage));
if (_settings.GameLog.LogServerCommands) Subscribe(nameof(OnServerCommand));
if (_settings.GameLog.LogF7Reports) Subscribe(nameof(OnPlayerReported));
if (_settings.GameLog.LogTeams)
{
Subscribe(nameof(OnTeamCreated));
Subscribe(nameof(OnTeamAcceptInvite));
Subscribe(nameof(OnTeamLeave));
Subscribe(nameof(OnTeamKick));
Subscribe(nameof(OnTeamDisbanded));
}
if (_settings.GameLog.LogRCON)
{
Subscribe(nameof(OnRconConnection));
}
if (_settings.GameLog.LogSpectates)
{
Subscribe(nameof(OnPlayerSpectate));
Subscribe(nameof(OnPlayerSpectateEnd));
}
if (_settings.PluginLog.LogPluginAdminHammer)
{
Subscribe(nameof(OnAdminHammerEnabled));
Subscribe(nameof(OnAdminHammerDisabled));
}
if (_settings.PluginLog.LogPluginAdminRadar)
{
Subscribe(nameof(OnRadarActivated));
Subscribe(nameof(OnRadarDeactivated));
}
if (_settings.PluginLog.LogPluginBetterChatMute)
{
Subscribe(nameof(OnBetterChatMuted));
Subscribe(nameof(OnBetterChatTimeMuted));
Subscribe(nameof(OnBetterChatUnmuted));
Subscribe(nameof(OnBetterChatMuteExpired));
}
if (_settings.PluginLog.LogPluginClans)
{
Subscribe(nameof(OnClanCreate));
Subscribe(nameof(OnClanDisbanded));
Subscribe(nameof(OnClanChat));
}
if (_settings.PluginLog.LogPluginPrivateMessages) Subscribe(nameof(OnPMProcessed));
if (_settings.PluginLog.LogPluginRaidableBases)
{
Subscribe(nameof(OnRaidableBaseStarted));
Subscribe(nameof(OnRaidableBaseEnded));
}
if (_settings.PluginLog.LogPluginSignArtist) Subscribe(nameof(OnImagePost));
if (_settings.PluginLog.LogPluginDiscordAuth)
{
Subscribe(nameof(OnAuthenticate));
Subscribe(nameof(OnDeauthenticate));
}
if (_settings.PluginLog.LogPluginVanish)
{
Subscribe(nameof(OnVanishDisappear));
Subscribe(nameof(OnVanishReappear));
}
}
private void Init()
{
cache[CacheType.OnPlayerChat] = new Dictionary<BasePlayer, Dictionary<string, string>>();
cache[CacheType.OnPlayerConnected] = new Dictionary<BasePlayer, Dictionary<string, string>>();
cache[CacheType.OnPlayerDisconnected] = new Dictionary<BasePlayer, Dictionary<string, string>>();
cache[CacheType.OnPlayerJoin] = new Dictionary<BasePlayer, Dictionary<string, string>>();
UnsubscribeHooks();
}
void UnsubscribeHooks()
{
Unsubscribe(nameof(OnPlayerChat));
Unsubscribe(nameof(OnPlayerConnected));
Unsubscribe(nameof(OnPlayerDisconnected));
Unsubscribe(nameof(OnDeathNotice));
Unsubscribe(nameof(OnPlayerDeath));
Unsubscribe(nameof(OnEntitySpawned));
Unsubscribe(nameof(OnCrateDropped));
Unsubscribe(nameof(OnSupplyDropLanded));
Unsubscribe(nameof(OnGroupCreated));
Unsubscribe(nameof(OnGroupDeleted));
Unsubscribe(nameof(OnUserGroupAdded));
Unsubscribe(nameof(OnUserGroupRemoved));
Unsubscribe(nameof(OnUserPermissionGranted));
Unsubscribe(nameof(OnGroupPermissionGranted));
Unsubscribe(nameof(OnUserPermissionRevoked));
Unsubscribe(nameof(OnGroupPermissionRevoked));
Unsubscribe(nameof(OnUserKicked));
Unsubscribe(nameof(OnUserBanned));
Unsubscribe(nameof(OnUserUnbanned));
Unsubscribe(nameof(OnUserNameUpdated));
Unsubscribe(nameof(OnServerMessage));
Unsubscribe(nameof(OnServerCommand));
Unsubscribe(nameof(OnPlayerReported));
Unsubscribe(nameof(OnTeamCreated));
Unsubscribe(nameof(OnTeamAcceptInvite));
Unsubscribe(nameof(OnTeamLeave));
Unsubscribe(nameof(OnTeamKick));
Unsubscribe(nameof(OnTeamDisbanded));
Unsubscribe(nameof(OnRconConnection));
Unsubscribe(nameof(OnPlayerSpectate));
Unsubscribe(nameof(OnPlayerSpectateEnd));
Unsubscribe(nameof(OnAdminHammerEnabled));
Unsubscribe(nameof(OnAdminHammerDisabled));
Unsubscribe(nameof(OnRadarActivated));
Unsubscribe(nameof(OnRadarDeactivated));
Unsubscribe(nameof(OnBetterChatTimeMuted));
Unsubscribe(nameof(OnBetterChatMuted));
Unsubscribe(nameof(OnBetterChatTimeMuted));
Unsubscribe(nameof(OnBetterChatUnmuted));
Unsubscribe(nameof(OnBetterChatMuteExpired));
Unsubscribe(nameof(OnClanCreate));
Unsubscribe(nameof(OnClanDisbanded));
Unsubscribe(nameof(OnClanChat));
Unsubscribe(nameof(OnPMProcessed));
Unsubscribe(nameof(OnImagePost));
Unsubscribe(nameof(OnAuthenticate));
Unsubscribe(nameof(OnDeauthenticate));
Unsubscribe(nameof(OnRaidableBaseStarted));
Unsubscribe(nameof(OnRaidableBaseEnded));
}
private void Loaded()
{
_settings = Config.ReadObject<Settings>();
// Make sure objects are not taken off the config, otherwise some parts of code will release NRE.
if (_settings.OutputFormat.OutputTypeBans == null)
_settings.OutputFormat.OutputTypeBans = "Simple";
if (_settings.OutputFormat.OutputTypeBugs == null)
_settings.OutputFormat.OutputTypeBugs = "Simple";
if (_settings.OutputFormat.OutputTypeDeaths == null)
_settings.OutputFormat.OutputTypeDeaths = "Simple";
if (_settings.OutputFormat.OutputTypeF7Report == null)
_settings.OutputFormat.OutputTypeF7Report = "Simple";
if (_settings.OutputFormat.OutputTypeJoinQuit == null)
_settings.OutputFormat.OutputTypeJoinQuit = "Simple";
if (_settings.OutputFormat.OutputTypeJoinAdminChan == null)
_settings.OutputFormat.OutputTypeJoinAdminChan = "Simple";
if (_settings.OutputFormat.OutputTypeKicks == null)
_settings.OutputFormat.OutputTypeKicks = "Simple";
if (_settings.OutputFormat.OutputTypeNameChange == null)
_settings.OutputFormat.OutputTypeNameChange = "Simple";
if (_settings.OutputFormat.OutputTypeNoteLog == null)
_settings.OutputFormat.OutputTypeNoteLog = "Simple";
if (_settings.OutputFormat.OutputTypeReports == null)
_settings.OutputFormat.OutputTypeReports = "Simple";
if (_settings.OutputFormat.OutputTypeTeams == null)
_settings.OutputFormat.OutputTypeTeams = "Simple";
if (_settings.OutputFormat.OutputTypeAdminHammer == null)
_settings.OutputFormat.OutputTypeAdminHammer = "Simple";
if (_settings.OutputFormat.OutputTypeAdminRadar == null)
_settings.OutputFormat.OutputTypeAdminRadar = "Simple";
if (_settings.OutputFormat.OutputTypeBetterChatMute == null)
_settings.OutputFormat.OutputTypeBetterChatMute = "Simple";
if (_settings.OutputFormat.OutputTypeClans == null)
_settings.OutputFormat.OutputTypeClans = "Simple";
if (_settings.OutputFormat.OutputTypePMs == null)
_settings.OutputFormat.OutputTypePMs = "Simple";
if (_settings.OutputFormat.OutputTypeRaidableBases == null)
_settings.OutputFormat.OutputTypeRaidableBases = "Simple";
if (_settings.OutputFormat.OutputTypeVanish == null)
_settings.OutputFormat.OutputTypeVanish = "Simple";
foreach (var channel in _settings.Channels)
{
if (channel.CustomFilter == null)
{
channel.CustomFilter = new List<string>();
}
}
if (_settings.General.ReportCommand == null)
_settings.General.ReportCommand = "report";
if (string.IsNullOrEmpty(_settings.DiscordSide.GameChatTag))
_settings.DiscordSide.GameChatTag = "[Rustcord]";
if (string.IsNullOrEmpty(_settings.DiscordSide.GameChatTagColor))
_settings.DiscordSide.GameChatTagColor = "#7289DA";
if (string.IsNullOrEmpty(_settings.DiscordSide.GameChatNameColor))
_settings.DiscordSide.GameChatNameColor = "#55aaff";
if (string.IsNullOrEmpty(_settings.DiscordSide.GameChatTextColor))
_settings.DiscordSide.GameChatTextColor = "#ffffff";
if (_settings.DiscordSide.GameChatIconSteamID.Equals(0uL))
_settings.DiscordSide.GameChatIconSteamID = 76561199066612103;
if (_settings.Channels == null)
_settings.Channels = new List<Settings.Channel>();
if (_settings.Commandroles == null)
_settings.Commandroles = new Dictionary<string, List<string>>();
_settings.Filters = new FilterSettings
{
FilteredWord = _settings.Filters?.FilteredWord ?? "<censored>",
FilterWords = _settings.Filters?.FilterWords ?? new List<string>()
};
if (_settings.Excluded.LogExcludeGroups == null)
_settings.Excluded.LogExcludeGroups = new List<string>();
if (_settings.Excluded.LogExcludePerms == null)
_settings.Excluded.LogExcludePerms = new List<string>();
Config.WriteObject(_settings, true);
// ------------------------------------------------------------------------
}
private void OnDiscordClientCreated()
{
if (string.IsNullOrEmpty(_settings.General.Apikey) || _settings.General.Apikey == null || _settings.General.Apikey == "BotToken")
{
PrintError("API key is empty or invalid!");
return;
}
bool flag = true;
try
{
DiscordSettings settings = new DiscordSettings
{
ApiToken = _settings.General.Apikey,
Intents = GatewayIntents.Guilds | GatewayIntents.GuildMembers | GatewayIntents.GuildMessages | GatewayIntents.DirectMessages,
LogLevel = _settings.General.ExtensionDebugging
};
_client.Connect(settings);
}
catch (Exception e)
{
flag = false;
PrintError($"Rustcord failed to create client! Exception message: {e}");
}
if (flag)
{
cmd.AddChatCommand(_settings.General.ReportCommand, this, "cmdReport");
cmd.AddChatCommand("bug", this, "cmdBug");
SubscribeHooks();
}
if (_settings.GameLog.EnableCustomLogging)
UnityEngine.Application.logMessageReceived += ConsoleLog;
}
private void Reload()
{
rust.RunServerCommand("oxide.reload Rustcord");
}
void OnDiscordGatewayReady(GatewayReadyEvent rdy)
{
_botId = rdy.User.Id;
SubscribeHooks();
_channelCount = _settings?.Channels.Count;
if (_settings.General.EnableBotStatus)
{
NextFrame(() =>
{
if (StatusTimer != null && !StatusTimer.Destroyed)
{
StatusTimer.Destroy();
}
StatusTimer = timer.Every(6f, () =>
{
var text = new Dictionary<string, string>
{
["players"] = Convert.ToString(BasePlayer.activePlayerList.Count),
["maxplayers"] = Convert.ToString(ConVar.Server.maxplayers),
["sleepers"] = Convert.ToString(BasePlayer.sleepingPlayerList.Count)
};
var msg = Translate("Discord_Status", text);
DiscordPresence.Activities[0].Name = string.IsNullOrEmpty(msg) ? "Rustcord initializing...." : msg;
_client.Bot.UpdateStatus(DiscordPresence);
});
});
}
}
void OnDiscordGuildCreated(DiscordGuild newguild)
{
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("msg_plugininit"))
{
GetChannel(_client, _settings.Channels[i].Channelid, c => {
c.CreateMessage(_client, "Rustcord Initialized!");
}, newguild.Id);
}
}
}
private void Unload()
{
if (StatusTimer != null && !StatusTimer.Destroyed)
{
StatusTimer.Destroy();
}
if (_settings.GameLog.EnableCustomLogging)
UnityEngine.Application.logMessageReceived -= ConsoleLog;
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
{ "Discord_PlayersResponse", ":mag_right: Connected Players [{count}/{maxplayers}]: {playerslist}" },
{ "Discord_Status", "{players}/{maxplayers} Online, {sleepers} Sleepers." },
{ "RUST_OnInitMsg", ":vertical_traffic_light: Server is back online! Players may now re-join. :vertical_traffic_light:" },
{ "RUST_OnServerShutdown", ":vertical_traffic_light: Server shutting down. :vertical_traffic_light:" },
{ "RUST_OnPlayerGesture", ":speech_left: {playername}: {gesture}"},
{ "RUST_OnPlayerChat", ":speech_left: {playername}: {message}"},
{ "RUST_OnPlayerTeamChat", ":speech_left: {playername}: {message}"},
{ "RUST_OnPlayerJoin", ":white_check_mark: {playername} has connected!" },
{ "RUST_OnPlayerJoinAdminLog", ":clipboard: {playername} has connected! (IP: {playerip} SteamID: {playersteamid})" },
{ "RUST_OnPlayerQuit", ":x: {playername} has disconnected! ({reason})" },
{ "RUST_OnPlayerBug", ":beetle: {playername}: {message}"},
{ "RUST_OnPlayerReport", ":warning: {playername}: {message}"},
{ "RUST_OnPlaneSpawn", ":airplane: Cargo Plane has spawned."},
{ "RUST_OnBradleySpawn", ":trolleybus: Bradley APC has spawned."},
{ "RUST_OnShipSpawn", ":ship: Cargo Ship has spawned."},
{ "RUST_OnSupplyDrop", ":airplane: A supply drop has landed."},
{ "RUST_OnHeliSpawn", ":helicopter: Patrol Helicopter has spawned."},
{ "RUST_OnChinookSpawn", ":helicopter: Chinook Helicopter has spawned."},
{ "RUST_OnCrateDropped", ":helicopter: A Chinook has delivered a crate."},
{ "RUST_OnTeamAcceptInvite", ":family_mwgb: {playername} joined {teamleader}'s team. ({teamid})"},
{ "RUST_OnTeamCreated", ":family_mwgb: {playername} created a new team. ({teamid})"},
{ "RUST_OnTeamKicked", ":family_mwgb: {teamleader} kicked {playername} from their team. ({teamid})"},
{ "RUST_OnTeamLeave", ":family_mwgb: {playername} left {teamleader}'s team ({teamid})."},
{ "RUST_OnTeamDisbanded", ":family_mwgb: {teamleader}'s team has been disbanded. ({teamid})"},
{ "RUST_OnGroupCreated", ":desktop: Group {groupname} has been created."},
{ "RUST_OnGroupDeleted", ":desktop: Group {groupname} has been deleted."},
{ "RUST_OnUserGroupAdded", ":desktop: {playername} ({steamid}) has been added to group: {group}."},
{ "RUST_OnUserGroupRemoved", ":desktop: {playername} ({steamid}) has been removed from group: {group}."},
{ "RUST_OnUserPermissionGranted", ":desktop: {playername} ({steamid}) has been granted permission: {permission}."},
{ "RUST_OnGroupPermissionGranted", ":desktop: Group {group} has been granted permission: {permission}."},
{ "RUST_OnUserPermissionRevoked", ":desktop: {playername} ({steamid}) has been revoked permission: {permission}."},
{ "RUST_OnGroupPermissionRevoked", ":desktop: Group {group} has been revoked permission: {permission}."},
{ "RUST_OnPlayerKicked", ":desktop: {playername} has been kicked for: {reason}"},
{ "RUST_OnPlayerBanned", ":desktop: {playername} ({steamid}/{ip}) has been banned for: {reason}"}, //only works with vanilla/native system atm
{ "RUST_OnPlayerUnBanned", ":desktop: {playername} ({steamid}/{ip}) has been unbanned."}, //only works with vanilla/native system atm
{ "RUST_OnPlayerNameChange", ":desktop: {oldname} ({steamid}) is now playing as {newname}."},
{ "RUST_OnPlayerReported", ":desktop: {reporter} reported {targetplayer} ({targetsteamid}) to Facepunch for {reason}. Message: {message}"},
{ "RUST_OnPlayerDeath", ":skull_crossbones: {killer} killed {victim}."},
{ "RUST_OnF1ItemSpawn", ":desktop: {name}: {givemessage}."},
{ "RUST_OnNoteUpdate", ":desktop: [NOTES] {playername}: {notemessage}."},
{ "RUST_OnRCONConnected", ":desktop: [RCON] New connection from: {ip}."},
{ "RUST_OnPlayerSpectate", ":desktop: {player} is spectating {target}"},
{ "RUST_CustomLog", ":desktop: [Custom] {logtext}"},
{ "RUST_OnPlayerSpectateEnd", ":desktop: {player} stopped spectating {target}"},
{ "PLUGIN_AdminHammer_Enabled", ":hammer: {player} has enabled Admin Hammer."},
{ "PLUGIN_AdminHammer_Disabled", ":hammer: {player} has disabled Admin Hammer."},
{ "PLUGIN_AdminRadar_Enabled", ":satellite: {player} has enabled Admin Radar."},
{ "PLUGIN_AdminRadar_Disabled", ":satellite: {player} has disabled Admin Radar."},
{ "PLUGIN_BetterChatMute_Mute", "[MUTE] :zipper_mouth: {muter} has permanently muted {target}. Reason: {reason}"},
{ "PLUGIN_BetterChatMute_UnMute", "[MUTE] :loudspeaker: {unmuter} has unmuted {target}."},
{ "PLUGIN_BetterChatMute_TimedMute", "[MUTE] :hourglass_flowing_sand: {muter} has been temporarily muted {target} for {time}. Reason: {reason}"},
{ "PLUGIN_BetterChatMute_MuteExpire", "[MUTE] :hourglass: {target}'s temporary mute has expired."},
{ "PLUGIN_Clans_Chat", ":speech_left: [CLANS] {playername}: {message}"},
{ "PLUGIN_Clans
// ... [Code preview truncated due to length. Full source in attached file] ...