C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.ClansExtensionMethods;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Oxide.Plugins {
[Info("Clans", "Mevent", "1.1.6")]
public class Clans : RustPlugin {
//TODO: Displaying the top clans on the screen
//TODO: Added UI options for clan management
#region Fields
[PluginReference]
private Plugin ImageLibrary = null, BetterChat = null, ZoneManager = null, PlayerDatabase = null;
private const string Layer = "UI.Clans";
private const string ModalLayer = "UI.Clans.Modal";
private const string PermAdmin = "clans.admin";
private static Clans _instance;
private readonly List<ItemDefinition> _defaultItems = new List<ItemDefinition>();
private Coroutine _actionAvatars;
private Coroutine _actionConvert;
private Coroutine _handleTop;
private readonly Dictionary<uint, ulong> _looters = new Dictionary<uint, ulong>();
private const string COLORED_LABEL = "<color={0}>{1}</color>";
private Regex _tagFilter;
private Regex _hexFilter = new Regex("^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
#region Colors
private string Color1;
private string Color2;
private string Color3;
private string Color4;
private string Color5;
private string Color6;
#endregion
#endregion
#region Config
private static Configuration _config;
private class Configuration {
[JsonProperty(PropertyName = "Default Avatar")]
public string DefaultAvatar = "https://i.imgur.com/nn7Lcm2.png";
[JsonProperty(PropertyName = "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> Commands = new List<string> {
"clan", "clans"
}
;
[JsonProperty(PropertyName = "Clan Info Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] ClanInfoCommands = {
"cinfo"
}
;
[JsonProperty(PropertyName = "Maximum clan description characters")]
public int DescriptionMax = 256;
[JsonProperty(PropertyName = "Clan tag in player name")]
public bool TagInName = true;
[JsonProperty(PropertyName = "Automatic team creation")]
public bool AutoTeamCreation = true;
[JsonProperty(PropertyName = "Allow players to leave their clan by using Rust's leave team button")]
public bool ClanTeamLeave = true;
[JsonProperty(PropertyName = "Allow players to kick members from their clan using Rust's kick member button")]
public bool ClanTeamKick = true;
[JsonProperty(PropertyName = "Allow players to invite other players to their clan via Rust's team invite system")]
public bool ClanTeamInvite = true;
[JsonProperty(PropertyName = "Allow players to promote other clan members via Rust's team promote button")]
public bool ClanTeamPromote = true;
[JsonProperty(PropertyName = "Allow players to accept a clan invite using the Rust invite accept button")]
public bool ClanTeamAcceptInvite = true;
[JsonProperty(PropertyName = "Show clan creation interface when creating a team?")]
public bool ClanCreateTeam = false;
[JsonProperty(PropertyName = "Force to create a clan when creating a team?")]
public bool ForceClanCreateTeam = false;
[JsonProperty(PropertyName = "Use Friendly Fire?")]
public bool UseFriendlyFire = true;
[JsonProperty(PropertyName = "Use Friendly Fire for Turrets?")]
public bool UseTurretsFF = false;
[JsonProperty(PropertyName = "General friendly fire (only the leader of the clan can enable/disable it)")]
public bool GeneralFriendlyFire = false;
[JsonProperty(PropertyName = "Can moderators toggle general friendly fire?")]
public bool ModersGeneralFF = false;
[JsonProperty(PropertyName = "Can players toggle general friendly fire?")]
public bool PlayersGeneralFF = false;
[JsonProperty(PropertyName = "Friendly Fire Default Value")]
public bool FriendlyFire = false;
[JsonProperty(PropertyName = "Top refresh rate")]
public float TopRefreshRate = 15f;
[JsonProperty(PropertyName = "Default value for the resource standarts")]
public int DefaultValStandarts = 100000;
[JsonProperty(PropertyName = "Chat Settings")]
public ChatSettings ChatSettings = new ChatSettings {
Enabled = true, TagFormat = "<color=#{color}>[{tag}]</color>"
}
;
[JsonProperty(PropertyName = "Permission Settings")]
public PermissionSettings PermissionSettings = new PermissionSettings {
UseClanCreating = false, ClanCreating = "clans.cancreate", UseClanJoining = false, ClanJoining = "clans.canjoin", UseClanLeave = false, ClanLeave = "clans.canleave", UseClanDisband = false, ClanDisband = "clans.candisband", UseClanKick = false, ClanKick = "clans.cankick", UseClanSkins = false, ClanSkins = "clans.canskins", ClanInfoAuthLevel = 0
}
;
[JsonProperty(PropertyName = "Alliance Settings")]
public AllianceSettings AllianceSettings = new AllianceSettings {
Enabled = true, UseFF = true, DefaultFF = false
}
;
[JsonProperty(PropertyName = "Purge Settings")]
public PurgeSettings PurgeSettings = new PurgeSettings {
Enabled = true, OlderThanDays = 14, ListPurgedClans = true, WipeOnNewSave = false
}
;
[JsonProperty(PropertyName = "Limit Settings")]
public LimitSettings LimitSettings = new LimitSettings {
MemberLimit = 12, ModeratorLimit = 2, AlliancesLimit = 2
}
;
[JsonProperty(PropertyName = "Resources", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> Resources = new List<string> {
"stones", "sulfur.ore", "metal.ore", "hq.metal.ore", "wood"
}
;
[JsonProperty(PropertyName = "Score Table (shortname - score)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> ScoreTable = new Dictionary<string, float> {
["kills"]
= 1, ["deaths"] = -1, ["stone-ore"] = 0.1f, ["supply_drop"] = 3f, ["crate_normal"] = 0.3f, ["crate_elite"] = 0.5f, ["bradley_crate"] = 5f, ["heli_crate"] = 5f, ["bradley"] = 10f, ["helicopter"] = 15f, ["barrel"] = 0.1f, ["scientistnpc"] = 0.5f, ["heavyscientist"] = 2f, ["sulfur.ore"] = 0.5f, ["metal.ore"] = 0.5f, ["hq.metal.ore"] = 0.5f, ["stones"] = 0.5f, ["cupboard.tool.deployed"] = 1f
}
;
[JsonProperty(PropertyName = "Available items for resource standarts", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> AvailableStandartItems = new List<string> {
"gears", "metalblade", "metalpipe", "propanetank", "roadsigns", "rope", "sewingkit", "sheetmetal", "metalspring", "tarp", "techparts", "riflebody", "semibody", "smgbody", "fat.animal", "cctv.camera", "charcoal", "cloth", "crude.oil", "diesel_barrel", "gunpowder", "hq.metal.ore", "leather", "lowgradefuel", "metal.fragments", "metal.ore", "scrap", "stones", "sulfur.ore", "sulfur", "targeting.computer", "wood"
}
;
[JsonProperty(PropertyName = "Pages", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<PageSettings> Pages = new List<PageSettings> {
new PageSettings {
ID = 0, Key = "aboutclan", Enabled = true, Permission = string.Empty
}
, new PageSettings {
ID = 1, Key = "memberslist", Enabled = true, Permission = string.Empty
}
, new PageSettings {
ID = 2, Key = "clanstop", Enabled = true, Permission = string.Empty
}
, new PageSettings {
ID = 3, Key = "playerstop", Enabled = true, Permission = string.Empty
}
, new PageSettings {
ID = 4, Key = "resources", Enabled = true, Permission = string.Empty
}
, new PageSettings {
ID = 6, Key = "skins", Enabled = true, Permission = string.Empty
}
, new PageSettings {
ID = 5, Key = "playerslist", Enabled = true, Permission = string.Empty
}
, new PageSettings {
ID = 7, Key = "alianceslist", Enabled = true, Permission = string.Empty
}
}
;
[JsonProperty(PropertyName = "Interface")]
public InterfaceSettings UI = new InterfaceSettings {
Color1 = "#0E0E10", Color2 = "#4B68FF", Color3 = "#161617", Color4 = "#324192", Color5 = "#303030", Color6 = "#FF4B4B", ValueAbbreviation = true, TopClansColumns = new List<ColumnSettings> {
new ColumnSettings {
Width = 75, Key = "top", LangKey = TopTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 10, FontSize = 12, TextFormat = "#{0}"
}
, new ColumnSettings {
Width = 165, Key = "name", LangKey = NameTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
, new ColumnSettings {
Width = 70, Key = "leader", LangKey = LeaderTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
, new ColumnSettings {
Width = 90, Key = "members", LangKey = MembersTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
, new ColumnSettings {
Width = 80, Key = "score", LangKey = ScoreTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
}
, TopPlayersColumns = new List<ColumnSettings> {
new ColumnSettings {
Width = 75, Key = "top", LangKey = TopTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 10, FontSize = 12, TextFormat = "#{0}"
}
, new ColumnSettings {
Width = 185, Key = "name", LangKey = NameTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
, new ColumnSettings {
Width = 70, Key = "kills", LangKey = KillsTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
, new ColumnSettings {
Width = 70, Key = "resources", LangKey = ResourcesTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
, new ColumnSettings {
Width = 80, Key = "score", LangKey = ScoreTitle, TextAlign = TextAnchor.MiddleCenter, TitleFontSize = 12, FontSize = 12, TextFormat = "{0}"
}
}
, ProfileButtons = new List<BtnConf> {
new BtnConf {
Enabled = false, CloseMenu = true, AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "270 -55", OffsetMax = "360 -30", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 10, TextColor = new IColor("#FFFFFF", 100), Color = new IColor("#324192", 100), Title = "TP", Command = "tpr {target}"
}
, new BtnConf {
Enabled = false, CloseMenu = true, AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "370 -55", OffsetMax = "460 -30", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 10, TextColor = new IColor("#FFFFFF", 100), Color = new IColor("#324192", 100), Title = "TRADE", Command = "trade {target}"
}
}
}
;
[JsonProperty(PropertyName = "Skins Settings")]
public SkinsSettings Skins = new SkinsSettings {
ItemSkins = new Dictionary<string, List<ulong>> {
["metal.facemask"]
= new List<ulong>(), ["hoodie"] = new List<ulong>(), ["metal.plate.torso"] = new List<ulong>(), ["pants"] = new List<ulong>(), ["roadsign.kilt"] = new List<ulong>(), ["shoes.boots"] = new List<ulong>(), ["rifle.ak"] = new List<ulong>(), ["rifle.bolt"] = new List<ulong>()
}
, UseSkinBox = false, UsePlayerSkins = false, CanCustomSkin = true, Permission = string.Empty, DisableSkins = false, DefaultValueDisableSkins = true
}
;
[JsonProperty(PropertyName = "Statistics Settings")]
public StatisticsSettings Statistics = new StatisticsSettings {
Kills = true, Gather = true, Loot = true, Entities = true, Craft = true
}
;
[JsonProperty(PropertyName = "Colos Settings")]
public ColorsSettings Colors = new ColorsSettings {
Member = "#fcf5cb", Moderator = "#74c6ff", Owner = "#a1ff46"
}
;
[JsonProperty(PropertyName = "PlayerDatabase")]
public PlayerDatabaseConf PlayerDatabase = new PlayerDatabaseConf(false, "Clans");
[JsonProperty(PropertyName = "ZoneManager Settings")]
public ZoneManagerSettings ZMSettings = new ZoneManagerSettings {
Enabled = false, FFAllowlist = new List<string> {
"92457", "4587478545"
}
}
;
[JsonProperty(PropertyName = "Clan Tag Settings")]
public TagSettings Tags = new TagSettings {
TagMin = 2, TagMax = 6, BlockedWords = new List<string> {
"admin", "mod", "owner"
}
, CheckingCharacters = true, AllowedCharacters = "!²³", TagColor = new TagSettings.TagColorSettings {
Enabled = true, DefaultColor = "AAFF55", Owners = true, Moderators = false, Players = false
}
}
;
public VersionNumber Version;
}
private class TagSettings {
[JsonProperty(PropertyName = "Blocked Words", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> BlockedWords;
[JsonProperty(PropertyName = "Minimum clan tag characters")]
public int TagMin;
[JsonProperty(PropertyName = "Maximum clan tag characters")]
public int TagMax;
[JsonProperty(PropertyName = "Enable character checking in tags?")]
public bool CheckingCharacters;
[JsonProperty(PropertyName = "Special characters allowed in tags")]
public string AllowedCharacters;
[JsonProperty(PropertyName = "Tag Color Settings")]
public TagColorSettings TagColor;
public class TagColorSettings {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "DefaultColor")]
public string DefaultColor;
[JsonProperty(PropertyName = "Can the owner change the color?")]
public bool Owners;
[JsonProperty(PropertyName = "Can the moderators change the color?")]
public bool Moderators;
[JsonProperty(PropertyName = "Can the players change the color?")]
public bool Players;
}
}
private class ZoneManagerSettings {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Zones with allowed Friendly Fire", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> FFAllowlist;
}
private class ColorsSettings {
[JsonProperty(PropertyName = "Clan owner color (hex)")]
public string Owner;
[JsonProperty(PropertyName = "Clan moderator color (hex)")]
public string Moderator;
[JsonProperty(PropertyName = "Clan member color (hex)")]
public string Member;
}
private class PlayerDatabaseConf {
[JsonProperty(PropertyName = "Enabled")]
public readonly bool Enabled;
[JsonProperty(PropertyName = "Table")]
public readonly string Field;
public PlayerDatabaseConf(bool enabled, string field) {
Enabled = enabled;
Field = field;
}
}
private class StatisticsSettings {
[JsonProperty(PropertyName = "Kills")]
public bool Kills;
[JsonProperty(PropertyName = "Gather")]
public bool Gather;
[JsonProperty(PropertyName = "Loot")]
public bool Loot;
[JsonProperty(PropertyName = "Entities")]
public bool Entities;
[JsonProperty(PropertyName = "Craft")]
public bool Craft;
}
private class SkinsSettings {
[JsonProperty(PropertyName = "Item Skins", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, List<ulong>> ItemSkins;
[JsonProperty(PropertyName = "Use skins from SkinBox?")]
public bool UseSkinBox;
[JsonProperty(PropertyName = "Use skins from PlayerSkins?")]
public bool UsePlayerSkins;
[JsonProperty(PropertyName = "Can players install custom skins?")]
public bool CanCustomSkin;
[JsonProperty(PropertyName = "Permission to install custom skin")]
public string Permission;
[JsonProperty(PropertyName = "Option to disable clan skins?")]
public bool DisableSkins;
[JsonProperty(PropertyName = "Default value to disable skins")]
public bool DefaultValueDisableSkins;
}
private class InterfaceSettings {
[JsonProperty(PropertyName = "Color 1")]
public string Color1;
[JsonProperty(PropertyName = "Color 2")]
public string Color2;
[JsonProperty(PropertyName = "Color 3")]
public string Color3;
[JsonProperty(PropertyName = "Color 4")]
public string Color4;
[JsonProperty(PropertyName = "Color 5")]
public string Color5;
[JsonProperty(PropertyName = "Color 6")]
public string Color6;
[JsonProperty(PropertyName = "Use value abbreviation?")]
public bool ValueAbbreviation;
[JsonProperty(PropertyName = "Top Clans Columns", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ColumnSettings> TopClansColumns;
[JsonProperty(PropertyName = "Top Players Columns", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ColumnSettings> TopPlayersColumns;
[JsonProperty(PropertyName = "Profile Buttons", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<BtnConf> ProfileButtons;
}
private abstract class InterfacePosition {
public string AnchorMin;
public string AnchorMax;
public string OffsetMin;
public string OffsetMax;
}
private class BtnConf : InterfacePosition {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Close Menu?")]
public bool CloseMenu;
[JsonProperty(PropertyName = "Command")]
public string Command;
[JsonProperty(PropertyName = "Color")]
public IColor Color;
[JsonProperty(PropertyName = "Title")]
public string Title;
[JsonProperty(PropertyName = "Font Size")]
public int FontSize;
[JsonProperty(PropertyName = "Font")]
public string Font;
[JsonProperty(PropertyName = "Align")]
[JsonConverter(typeof(StringEnumConverter))]
public TextAnchor Align;
[JsonProperty(PropertyName = "Text Color")]
public IColor TextColor;
public void Get(ref CuiElementContainer container, ulong target, string parent, string close) {
if (!Enabled) return;
container.Add(new CuiButton {
RectTransform = {
AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = OffsetMin, OffsetMax = OffsetMax
}
, Text = {
Text = $"{Title}", Align = Align, Font = Font, FontSize = FontSize, Color = TextColor.Get()
}
, Button = {
Command = $"clans.sendcmd {Command.Replace(" {
target
}
", target.ToString())}", Color = Color.Get(), Close = CloseMenu ? close : string.Empty
}
}
, parent);
}
}
private class ColumnSettings {
[JsonProperty(PropertyName = "Width")]
public float Width;
[JsonProperty(PropertyName = "Lang Key")]
public string LangKey;
[JsonProperty(PropertyName = "Key")]
public string Key;
[JsonProperty(PropertyName = "Text Format")]
public string TextFormat;
[JsonProperty(PropertyName = "Text Align")]
[JsonConverter(typeof(StringEnumConverter))]
public TextAnchor TextAlign;
[JsonProperty(PropertyName = "Title Font Size")]
public int TitleFontSize;
[JsonProperty(PropertyName = "Font Size")]
public int FontSize;
public string GetKey(int top, string values) {
switch (Key) {
case "top" : return string.Format(TextFormat, top);
default : return string.Format(TextFormat, values);
}
}
}
private class IColor {
[JsonProperty(PropertyName = "HEX")]
public string Hex;
[JsonProperty(PropertyName = "Opacity (0 - 100)")]
public readonly float Alpha;
public string Get() {
if (string.IsNullOrEmpty(Hex)) Hex = "#FFFFFF";
var str = Hex.Trim('#');
if (str.Length != 6) throw new Exception(Hex);
var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
}
public IColor(string hex, float alpha) {
Hex = hex;
Alpha = alpha;
}
}
private class PageSettings {
[JsonProperty(PropertyName = "ID (DON'T CHANGE)")]
public int ID;
[JsonProperty(PropertyName = "Key (DON'T CHANGE)")]
public string Key;
[JsonProperty(PropertyName = "Enabled?")]
public bool Enabled;
[JsonProperty(PropertyName = "Permission")]
public string Permission;
}
private class LimitSettings {
[JsonProperty(PropertyName = "Member Limit")]
public int MemberLimit;
[JsonProperty(PropertyName = "Moderator Limit")]
public int ModeratorLimit;
[JsonProperty(PropertyName = "Alliances Limit")]
public int AlliancesLimit;
}
private class PurgeSettings {
[JsonProperty(PropertyName = "Enable clan purging")]
public bool Enabled;
[JsonProperty(PropertyName = "Purge clans that havent been online for x amount of day")]
public int OlderThanDays;
[JsonProperty(PropertyName = "List purged clans in console when purging")]
public bool ListPurgedClans;
[JsonProperty(PropertyName = "Wipe clans on new map save")]
public bool WipeOnNewSave;
}
private class ChatSettings {
[JsonProperty(PropertyName = "Enable clan tags in chat?")]
public bool Enabled;
[JsonProperty(PropertyName = "Tag format")]
public string TagFormat;
}
private class PermissionSettings {
[JsonProperty(PropertyName = "Use permission to create a clan")]
public bool UseClanCreating;
[JsonProperty(PropertyName = "Permission to create a clan")]
public string ClanCreating;
[JsonProperty(PropertyName = "Use permission to join a clan")]
public bool UseClanJoining;
[JsonProperty(PropertyName = "Permission to join a clan")]
public string ClanJoining;
[JsonProperty(PropertyName = "Use permission to kick a clan member")]
public bool UseClanKick;
[JsonProperty(PropertyName = "Clan kick permission")]
public string ClanKick;
[JsonProperty(PropertyName = "Use permission to leave a clan")]
public bool UseClanLeave;
[JsonProperty(PropertyName = "Clan leave permission")]
public string ClanLeave;
[JsonProperty(PropertyName = "Use permission to disband a clan")]
public bool UseClanDisband;
[JsonProperty(PropertyName = "Clan disband permission")]
public string ClanDisband;
[JsonProperty(PropertyName = "Use permission to clan skins")]
public bool UseClanSkins;
[JsonProperty(PropertyName = "Use clan skins permission")]
public string ClanSkins;
[JsonProperty(PropertyName = "Minimum auth level required to view clan info (0 = player, 1 = moderator, 2 = owner)")]
public int ClanInfoAuthLevel;
}
private class AllianceSettings {
[JsonProperty(PropertyName = "Enable clan alliances")]
public bool Enabled;
[JsonProperty(PropertyName = "Enable friendly fire (allied clans)")]
public bool UseFF;
[JsonProperty(PropertyName = "Default friendly fire value")]
public bool DefaultFF;
[JsonProperty(PropertyName = "General friendly fire (only the leader of the clan can enable/disable it)")]
public readonly bool GeneralFriendlyFire = false;
[JsonProperty(PropertyName = "Can moderators toggle general friendly fire?")]
public readonly bool ModersGeneralFF = false;
[JsonProperty(PropertyName = "Can players toggle general friendly fire?")]
public readonly bool PlayersGeneralFF = false;
}
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
if (_config.Version < Version) UpdateConfigValues();
SaveConfig();
}
catch (Exception ex) {
PrintError($"Your configuration file contains an error. Using default configuration values.\n{ex}");
LoadDefaultConfig();
}
}
private void UpdateConfigValues() {
PrintWarning("Config update detected! Updating config values...");
var baseConfig = new Configuration();
if (_config.Version < new VersionNumber(1, 0, 15)) {
_config.Skins.DisableSkins = baseConfig.Skins.DisableSkins;
_config.Skins.DefaultValueDisableSkins = baseConfig.Skins.DefaultValueDisableSkins;
_config.PermissionSettings.UseClanSkins = baseConfig.PermissionSettings.UseClanSkins;
_config.PermissionSettings.ClanSkins = baseConfig.PermissionSettings.ClanSkins;
}
if (_config.Version < new VersionNumber(1, 1, 0)) StartConvertOldData();
_config.Version = Version;
PrintWarning("Config update completed!");
}
protected override void SaveConfig() {
Config.WriteObject(_config);
}
protected override void LoadDefaultConfig() {
_config = new Configuration();
}
#endregion
#region Data
private List<ClanData> _clansList = new List<ClanData>();
private void SaveClans() {
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/ClansList", _clansList);
}
private void LoadClans() {
try {
_clansList = Interface.Oxide.DataFileSystem.ReadObject<List<ClanData>>($"{Name}/ClansList");
}
catch (Exception e) {
PrintError(e.ToString());
}
if (_clansList == null) _clansList = new List<ClanData>();
}
private class InviteData {
[JsonProperty(PropertyName = "Inviter Name")]
public string InviterName;
[JsonProperty(PropertyName = "Inviter Id")]
public ulong InviterId;
}
private class ClanData {
[JsonProperty(PropertyName = "Clan Tag")]
public string ClanTag;
[JsonProperty(PropertyName = "Tag Color")]
public string TagColor;
[JsonProperty(PropertyName = "Avatar")]
public string Avatar;
[JsonProperty(PropertyName = "Leader ID")]
public ulong LeaderID;
[JsonProperty(PropertyName = "Leader Name")]
public string LeaderName;
[JsonProperty(PropertyName = "Description")]
public string Description;
[JsonProperty(PropertyName = "Creation Time")]
public DateTime CreationTime;
[JsonProperty(PropertyName = "Last Online Time")]
public DateTime LastOnlineTime;
[JsonProperty(PropertyName = "Friendly Fire")]
public bool FriendlyFire;
[JsonProperty(PropertyName = "Ally Friendly Fire")]
public bool AllyFriendlyFire;
[JsonProperty(PropertyName = "Moderators", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ulong> Moderators = new List<ulong>();
[JsonProperty(PropertyName = "Members", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ulong> Members = new List<ulong>();
[JsonProperty(PropertyName = "Invited Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<ulong, ulong> InvitedPlayers = new Dictionary<ulong, ulong>();
[JsonProperty(PropertyName = "Resource Standarts", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<int, ResourceStandart> ResourceStandarts = new Dictionary<int, ResourceStandart>();
[JsonProperty(PropertyName = "Skins", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<string, ulong> Skins = new Dictionary<string, ulong>();
[JsonProperty(PropertyName = "Alliances", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<string> Alliances = new List<string>();
[JsonProperty(PropertyName = "Alliance Invites", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<string, ulong> AllianceInvites = new Dictionary<string, ulong>();
[JsonProperty(PropertyName = "Incoming Alliances", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<string> IncomingAlliances = new List<string>();
[JsonProperty(PropertyName = "Team ID")]
public ulong TeamID;
[JsonIgnore]
public int Top;
[JsonIgnore]
private RelationshipManager.PlayerTeam Team => RelationshipManager.ServerInstance.FindTeam(TeamID) ?? FindOrCreateTeam();
#region Info
public bool IsOwner(string userId) {
return IsOwner(ulong.Parse(userId));
}
public bool IsOwner(ulong userId) {
return LeaderID == userId;
}
public bool IsModerator(string userId) {
return IsModerator(ulong.Parse(userId));
}
public bool IsModerator(ulong userId) {
return Moderators.Contains(userId) || IsOwner(userId);
}
public bool IsMember(string userId) {
return IsMember(ulong.Parse(userId));
}
public bool IsMember(ulong userId) {
return Members.Contains(userId);
}
public string GetRoleColor(ulong userId) {
return IsOwner(userId) ? _config.Colors.Owner : IsModerator(userId) ? _config.Colors.Moderator : _config.Colors.Member;
}
public string GetHexTagColor() {
return string.IsNullOrEmpty(TagColor) ? _config.Tags.TagColor.DefaultColor : TagColor;
}
public bool CanEditTagColor(ulong userId) {
if (_config.Tags.TagColor.Owners) if (IsOwner(userId)) return true;
if (_config.Tags.TagColor.Moderators) if (IsModerator(userId)) return true;
if (_config.Tags.TagColor.Players) if (IsMember(userId)) return true;
return false;
}
#endregion
#region Create
public static ClanData CreateNewClan(string clanTag, BasePlayer leader) {
var clan = new ClanData {
ClanTag = clanTag, LeaderID = leader.userID, LeaderName = leader.displayName, Avatar = _config.DefaultAvatar, Members = new List<ulong> {
leader.userID
}
, CreationTime = DateTime.Now, LastOnlineTime = DateTime.Now, Top = _instance.TopClans.Count + 1
}
;
#region Invites
PlayerData.GetOrLoad(leader.UserIDString)?.Invites.Clear();
_instance._clansList.ForEach(x => x.InvitedPlayers.Remove(leader.userID));
#endregion
_instance._clansList.Add(clan);
if (_config.TagInName) leader.displayName = $"[{clanTag}] {_instance.GetPlayerName(leader)}";
if (_config.AutoTeamCreation) clan.FindOrCreateTeam();
ClanCreate(clanTag);
_instance.NextTick(() => _instance.HandleTop());
return clan;
}
#endregion
#region Main
public void Rename(string newName) {
if (string.IsNullOrEmpty(newName)) return;
var oldName = ClanTag;
ClanTag = newName;
foreach (var check in AllianceInvites) {
var clan = _instance.FindClanByTag(check.Key);
if (clan != null) {
clan.IncomingAlliances.Remove(oldName);
clan.IncomingAlliances.Add(newName);
}
}
foreach (var check in Alliances) {
var clan = _instance.FindClanByTag(check);
if (clan != null) {
clan.Alliances.Remove(oldName);
clan.Alliances.Add(newName);
}
}
foreach (var check in InvitedPlayers) {
var data = PlayerData.GetOrCreate(check.Key.ToString());
if (data != null) {
InviteData inviteData;
if (data.Invites.TryGetValue(ClanTag, out inviteData)) {
data.Invites.Remove(oldName);
data.Invites.Add(newName, inviteData);
}
}
}
foreach (var player in Players) _instance?.OnPlayerConnected(player);
ClanUpdate(ClanTag);
}
public void Disband() {
var memberUserIDs = Members.Select(x => x.ToString());
ClanDisbanded(memberUserIDs);
ClanDisbanded(ClanTag, memberUserIDs);
Members.ToList().ForEach(member => Kick(member, true));
ClanDestroy(ClanTag);
_instance?._clansList.ForEach(clan => {
clan.Alliances.Remove(ClanTag);
clan.AllianceInvites.Remove(ClanTag);
clan.IncomingAlliances.Remove(ClanTag);
}
);
if (_config.AutoTeamCreation) Team?.members.ToList().ForEach(member => {
Team.RemovePlayer(member);
var player = RelationshipManager.FindByID(member);
if (player != null) player.ClearTeam();
}
);
_instance?._clansList.Remove(this);
_instance?.NextTick(() => _instance.HandleTop());
}
public void Join(BasePlayer player) {
Members.Add(player.userID);
if (_config.TagInName) player.displayName = $"[{ClanTag}] {player.displayName}";
if (_config.AutoTeamCreation) {
player.Team?.RemovePlayer(player.userID);
Team?.AddPlayer(player);
}
if (Members.Count >= _config.LimitSettings.MemberLimit) {
InvitedPlayers.Clear();
PlayerData.StartAll(data => data.Invites.Remove(ClanTag));
}
_instance._clansList.ForEach(x => x.InvitedPlayers.Remove(player.userID));
PlayerData.GetOrCreate(player.UserIDString)?.Invites.Clear();
ClanMemberJoined(player.UserIDString, ClanTag);
ClanMemberJoined(player.UserIDString, Members.Select(x => x.ToString()));
ClanUpdate(ClanTag);
}
public void Kick(ulong target, bool disband = false) {
Members.Remove(target);
Moderators.Remove(target);
if (_config.TagInName) {
var data = PlayerData.GetOrCreate(target.ToString());
if (data == null) return;
var player = BasePlayer.FindByID(target);
if (player != null) player.displayName = data.DisplayName;
}
if (!disband) {
if (_config.AutoTeamCreation && Team != null) Team.RemovePlayer(target);
if (Members.Count == 0) {
Disband();
}
else {
if (LeaderID == target) SetLeader((Moderators.Count > 0 ? Moderators : Members).GetRandom());
}
}
ClanMemberGone(target.ToString(), Members.Select(x => x.ToString()));
ClanMemberGone(target.ToString(), ClanTag);
ClanUpdate(ClanTag);
}
public void SetModer(ulong target) {
if (!Moderators.Contains(target)) Moderators.Add(target);
ClanUpdate(ClanTag);
}
public void UndoModer(ulong target) {
Moderators.Remove(target);
ClanUpdate(ClanTag);
}
public void SetLeader(ulong target) {
var data = PlayerData.GetOrLoad(target.ToString());
if (data != null) LeaderName = data.DisplayName;
LeaderID = target;
if (_config.AutoTeamCreation) Team.SetTeamLeader(target);
ClanUpdate(ClanTag);
}
#endregion
#region Additionall
public RelationshipManager.PlayerTeam FindOrCreateTeam() {
var leaderTeam = RelationshipManager.ServerInstance.FindPlayersTeam(LeaderID);
if (leaderTeam != null) {
if (leaderTeam.teamLeader == LeaderID) {
TeamID = leaderTeam.teamID;
return leaderTeam;
}
leaderTeam.RemovePlayer(LeaderID);
}
return CreateTeam();
}
public RelationshipManager.PlayerTeam CreateTeam() {
var team = RelationshipManager.ServerInstance.CreateTeam();
team.teamLeader = LeaderID;
AddPlayer(LeaderID, team);
TeamID = team.teamID;
return team;
}
public void AddPlayer(ulong member, RelationshipManager.PlayerTeam team = null) {
if (team == null) team = Team;
if (!team.members.Contains(member)) team.members.Add(member);
if (member == LeaderID) team.teamLeader = LeaderID;
RelationshipManager.ServerInstance.playerToTeam[member] = team;
var player = RelationshipManager.FindByID(member);
if (player != null) {
if (player.Team != null && player.Team.teamID != team.teamID) {
player.Team.RemovePlayer(player.userID);
player.ClearTeam();
}
player.currentTeam = team.teamID;
team.MarkDirty();
player.SendNetworkUpdate();
}
}
public float Score() {
return Members.Sum(member => PlayerData.GetNotLoad(member.ToString())?.Score ?? 0f);
}
public string Scores() {
return GetValue(Score());
}
public float GetTotalFarm() {
return (float) Math.Round(Members.Sum(member => PlayerData.GetOrLoad(member.ToString()).GetTotalFarm(this)) / Members.Count, 3);
}
public JObject ToJObject() {
return new JObject {
["tag"]
= ClanTag, ["description"] = Description, ["owner"] = LeaderID, ["moderators"] = new JArray(Moderators), ["members"] = new JArray(Members), ["invitedallies"] = new JArray(InvitedPlayers.Keys.ToList().Select(x => x.ToString()))
}
;
}
public void SetSkin(string shortName, ulong skin) {
Skins[shortName] = skin;
foreach (var player in Players.Where(x => _instance.CanUseSkins(x))) foreach (var item in player.inventory.AllItems()) if (item.info.shortname == shortName) ApplySkinToItem(item, skin);
}
public string GetParams(string value) {
switch (value) {
case "name" : return ClanTag;
case "leader" : return LeaderName;
case "members" : return Members.Count.ToString();
case "score" : return Scores();
default : return Math.Round(Members.Sum(member => PlayerData.GetNotLoad(member.ToString())?.GetValue(value) ?? 0f)) .ToString(CultureInfo.InvariantCulture);
}
}
#endregion
#region Utils
[JsonIgnore]
public IEnumerable<BasePlayer> Players {
get {
return Members.Select(BasePlayer.FindByID).Where(player => player != null);
}
}
public void Broadcast(string key, params object[] obj) {
foreach (var player in Players) _instance.Reply(player, key, obj);
}
#endregion
#region Clan Info
public string GetClanInfo(BasePlayer player) {
var str = new StringBuilder();
str.Append(_instance.Msg(player, ClanInfoTitle));
str.Append(_instance.Msg(player, ClanInfoTag, ClanTag));
if (!string.IsNullOrEmpty(Description)) str.Append(_instance.Msg(player, ClanInfoDescription, Description));
var online = Pool.GetList<string>();
var offline = Pool.GetList<string>();
foreach (var kvp in Members) {
var member = string.Format(COLORED_LABEL, GetRoleColor(kvp), PlayerData.GetOrLoad(kvp.ToString()).DisplayName);
if (IsOnline(kvp)) online.Add(member);
else offline.Add(member);
}
if (online.Count > 0) str.Append(_instance.Msg(player, ClanInfoOnline, online.ToSentence()));
if (offline.Count > 0) str.Append(_instance.Msg(player, ClanInfoOffline, offline.ToSentence()));
Pool.FreeList(ref online);
Pool.FreeList(ref offline);
str.Append(_instance.Msg(player, ClanInfoEstablished, CreationTime));
str.Append(_instance.Msg(player, ClanInfoLastOnline, LastOnlineTime));
if (_config.AllianceSettings.Enabled) str.Append(_instance.Msg(player, ClanInfoAlliances, Alliances.Count > 0 ? Alliances.ToSentence() : _instance.Msg(player, ClanInfoAlliancesNone)));
return str.ToString();
}
#endregion
}
private class ResourceStandart {
public string ShortName;
public int Amount;
[JsonIgnore]
private int _itemId = -1;
[JsonIgnore]
public int itemId {
get {
if (_itemId == -1) _itemId = ItemManager.FindItemDefinition(ShortName)?.itemid ?? -1;
return _itemId;
}
}
// ... [Code preview truncated due to length. Full source in attached file] ...