C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Globalization;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
using Oxide.Ext.Discord;
using Oxide.Ext.Discord.Attributes;
using Oxide.Ext.Discord.DiscordObjects;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins
{
[Info("Rustcord", "Kirollos & OuTSMoKE", "2.5.2")]
[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 Presence DiscordPresence = new Presence()
{
Game = new Ext.Discord.DiscordObjects.Game()
{
Type = ActivityType.Game,
Name = "Rustcord Initializing..."
}
};
private Timer StatusTimer = null;
private class Settings
{
public string Apikey { get; set; }
public bool AutoReloadPlugin { get; set; }
public int AutoReloadTime { get; set; }
public bool EnableBotStatus { get; set; }
public ulong GameChatIconSteamID { get; set; }
public string GameChatTag { get; set; }
public string GameChatTagColor { get; set; }
public string GameChatNameColor { get; set; }
public string GameChatTextColor { get; set; }
public bool LogChat { get; set; }
public bool LogJoinQuits { get; set; }
public bool LogDeaths { get; set; }
public bool LogVehicleSpawns { get; set; }
public bool LogCrateDrops { get; set; }
public bool LogUserGroups { get; set; }
public bool LogPermissions { get; set; }
public bool LogKickBans { get; set; }
public bool LogNameChanges { get; set; }
public bool LogServerCommands { get; set; }
public bool LogServerMessages { get; set; }
public bool LogF7Reports { get; set; }
public bool LogTeams { get; set; }
public bool LogRCON { get; set; }
public bool LogPluginAdminHammer { get; set; }
public bool LogPluginAdminRadar { get; set; }
public bool LogPluginBetterChatMute { get; set; }
public bool LogPluginClans { get; set; }
public bool LogPluginDiscordAuth { get; set; }
public bool LogPluginPrivateMessages { get; set; }
public bool LogPluginRaidableBases { get; set; }
public bool LogPluginSignArtist { get; set; }
public bool LogPluginVanish { get; set; }
public bool EnableCustomLogging { get; set; }
public List<string> CustomLoggingKeywords;
public string ReportCommand { get; set; }
private string _Botid { get; set; }
public string Botid(string id = null)
{
if (id != null)
{
_Botid = id;
}
return _Botid;
}
public string Commandprefix { get; set; }
public List<Channel> Channels { get; set; }
public Dictionary<string, List<string>> Commandroles { get; set; }
public class Channel
{
public string Channelid { get; set; }
public List<string> perms { get; set; }
}
public List<string> FilterWords;
public string FilteredWord;
public List<string> LogExcludeGroups;
public List<string> LogExcludePerms;
}
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
{
Apikey = "BotToken",
AutoReloadPlugin = false,
AutoReloadTime = 901,
Commandprefix = "!",
GameChatIconSteamID = 76561199066612103,
GameChatTag = "[RUSTCORD]",
GameChatTagColor = "#7289DA",
GameChatNameColor = "#55aaff",
GameChatTextColor = "#ffffff",
ReportCommand = "report",
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,
LogPluginAdminHammer = false,
LogPluginAdminRadar = false,
LogPluginBetterChatMute = false,
LogPluginClans = false,
LogPluginDiscordAuth = false,
LogPluginPrivateMessages = false,
LogPluginRaidableBases = false,
LogPluginSignArtist = false,
LogPluginVanish = false,
EnableCustomLogging = false,
EnableBotStatus = false,
CustomLoggingKeywords = new List<string>() {
"Keyword 1",
"Keyword 2"
},
Channels = new List<Settings.Channel>
{
new Settings.Channel
{
Channelid = string.Empty,
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"
}
}
},
Commandroles = new Dictionary<string, List<string>>
{
{
"command", new List<string>()
{
"rolename1",
"rolename2"
}
}
},
FilterWords = new List<string>
{
"badword1",
"badword2"
},
FilteredWord = "<censored>",
LogExcludeGroups = new List<string>
{
"default"
},
LogExcludePerms = new List<string>
{
"example.permission"
}
};
}
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.AutoReloadTime;
permission.RegisterPermission("rustcord.hidejoinquit", this);
permission.RegisterPermission("rustcord.hidechat", this);
if (_settings.AutoReloadPlugin && _settings.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.LogChat) Subscribe(nameof(OnPlayerChat));
if (_settings.LogJoinQuits)
{
Subscribe(nameof(OnPlayerConnected));
Subscribe(nameof(OnPlayerDisconnected));
}
if (_settings.LogDeaths) Subscribe(nameof(OnDeathNotice));
if (_settings.LogVehicleSpawns) Subscribe(nameof(OnEntitySpawned));
if (_settings.LogCrateDrops)
{
Subscribe(nameof(OnCrateDropped));
Subscribe(nameof(OnSupplyDropLanded));
}
if (_settings.LogUserGroups)
{
Subscribe(nameof(OnGroupCreated));
Subscribe(nameof(OnGroupDeleted));
Subscribe(nameof(OnUserGroupAdded));
Subscribe(nameof(OnUserGroupRemoved));
}
if (_settings.LogPermissions)
{
Subscribe(nameof(OnUserPermissionGranted));
Subscribe(nameof(OnGroupPermissionGranted));
Subscribe(nameof(OnUserPermissionRevoked));
Subscribe(nameof(OnGroupPermissionRevoked));
}
if (_settings.LogKickBans)
{
Subscribe(nameof(OnUserKicked));
Subscribe(nameof(OnUserBanned));
Subscribe(nameof(OnUserUnbanned));
}
if (_settings.LogNameChanges) Subscribe(nameof(OnUserNameUpdated));
if (_settings.LogServerMessages) Subscribe(nameof(OnServerMessage));
if (_settings.LogServerCommands) Subscribe(nameof(OnServerCommand));
if (_settings.LogF7Reports) Subscribe(nameof(OnPlayerReported));
if (_settings.LogTeams)
{
Subscribe(nameof(OnTeamCreated));
Subscribe(nameof(OnTeamAcceptInvite));
Subscribe(nameof(OnTeamLeave));
Subscribe(nameof(OnTeamKick));
Subscribe(nameof(OnTeamDisbanded));
}
if (_settings.LogRCON)
{
Subscribe(nameof(OnRconConnection));
}
if (_settings.LogPluginAdminHammer)
{
Subscribe(nameof(OnAdminHammerEnabled));
Subscribe(nameof(OnAdminHammerDisabled));
}
if (_settings.LogPluginAdminRadar)
{
Subscribe(nameof(OnRadarActivated));
Subscribe(nameof(OnRadarDeactivated));
}
if (_settings.LogPluginBetterChatMute)
{
Subscribe(nameof(OnBetterChatMuted));
Subscribe(nameof(OnBetterChatTimeMuted));
Subscribe(nameof(OnBetterChatUnmuted));
Subscribe(nameof(OnBetterChatMuteExpired));
}
if (_settings.LogPluginClans)
{
Subscribe(nameof(OnClanCreate));
Subscribe(nameof(OnClanDestroy));
Subscribe(nameof(OnClanChat));
}
if (_settings.LogPluginPrivateMessages) Subscribe(nameof(OnPMProcessed));
if (_settings.LogPluginRaidableBases)
{
Subscribe(nameof(OnRaidableBaseStarted));
Subscribe(nameof(OnRaidableBaseEnded));
}
if (_settings.LogPluginSignArtist) Subscribe(nameof(OnImagePost));
if (_settings.LogPluginDiscordAuth)
{
Subscribe(nameof(OnAuthenticate));
Subscribe(nameof(OnDeauthenticate));
}
if (_settings.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(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(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(OnClanDestroy));
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.Channels == null)
_settings.Channels = new List<Settings.Channel>();
if (_settings.Commandroles == null)
_settings.Commandroles = new Dictionary<string, List<string>>();
if (_settings.FilterWords == null)
_settings.FilterWords = new List<string>();
if (_settings.LogExcludeGroups == null)
_settings.LogExcludeGroups = new List<string>();
if (_settings.LogExcludePerms == null)
_settings.LogExcludePerms = new List<string>();
if (_settings.CustomLoggingKeywords == null)
_settings.CustomLoggingKeywords = new List<string>();
if (_settings.ReportCommand == null)
_settings.ReportCommand = "report";
if (string.IsNullOrEmpty(_settings.GameChatTag))
_settings.GameChatTag = "[Rustcord]";
if (string.IsNullOrEmpty(_settings.GameChatTagColor))
_settings.GameChatTagColor = "#7289DA";
if (string.IsNullOrEmpty(_settings.GameChatNameColor))
_settings.GameChatNameColor = "#55aaff";
if (string.IsNullOrEmpty(_settings.GameChatTextColor))
_settings.GameChatTextColor = "#ffffff";
if (_settings.GameChatIconSteamID.Equals(0uL))
_settings.GameChatIconSteamID = 76561199066612103;
Config.WriteObject(_settings, true);
// ------------------------------------------------------------------------
if (string.IsNullOrEmpty(_settings.Apikey) || _settings.Apikey == null || _settings.Apikey == "BotToken")
{
PrintError("API key is empty or invalid!");
return;
}
bool flag = true;
try
{
Oxide.Ext.Discord.Discord.CreateClient(this, _settings.Apikey);
}
catch (Exception e)
{
flag = false;
PrintError($"Rustcord failed to create client! Exception message: {e.Message}");
}
if (flag)
{
cmd.AddChatCommand(_settings.ReportCommand, this, "cmdReport");
cmd.AddChatCommand("bug", this, "cmdBug");
SubscribeHooks();
}
if (_settings.EnableCustomLogging)
UnityEngine.Application.logMessageReceived += ConsoleLog;
}
private void Reload()
{
rust.RunServerCommand("oxide.reload Rustcord");
}
void Discord_Ready(Oxide.Ext.Discord.DiscordEvents.Ready rdy)
{
_settings.Botid(rdy.User.id);
SubscribeHooks();
_channelCount = _settings?.Channels.Count;
if (_settings.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.Game.Name = string.IsNullOrEmpty(msg) ? "Rustcord initializing...." : msg;
_client.UpdateStatus(DiscordPresence);
});
});
}
}
void Discord_GuildCreate(Guild 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.EnableCustomLogging)
UnityEngine.Application.logMessageReceived -= ConsoleLog;
Discord.CloseClient(_client);
}
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_OnPlayerReport", ":warning: {playername}: {message}"},
{ "RUST_OnPlayerBug", ":beetle: {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_OnF1ItemSpawn", ":desktop: {name}: {givemessage}."},
{ "RUST_OnNoteUpdate", ":desktop: [NOTES] {playername}: {notemessage}."},
{ "RUST_OnRCONConnected", ":desktop: [RCON] New connection from: {ip}."},
{ "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_CreateClan", ":family_mwgb: Clan [{clan}] has been created."},
{ "PLUGIN_Clans_DisbandClan", ":family_mwgb: Clan [{clan}] has been disbanded."},
{ "PLUGIN_Clans_MemberJoin", ":family_mwgb: {playername} ({steamid}) joined clan: [{clan}]."},
{ "PLUGIN_Clans_MemberLeave", ":family_mwgb: {playername} left clan: [{clan}]."},
{ "PLUGIN_DiscordAuth_Auth", ":lock: {gamename} has linked to Discord account {discordname}."},
{ "PLUGIN_DiscordAuth_Deauth", ":unlock: {gamename} has been unlinked from Discord account {discordname}."},
{ "PLUGIN_PrivateMessages_PM", "[PM] {sender} :incoming_envelope: {target}: {message}"},
{ "PLUGIN_RaidableBases_Started", ":house: {difficulty} Raidable Base has spawned at {position}."},
{ "PLUGIN_RaidableBases_Ended", ":house: {difficulty} Raidable Base at {position} has ended."},
{ "PLUGIN_SignArtist", "{player} posted an image to a sign.\nPosition: ({position})"},
{ "PLUGIN_Vanish_Disappear", ":ghost: {player} has vanished." },
{ "PLUGIN_Vanish_Reappear", ":ghost: {player} has reappeared." }
}, this);
}
private void OnPlayerChat(BasePlayer player, string message, ConVar.Chat.ChatChannel channel)
{
if (_client == null) return;
if (player == null || message == null) return;
if (permission.UserHasPermission(player.UserIDString, "rustcord.hidechat")) return;
if (BetterChatMute?.Call<bool>("API_IsMuted", player.IPlayer) ?? false) return;
if (_settings.FilterWords != null && _settings.FilterWords.Count > 0)
{
for (int i = _settings.FilterWords.Count - 1; i >= 0; i--)
{
while (message.Contains(" " + _settings.FilterWords[i] + " ") || message.Contains(_settings.FilterWords[i]))
message = message.Replace(_settings.FilterWords[i], _settings.FilteredWord ?? "");
}
}
var text = GetPlayerCache(player, message, CacheType.OnPlayerChat);
for (int i = 0; i < _settings.Channels.Count; i++)
{
if (_settings.Channels[i].perms.Contains(channel == ConVar.Chat.ChatChannel.Team ? "msg_teamchat" : "msg_chat"))
{
if (!(player.IsValid())) continue;
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, Translate(channel == ConVar.Chat.ChatChannel.Team ? "RUST_OnPlayerTeamChat" : "RUST_OnPlayerChat", text));
});
}
}
text.Clear();
}
private void OnPlayerConnected(BasePlayer player)
{
if (_client == null) return;
if (player == null) return;
var text = GetPlayerCache(player, player.net.connection.ipaddress, CacheType.OnPlayerConnected);
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("msg_joinlog"))
{
if (!player.IsValid()) return;
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
// Admin
chan.CreateMessage(_client, Translate("RUST_OnPlayerJoinAdminLog", text));
});
}
}
if (permission.UserHasPermission(player.UserIDString, "rustcord.hidejoinquit")) return;
text = GetPlayerCache(player, null, CacheType.OnPlayerJoin);
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("msg_join"))
{
if (!player.IsValid()) return;
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, Translate("RUST_OnPlayerJoin", text));
});
}
}
}
private void OnPlayerDisconnected(BasePlayer player, string reason)
{
if (_client == null) return;
if (player == null || string.IsNullOrEmpty(reason)) return;
if (permission.UserHasPermission(player.UserIDString, "rustcord.hidejoinquit"))
return;
var text = GetPlayerCache(player, reason, CacheType.OnPlayerDisconnected);
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("msg_quit"))
{
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, Translate("RUST_OnPlayerQuit", text));
});
}
}
cache[CacheType.OnPlayerChat].Remove(player);
cache[CacheType.OnPlayerConnected].Remove(player);
cache[CacheType.OnPlayerDisconnected].Remove(player);
cache[CacheType.OnPlayerJoin].Remove(player);
}
private void OnDeathNotice(Dictionary<string, object> data, string message)
{
if (_client == null) return;
if (data["VictimEntityType"] == null || data["KillerEntityType"] == null) return;
int victimType = (int)data["VictimEntityType"];
int killerType = (int)data["KillerEntityType"];
var _DeathNotes = plugins.Find("DeathNotes");
if (_DeathNotes != null)
if ((victimType == 5 && (killerType == 5 || killerType == 6 || killerType == 7 || killerType == 8 || killerType == 9 || killerType == 10 || killerType == 11 || killerType == 12 || killerType == 14 || killerType == 15)))
{
message = (string)_DeathNotes.Call("StripRichText", message);
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("death_pvp"))
{
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, ":skull_crossbones: " + message);
});
}
}
}
else if ((victimType == 2 && killerType == 5) || (victimType == 5 && killerType == 2))
{
message = (string)_DeathNotes.Call("StripRichText", message);
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("death_animal"))
{
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, ":skull_crossbones: " + message);
});
}
}
}
else if ((victimType == 5 && (killerType == 0 || killerType == 1)) || ((victimType == 0 || victimType == 1) && (killerType == 5)))
{
message = (string)_DeathNotes.Call("StripRichText", message);
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("death_vehicle"))
{
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, ":skull_crossbones: " + message);
});
}
}
}
else if ((victimType == 5 && (killerType == 3 || killerType == 4)) || ((victimType == 3 || victimType == 4) && (killerType == 5)))
{
message = (string)_DeathNotes.Call("StripRichText", message);
for (int i = 0; i < _channelCount; i++)
{
if (_settings.Channels[i].perms.Contains("death_npc"))
{
GetChannel(_client, _settings.Channels[i].Channelid, chan =>
{
chan.CreateMessage(_client, ":skull_crossbones: " + message);
});
}
}
}
}
// TEMP fix until extension calls the hooks in NextFrame
private void Discord_MessageCreate(Message message)
{
NextFrame(() => Discord_MessageCreate_Ex(message));
}
private void Discord_MessageCreate_Ex(Message message)
{
if ((message.content?.Length ?? 0) == 0) return;
Settings.Channel channelidx = FindChannelById(message.channel_id);
if (channelidx == null)
return;
if (message.author.id == _settings.Botid()) return;
if (message.content[0] == _settings.Commandprefix[0])
{
if (!channelidx.perms.Contains("cmd_allow"))
return;
string cmd;
string msg;
try
{
cmd = message.content.Split(' ')[0].ToLower();
if (string.IsNullOrEmpty(cmd.Trim()))
cmd = message.content.Trim().ToLower();
}
catch
{
cmd = message.content.Trim().ToLower();
}
cmd = cmd.Remove(0, 1);
msg = message.content.Remove(0, 1 + cmd.Length).Trim();
cmd = cmd.Trim();
cmd = cmd.ToLower();
if (!channelidx.perms.Contains("cmd_" + cmd))
return;
if (!_settings.Commandroles.ContainsKey(cmd))
{
DiscordToGameCmd(cmd, msg, message.author, message.channel_id);
return;
}
var roles = _settings.Commandroles[cmd];
if (roles.Count == 0)
{
DiscordToGameCmd(cmd, msg, message.author, message.channel_id);
return;
}
foreach (var roleid in message.member.roles)
{
var rolename = GetRoleNameById(roleid);
if (roles.Contains(rolename))
{
DiscordToGameCmd(cmd, msg, message.author, message.channel_id);
break;
}
}
}
else
{
var chattag = _settings.GameChatTag;
var chattagcolor = _settings.GameChatTagColor;
var chatnamecolor = _settings.GameChatNameColor;
var chattextcolor = _settings.GameChatTextColor;
if (!channelidx.perms.Contains("msg_chat")) return;
string nickname = message.member?.nick ?? "";
if (nickname.Length == 0)
nickname = message.author.username;
//PrintToChat("<color=" + chattagcolor + ">" + chattag + "</color> " + "<color=" + chatnamecolor + ">" + nickname + ":</color> " + "<color=" + chattextcolor + ">" + message.content + "</color>");
string text = $"<color={chattagcolor}>{chattag}</color> <color={chatnamecolor}>{nickname}:</color> <color={chattextcolor}>{message.content}</color>";
foreach (var player in BasePlayer.activePlayerList) Player.Message(player, text, _settings.GameChatIconSteamID);
Puts("[DISCORD] " + nickname + ": " + message.content);
}
}
private void DiscordToGameCmd(string command, string param, User author, string channelid)
{
switch (command)
{
case "players":
{
string listStr = string.Empty;
var pList = BasePlayer.activePlayerList;
int i = 0;
foreach (var player in pList)
{
listStr += player.displayName + "[" + i++ + "]";
if (i != pList.Count)
listStr += ", ";
if (i % 25 == 0 || i == pList.Count)
{
var text = new Dictionary<string, string>
{
["count"] = Convert.ToString(BasePlayer.activePlayerList.Count),
["maxplayers"] = Convert.ToString(ConVar.Server.maxplayers),
["playerslist"] = listStr
};
GetChannel(_client, channelid, chan =>
{
// Connected Players [{count}/{maxplayers}]: {playerslist}
chan.CreateMessage(_client, Translate("Discord_PlayersResponse", text));
});
text.Clear();
listStr = string.Empty;
}
}
break;
}
case "kick":
{
if (String.IsNullOrEmpty(param))
{
GetChannel(_client, channelid, chan =>
{
chan.CreateMessage(_client, "Syntax: !kick <steam id> <reason>");
});
return;
}
string[] _param = param.Split(' ');
if (_param.Length < 2)
{
GetChannel(_client, channelid, chan =>
{
chan.CreateMessage(_client, "Syntax: !kick <steam id> <reason>");
});
return;
}
BasePlayer plr = BasePlayer.Find(_param[0]);
if (plr == null)
{
GetChannel(_client, channelid, chan =>
{
chan.CreateMessage(_client, "Error: player not found");
});
return;
}
plr.Kick(param.Remove(0, _param[0].Length + 1));
GetChannel(_client, channelid, chan =>
{
chan.CreateMessage(_client, "Success: Kick command executed!");
});
break;
}
case "timeban":
{
if (string.IsNullOrEmpty(param))
{
GetChannel(_client, channelid, chan =>
{
chan.CreateMessage(_client, "Syntax: !timeban <steamid> <name> <duration> <reason>");
});
return;
}
string[] _param = param.Split(' ');
if (_param.Length < 3)
{
GetChannel(_client, channelid, chan =>
{
chan.CreateMessage(_client, "Syntax: !timeban <steamid> <name> <duration> <reason>");
});
return;
}
var plr = covalence.Players.FindPlayer(_param[0]);
if (plr == null)
{
GetChannel(_client, channelid, chan =>
{
chan.CreateMessage(_client, "Error: player not found");
});
return;
}
string[] args = new string[4];
args[0] = _param[0]; // id
args[1] = _param[1]; // name
args[2] = "\""; // reason
for (int i = 3; i
// ... [Code preview truncated due to length. Full source in attached file] ...