C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Facepunch;
using Newtonsoft.Json;
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 ProtoBuf;
using Rust;
using UnityEngine;
namespace Oxide.Plugins {
[Info("Clan", "deity", "1.1.1")]
public class Clan : RustPlugin {
#region Variables
[PluginReference]
private Plugin ImageLibrary = null, TournamentClan = null;
private string[] _gatherHooks = {
"OnDispenserGather", "OnDispenserBonus",
}
;
private static Clan Instance;
public List<ulong> playerActive = new List<ulong>();
private static FieldInfo hookSubscriptions = typeof(PluginManager).GetField("hookSubscriptions", (BindingFlags.Instance | BindingFlags.NonPublic));
private List<ulong> _lootEntity = new List<ulong>();
private Dictionary<string, int> ItemID = new Dictionary<string, int>();
private const string Layer = "UI_LayerClan";
#endregion
#region Data
public List<ClanData> _clanList = new List<ClanData>();
public class ClanData {
#region Member
public class MemberData {
public int MemberScores = 0;
public int MemberKill = 0;
public int MemberDeath = 0;
public bool MemberFriendlyFire = false;
public float AliveTime;
public string LastTime;
public Dictionary<string, int> GatherMember = new Dictionary<string, int>();
}
#endregion
#region Gather
public class GatherData {
public int TotalFarm;
public int Need;
}
#endregion
#region Variables
public string ClanTag;
public string ImageAvatar;
public ulong LeaderUlongID;
public string Task;
public int TotalScores;
public ulong TeamIDCreate;
// 1.1.1
public int Turret;
public int SamSite;
public int Cupboard;
//
public Dictionary<ulong, MemberData> Members = new Dictionary<ulong, MemberData>();
public Dictionary<string, ulong> ItemList = new Dictionary<string, ulong>();
public Dictionary<string, GatherData> GatherList = new Dictionary<string, GatherData>();
public List<ulong> Moderators = new List<ulong>();
public List<ulong> PendingInvites = new List<ulong>();
[JsonIgnore]
private RelationshipManager.PlayerTeam Team => RelationshipManager.ServerInstance.FindTeam(TeamIDCreate) ?? FindOrCreateTeam();
#endregion
#region ClanTeam
public RelationshipManager.PlayerTeam FindOrCreateTeam() {
var leaderTeam = RelationshipManager.ServerInstance.FindPlayersTeam(LeaderUlongID);
if (leaderTeam != null) {
if (leaderTeam.teamLeader == LeaderUlongID) if (leaderTeam.teamLeader == LeaderUlongID) {
TeamIDCreate = leaderTeam.teamID;
return leaderTeam;
}
leaderTeam.RemovePlayer(LeaderUlongID);
}
return CreateTeam();
}
private RelationshipManager.PlayerTeam CreateTeam() {
var team = RelationshipManager.ServerInstance.CreateTeam();
team.teamLeader = LeaderUlongID;
AddPlayer(LeaderUlongID, team);
TeamIDCreate = 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 == LeaderUlongID) team.teamLeader = LeaderUlongID;
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();
}
}
#endregion
#region AddPlayer
public void InvitePlayer(BasePlayer player) {
Members.Add(player.userID, new MemberData {
GatherMember = config.Main.GatherDictionary.ToDictionary(x => x, p => 0),
}
);
if (config.Main.EnableTeam) {
if (player.Team != null) player.Team.RemovePlayer(player.userID);
if (Team != null) Team.AddPlayer(player);
}
if (config.Main.TagInPlayer) player.displayName = $"[{ClanTag}] {player.displayName}";
PendingInvites.Remove(player.userID);
Interface.CallHook("OnClanUpdate", ClanTag, Members.Keys.ToList());
}
#endregion
#region RemovePlayer
public void RemovePlayerInClan(ulong player) {
Members.Remove(player);
if (Moderators.Contains(player)) Moderators.Remove(player);
if (config.Main.TagInPlayer) {
var target = BasePlayer.Find(player.ToString());
if (target != null) target.displayName = target.IPlayer.Name;
}
if (config.Main.EnableTeam) {
if (Team != null) Team.RemovePlayer(player);
}
Interface.CallHook("OnClanUpdate", ClanTag, Members.Keys.ToList());
}
#endregion
#region Disband
public void Disband() {
Interface.CallHook("OnClanDestroy", ClanTag);
var listMember = Members.Keys.ToList();
listMember.ForEach(p => RemovePlayerInClan(p));
Instance._clanList.Remove(this);
}
#endregion
#region SetOwner
public void SetOwner(ulong playerID) {
Interface.CallHook("OnClanOwnerChanged", ClanTag, LeaderUlongID, playerID);
LeaderUlongID = playerID;
ImageAvatar = $"avatar_{playerID}";
if (config.Main.EnableTeam && Team != null) Team.SetTeamLeader(playerID);
}
#endregion
#region Functional Info
public bool IsOwner(ulong playerID) => LeaderUlongID == playerID;
public bool IsModerator(ulong playerID) => Moderators.Contains(playerID) || IsOwner(playerID);
public bool IsMember(ulong playerID) => Members.ContainsKey(playerID);
#endregion
#region Gather
public void ProcessingGather(BasePlayer player, Item item, bool bonus = false) {
if (!GatherList.ContainsKey(item.info.shortname)) return;
var getGather = GatherList[item.info.shortname];
if (getGather.TotalFarm < getGather.Need) {
getGather.TotalFarm += item.amount;
if (getGather.TotalFarm > getGather.Need) getGather.TotalFarm = getGather.Need;
}
if (!Members[player.userID].GatherMember.ContainsKey(item.info.shortname)) Members[player.userID].GatherMember.Add(item.info.shortname, item.amount);
else Members[player.userID].GatherMember[item.info.shortname] += item.amount;
if (bonus) {
int ScoresGive;
if (config.Point._gatherPoint.TryGetValue(item.info.shortname, out ScoresGive)) {
TotalScores += ScoresGive;
Members[player.userID].MemberScores += ScoresGive;
}
}
}
#endregion
#region GiveScores
public void GiveScores(BasePlayer player, int scores) {
TotalScores += scores;
Members[player.userID].MemberScores += scores;
}
#endregion
#region FF
public void ChangeFriendlyFire(BasePlayer player) {
var memberData = Members[player.userID];
if (memberData.MemberFriendlyFire == true) memberData.MemberFriendlyFire = false;
else memberData.MemberFriendlyFire = true;
}
public bool GetValueFriendlyFire(BasePlayer player) => Members[player.userID].MemberFriendlyFire;
#endregion
#region Information
[JsonIgnore]
public Dictionary<string, string> GetInformation {
get {
return new Dictionary<string, string> {
["НАЗВАНИЕ КЛАНА:"]
= ClanTag, ["ГЛАВА КЛАНА:"] = Instance.covalence.Players.FindPlayer(LeaderUlongID.ToString()).Name.ToUpper(), ["УЧАСТНИКОВ В ИГРЕ:"] = $"{Members.Keys.Select(p => BasePlayer.Find(p.ToString()) != null).Count()} ИЗ {Members.Count}", ["ОБЩЕЕ КОЛИЧЕСТВО ОЧКОВ:"] = $"{TotalScores}",
}
;
}
}
[JsonIgnore]
public Dictionary<string, string> GetInformationInfo {
get {
int totalPercent = GatherList.Sum(p => p.Value.TotalFarm) * 100 / GatherList.Sum(p => p.Value.Need > 0 ? p.Value.Need : 1);
if (totalPercent > 100) totalPercent = 100;
return new Dictionary<string, string> {
["ГЛАВА КЛАНА:"]
= Instance.covalence.Players.FindPlayer(LeaderUlongID.ToString()).Name, ["ИГРОКОВ В КЛАНЕ:"] = $"{Members.Count}", ["НАБРАНО ОЧКОВ:"] = $"{TotalScores}", ["ОБЩАЯ АКТИВНОСТЬ:"] = $"{totalPercent}%", ["ВСЕГО УБИЙСТВ:"] = $"{Members.Sum(p => p.Value.MemberKill)}", ["ВСЕГО СМЕРТЕЙ:"] = $"{Members.Sum(p => p.Value.MemberDeath)}",
}
;
}
}
public int TotalAmountFarm(ulong playerID) => Members[playerID].GatherMember.Sum(p => p.Value) * 100 / GatherList.Sum(p => p.Value.Need > 0 ? p.Value.Need : 1);
#endregion
#region JObject
internal JObject ToJObject() {
var obj = new JObject();
obj["tag"] = ClanTag;
obj["owner"] = LeaderUlongID;
var jmoderators = new JArray();
foreach (var moderator in Moderators) jmoderators.Add(moderator);
obj["moderators"] = jmoderators;
var jmembers = new JArray();
foreach (var member in Members) jmembers.Add(member.Key);
obj["members"] = jmembers;
return obj;
}
#endregion
}
#endregion
#region Hooks
#region Loaded
private void OnPluginLoaded(Plugin plugin) {
if (plugin.Title == "Better Chat" || plugin.Title == "ChatPlus") {
Interface.CallHook("API_RegisterThirdPartyTitle", this, new Func<IPlayer, string>(getFormattedClanTag));
}
NextTick(() => {
foreach (string hook in _gatherHooks) {
Unsubscribe(hook);
Subscribe(hook);
}
}
);
}
#endregion
#region Initialized
void OnServerInitialized() {
Instance = this;
LoadData();
SubscribeInternalHook("IOnBasePlayerHurt");
AddCovalenceCommand(config.Main.CommandsMain.ToArray(), nameof(ClanCmd));
AddCovalenceCommand(config.Main.CommandsTOP.ToArray(), nameof(ClanTopCmd));
LoadMessages();
if (!config.Stats.Gather) {
Unsubscribe(nameof(OnDispenserGather));
Unsubscribe(nameof(OnDispenserBonus));
}
if (!config.Stats.Entities && !config.Limit.EnableLimit) Unsubscribe(nameof(OnEntityDeath));
if (!config.Stats.Loot) Unsubscribe(nameof(OnLootEntity));
// Edited: 1.1.1
if (!config.Main.AutomaticCupboard && !config.Limit.EnableLimit) Unsubscribe(nameof(OnEntityBuilt));
if (!config.Main.AutomaticLock) Unsubscribe(nameof(CanUseLockedEntity));
if (!config.Main.AutomaticTurret) Unsubscribe(nameof(OnTurretTarget));
ImageLibrary?.Call("AddImage", "https://i.imgur.com/J5l4FWq.png", "lootbox");
foreach (var key in ItemManager.GetItemDefinitions()) {
if (ItemID.ContainsKey(key.shortname)) continue;
ItemID.Add(key.shortname, key.itemid);
}
foreach (var player in BasePlayer.activePlayerList) OnPlayerConnected(player);
if (config.ItemSkin.LoadSkinList) GenerateSkinList();
}
#endregion
#region Unload
void Unload() {
foreach (var tPlayer in BasePlayer.activePlayerList) {
OnPlayerDisconnected(tPlayer);
}
Interface.GetMod().DataFileSystem.WriteObject(Name, _clanList);
Instance = null;
config = null;
}
#endregion
#region Wipe
void OnNewSave() {
LoadData();
// Даем время на инициализацию даты-файла
timer.Once(3, () => {
if (config.Prize.EnablePrize) {
if (config.Prize.GSSettings.SecretKey == "UNDEFINED" || config.Prize.GSSettings.ShopID == "UNDEFINED") return;
int index = 1;
foreach (var clan in _clanList.OrderByDescending(p => p.TotalScores)) {
uint amount = 0;
if (config.Prize.RewardDictionary.TryGetValue(index, out amount)) {
foreach (var clanMember in clan.Members) {
Request($"&action=moneys&type=plus&steam_id={clanMember.Key}&amount={amount}", null);
}
}
index++;
}
}
if (!config.Main.ClearWipe) return;
_clanList.Clear();
Interface.GetMod().DataFileSystem.WriteObject(Name, _clanList);
}
);
}
#endregion
#region ServerSave
void OnServerSave() => timer.Once(5, () => Interface.GetMod().DataFileSystem.WriteObject(Name, _clanList));
#endregion
#region PlayerConnected
void OnPlayerConnected(BasePlayer player) {
var clan = FindClanByUser(player.userID);
if (clan != null) {
if (config.Main.TagInPlayer) player.displayName = $"[{clan.ClanTag}] {GetNamePlayer(player)}";
if (config.Main.EnableTeam) clan.AddPlayer(player.userID);
clan.Members[player.userID].LastTime = $"{DateTime.Now.ToString("t")} {DateTime.Now.Day}/{DateTime.Now.Month}/{DateTime.Now.Year}";
player.SendNetworkUpdateImmediate();
}
GetAvatar(player.userID, avatar => ImageLibrary?.Call("AddImage", avatar, $"avatar_{player.UserIDString}"));
}
#endregion
#region PlayerDisconnected
void OnPlayerDisconnected(BasePlayer player) {
if (playerActive.Contains(player.userID)) playerActive.Remove(player.userID);
var clan = FindClanByUser(player.userID);
if (clan != null) {
if (config.Main.TagInPlayer) player.displayName = player.IPlayer.Name;
}
}
#endregion
#region Gather
void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item) {
BasePlayer player = entity.ToPlayer();
if (player == null) return;
FindClanByUser(player.userID)?.ProcessingGather(player, item);
}
void OnDispenserBonus(ResourceDispenser disp, BasePlayer player, Item item) {
if (player == null) return;
FindClanByUser(player.userID)?.ProcessingGather(player, item, true);
}
#endregion
#region Limit
void OnEntityDeath(BaseCombatEntity entity, HitInfo info) {
if (entity == null) return;
if (info == null) return;
if (entity.OwnerID == 0) return;
if (!(entity as AutoTurret) || !(entity as BuildingPrivlidge) || !(entity as SamSite)) return;
var findEntityClan = FindClanByUser(entity.OwnerID);
if (findEntityClan == null) return;
if (entity as AutoTurret) {
findEntityClan.Turret--;
}
else if (entity as BuildingPrivlidge) {
findEntityClan.Cupboard--;
}
else if (entity as SamSite) {
findEntityClan.SamSite--;
}
}
#endregion
#region BradleyAPC
void OnEntityDeath(BradleyAPC entity, HitInfo info) {
if (entity == null) return;
if (info == null) return;
if (info.InitiatorPlayer == null) return;
var player = info.InitiatorPlayer;
var clan = FindClanByUser(player.userID);
if (clan == null) return;
clan.GiveScores(player, config.Point.BradleyAPC);
}
#endregion
#region Helicopter
private readonly Dictionary<ulong, BasePlayer> _lastHeli = new Dictionary<ulong, BasePlayer>();
private void OnEntityTakeDamage(BaseHelicopter entity, HitInfo info) {
if (entity == null) return;
if (info == null) return;
if (info.InitiatorPlayer == null) return;
_lastHeli[entity.net.ID.Value] = info.InitiatorPlayer;
}
void OnEntityDeath(BaseHelicopter entity, HitInfo info) {
if (entity == null) return;
if (info == null) return;
if (_lastHeli.ContainsKey(entity.net.ID.Value)) {
var basePlayer = _lastHeli[entity.net.ID.Value];
if (basePlayer != null) {
var clan = FindClanByUser(basePlayer.userID);
if (clan == null) return;
clan.GiveScores(basePlayer, config.Point.Helicopter);
}
}
}
#endregion
#region Barrel
private void OnEntityDeath(LootContainer entity, HitInfo info) {
if (entity == null) return;
if (info == null) return;
if (!entity.ShortPrefabName.Contains("barrel")) return;
if (!config.Point._gatherPoint.ContainsKey("lootbox")) return;
if (info.InitiatorPlayer == null) return;
var player = info.InitiatorPlayer;
var clan = FindClanByUser(player.userID);
if (clan == null) return;
clan.GiveScores(player, config.Point._gatherPoint["lootbox"]);
clan.GatherList["lootbox"].TotalFarm++;
clan.Members[player.userID].GatherMember["lootbox"]++;
}
#endregion
#region Loot
private void OnLootEntity(BasePlayer player, LootContainer entity) {
if (player == null || entity == null) return;
if (_lootEntity.Contains(entity.net.ID.Value)) return;
if (!config.Point._gatherPoint.ContainsKey("lootbox")) return;
var clan = FindClanByUser(player.userID);
if (clan == null) return;
clan.GiveScores(player, config.Point._gatherPoint["lootbox"]);
clan.GatherList["lootbox"].TotalFarm++;
clan.Members[player.userID].GatherMember["lootbox"]++;
_lootEntity.Add(entity.net.ID.Value);
}
#endregion
#region Kill && Death && Suicide
private void OnPlayerDeath(BasePlayer player, HitInfo info) {
if (player == null || info == null || !player.userID.IsSteamId()) return;
if (info.damageTypes.Has(DamageType.Suicide)) {
var clan = FindClanByUser(player.userID);
if (clan == null) return;
clan.TotalScores -= config.Point.Suicide;
var member = clan.Members[player.userID];
member.MemberDeath++;
member.MemberScores -= config.Point.Suicide;
return;
}
var attacker = info.InitiatorPlayer;
if (attacker == null || !attacker.userID.IsSteamId() || FindClanByUser(player.userID)?.IsMember(attacker.userID) == true) return;
if (player.userID.IsSteamId()) {
var clan = FindClanByUser(player.userID);
if (clan != null) {
clan.TotalScores -= config.Point.Death;
var member = clan.Members[player.userID];
member.MemberDeath++;
member.MemberScores -= config.Point.Death;
}
var clanAttacker = FindClanByUser(attacker.userID);
if (clanAttacker != null) {
clanAttacker.TotalScores += config.Point.Kill;
var member = clanAttacker.Members[attacker.userID];
member.MemberKill++;
member.MemberScores += config.Point.Kill;
}
}
}
#endregion
#region Damage
private object IOnBasePlayerHurt(BasePlayer player, HitInfo info) {
if (player == null) return null;
if (info == null) return null;
if (info.InitiatorPlayer == null) return null;
var initiator = info.InitiatorPlayer;
if (player == initiator) return null;
var clan = FindClanByUser(player.userID);
if (clan == null) return null;
if (clan.IsMember(initiator.userID) && !clan.GetValueFriendlyFire(initiator)) {
if (initiator.SecondsSinceAttacked > 5) {
initiator.ChatMessage(GetLang("ClanFFActive", initiator.UserIDString));
initiator.lastAttackedTime = UnityEngine.Time.time;
}
DisableDamage(info);
return false;
}
return null;
}
#endregion
#region Skins
private void OnItemAddedToContainer(ItemContainer container, Item item) {
if (container == null || item == null) return;
var player = container.GetOwnerPlayer();
if (player == null) return;
var clan = FindClanByUser(player.userID);
if (clan == null) return;
if (clan.ItemList.ContainsKey(item.info.shortname)) {
var skin = clan.ItemList[item.info.shortname];
if (skin > 0) {
if (item.info.category == ItemCategory.Attire && container == player.inventory.containerWear) {
ItemEditSkinID(item, skin);
}
else {
ItemEditSkinID(item, skin);
}
}
}
}
#endregion
#region Auth
void OnEntityBuilt(Planner plan, GameObject go) {
if (plan == null || go == null) return;
var player = plan.GetOwnerPlayer();
if (player == null) return;
BaseEntity entity = go.ToBaseEntity();
if (entity == null) return;
var clan = FindClanByUser(player.userID);
if (clan == null) return;
if (entity.GetComponent<BuildingPrivlidge>() != null) {
var cup = entity.GetComponent<BuildingPrivlidge>();
if (config.Limit.EnableLimit) {
if (clan.Cupboard >= config.Limit.LCupboard) {
player.GetActiveItem().amount++;
NextTick(() => entity.Kill());
}
else clan.Cupboard++;
player.ChatMessage(GetLang("Cupboard", player.UserIDString, config.Limit.LCupboard - clan.Cupboard, config.Limit.LCupboard));
}
if (config.Main.AutomaticCupboard && entity != null) {
foreach (var member in clan.Members) {
cup.authorizedPlayers.Add(new PlayerNameID {
userid = member.Key, username = ""
}
);
}
}
return;
}
if (entity.GetComponent<AutoTurret>() != null) {
if (config.Limit.EnableLimit) {
if (clan.Turret >= config.Limit.LTurret) {
player.GetActiveItem().amount++;
NextTick(() => entity.Kill());
}
else clan.Turret++;
player.ChatMessage(GetLang("Turret", player.UserIDString, config.Limit.LTurret - clan.Turret, config.Limit.LTurret));
}
return;
}
if (entity.GetComponent<SamSite>() != null) {
if (config.Limit.EnableLimit) {
if (clan.SamSite >= config.Limit.LSamSite) {
player.GetActiveItem().amount++;
NextTick(() => entity.Kill());
}
else clan.SamSite++;
player.ChatMessage(GetLang("SamSite", player.UserIDString, config.Limit.LSamSite - clan.SamSite, config.Limit.LSamSite));
}
return;
}
}
object CanUseLockedEntity(BasePlayer player, BaseLock baseLock) {
if (player == null || baseLock == null || baseLock.OwnerID == 0 || baseLock.OwnerID == player.userID) return null;
if (baseLock.GetComponent<CodeLock>() == null || baseLock.GetComponent<CodeLock>().whitelistPlayers.Contains(player.userID)) return null;
if ((bool) IsClanMember(baseLock.OwnerID.ToString(), player.userID.ToString())) return true;
return null;
}
object OnTurretTarget(AutoTurret turret, BasePlayer player) {
if (turret == null) return null;
if (player == null) return null;
if (turret.OwnerID == 0) return null;
//if (turret.IsAuthed(player)) return null;
if ((bool)IsClanMember(turret.OwnerID.ToString(), player.userID.ToString())) {
return false;
}
return null;
}
#endregion
#endregion
#region Functional
#region Request
private static void Request(string ask, Action<int, string> callback) {
Dictionary<string, string> reqHeaders = new Dictionary<string, string> {
{
"User-Agent", "Clan Plugin"
}
}
;
Instance.webrequest.Enqueue($"https://gamestores.app/api/?shop_id={config.Prize.GSSettings.ShopID}&secret={config.Prize.GSSettings.SecretKey}" + ask, "", (code, response) => {
switch (code) {
case 200 : {
break;
}
case 404 : {
Instance.PrintWarning($"Please check your configuration! [404] #2");
break;
}
}
if (response.Contains("The authentication or decryption has failed.")) {
Instance.PrintWarning("HTTPS request is broken (broken CA certificate?).Changed to non secure connection!");
Interface.Oxide.UnloadPlugin(Instance.Name);
return;
}
callback?.Invoke(code, response);
}
, Instance, RequestMethod.GET, reqHeaders);
}
#endregion
#region Formated
string getFormattedClanTag(IPlayer player) {
var clan = FindClanByUser(ulong.Parse(player.Id));
if (clan != null && !string.IsNullOrEmpty(clan.ClanTag)) return $"[{clan.ClanTag}]";
return string.Empty;
}
#endregion
#region LoadData
void LoadData() {
if (Interface.GetMod().DataFileSystem.ExistsDatafile(Name)) {
_clanList = Interface.GetMod().DataFileSystem.ReadObject<List<ClanData>>(Name);
}
else _clanList = new List<ClanData>();
}
#endregion
#region GetAvatar
private readonly Regex Regex = new Regex(@"<avatarFull><!\[CDATA\[(.*)\]\]></avatarFull>");
private void GetAvatar(ulong userId, Action<string> callback) {
if (callback == null) return;
webrequest.Enqueue($"http://steamcommunity.com/profiles/{userId}?xml=1", null, (code, response) => {
if (code != 200 || response == null) return;
var avatar = Regex.Match(response).Groups[1].ToString();
if (string.IsNullOrEmpty(avatar)) return;
callback.Invoke(avatar);
}
, this);
}
#endregion
#region HexColor
public string HexToCuiColor(string HEX, float Alpha = 100) {
if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF";
var str = HEX.Trim('#');
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}";
}
#endregion
#region GenerateSkins
public void GenerateSkinList() {
if (!ImageLibrary) return;
bool any = false;
foreach (var wearDictionary in config.Main.WearDictionary) {
var anyDictionary = config.ItemSkin.ItemsSkins.ContainsKey(wearDictionary.Key);
if (!anyDictionary) {
config.ItemSkin.ItemsSkins[wearDictionary.Key] = ImageLibrary?.Call<List<ulong>>("GetImageList", wearDictionary.Key) ?? new List<ulong>();
any = true;
}
}
if (any) SaveConfig();
}
#endregion
#region GetNamePlayer
private string GetNamePlayer(BasePlayer player) {
if (player == null || !player.userID.IsSteamId()) return string.Empty;
var covPlayer = player.IPlayer;
if (player.net?.connection == null) {
if (covPlayer != null) return covPlayer.Name;
return player.UserIDString;
}
var value = player.net.connection.username;
var str = value.ToPrintable(32).EscapeRichText().Trim();
if (string.IsNullOrWhiteSpace(str)) {
str = covPlayer.Name;
if (string.IsNullOrWhiteSpace(str)) str = player.UserIDString;
}
return str;
}
#endregion
#region Disable Damage
private void DisableDamage(HitInfo info) {
info.damageTypes = new DamageTypeList();
info.DidHit = false;
info.HitEntity = null;
info.Initiator = null;
info.DoHitEffects = false;
info.HitMaterial = 0;
}
#endregion
#region InternalHook
private void SubscribeInternalHook(string hook) {
var hookSubscriptions_ = hookSubscriptions.GetValue(Interface.Oxide.RootPluginManager) as IDictionary<string, IList<Plugin>>;
IList<Plugin> plugins;
if (!hookSubscriptions_.TryGetValue(hook, out plugins)) {
plugins = new List<Plugin>();
hookSubscriptions_.Add(hook, plugins);
}
if (!plugins.Contains(this)) plugins.Add(this);
}
#endregion
#region AddedClan
public void CreateInClan(BasePlayer player, string clanTag) {
var clanGather = new Dictionary<string, ClanData.GatherData>();
var SkinList = new Dictionary<string, ulong>();
foreach (var key in config.Main.WearDictionary) {
SkinList.Add(key.Key, key.Value);
}
foreach (var key in config.Main.GatherDictionary) {
clanGather.Add(key, new ClanData.GatherData {
Need = 1000, TotalFarm = 0,
}
);
}
var newclan = new ClanData() {
ClanTag = clanTag, ImageAvatar = $"avatar_{player.UserIDString}", GatherList = clanGather, ItemList = SkinList, LeaderUlongID = player.userID, Task = "", TotalScores = 0, Members = new Dictionary<ulong, ClanData.MemberData>(), Moderators = new List<ulong>(), PendingInvites = new List<ulong>()
}
;
newclan.Members.Add(player.userID, new ClanData.MemberData {
GatherMember = config.Main.GatherDictionary.ToDictionary(x => x, p => 0),
}
);
//_ins.PrintWarning($"[{DateTime.Now.ToString("g")}] был создан клан {clanTag} игроком {player.displayName}");
if (config.Main.TagInPlayer) player.displayName = $"[{clanTag}] {GetNamePlayer(player)}";
if (config.Main.EnableTeam) newclan.FindOrCreateTeam();
player.SendNetworkUpdateImmediate();
_clanList.Add(newclan);
Interface.CallHook("OnClanCreate", clanTag, player);
}
#endregion
#region FormatTime
private string GetFormatTime(TimeSpan timespan) {
return string.Format("{0:00}м.{1:00}с.", timespan.Minutes, timespan.Seconds);
}
#endregion
#region Lang
public static StringBuilder sb = new StringBuilder();
public string GetLang(string LangKey, string userID = null, params object[] args) {
sb.Clear();
if (args != null) {
sb.AppendFormat(lang.GetMessage(LangKey, this, userID), args);
return sb.ToString();
}
return lang.GetMessage(LangKey, this, userID);
}
private void LoadMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["ClanNotFound"]
= "Что бы создать клан введите: /clan create \"название клана\"", ["ClanInviteNotFoundPlayer"] = "/clan invite \"ник или steamid игрока\" - отправить предложение вступить в клан", ["ClanKickNotFoundPlayer"] = "/clan kick \"ник или steamid игрока\" - исключить игрока из клана", ["ClanOwnerNotFoundPlayer"] = "/clan owner \"ник или steamid игрока\" - назначить игрока главой клана", ["ClanTaskNotLength"] = "/clan task \"задача\" - установить задачу", ["ClanTask"] = "Вы успешно установили задачу!", ["TargetNotClan"] = "Игрок {0} не был найден в клане", ["TargetModeratorAndOwner"] = "Игрок является модератором или главой в клане!", ["PlayerNotFound"] = "Игрок {0} не был найден", ["PlayerNotClan"] = "Вы не состоите в клане", ["PlayerOwner"] = "Вы являетесь главой клана", ["PlayerLeave"] = "Вы успешно покинули клан", ["PlayerKickSelf"] = "Вы не можете кикнуть самого себя!", ["PlayerKick"] = "Вы были кикнуты из клана!", ["PlayerModeratorKick"] = "Вы успешно кикнули игрока {0} из клана!", ["NameClanLength"] = "Минимальная длина тега: {0}, максимальная длина тега: {1}", ["ContainsTAG"] = "Данный клан тег уже занят другим кланом", ["ClanTagBlocked"] = "Данный клан тег запрещен", ["PlayerInClan"] = "Вы уже состоите в клане", ["TargetInClan"] = "Данный игрок уже находится в клане", ["PlayerNotOwnerAndModerator"] = "Вы не являетесь модератором или главой клана", ["PlayerNotOwner"] = "Вы не являетесь главой клана", ["PSetLeader"] = "Вы успешно стали главой клана", ["PGiveLeader"] = "Вы успешно передали главу клана", ["ClanDisband"] = "Вы успешно расформировали клан", ["PlayerNotInvite"] = "Вы не имеете активных предложений", ["PlayerStartClan"] = "Вы успешно создали клан: {0}!", ["ClanLimitPlayer"] = "Превышено количество игроков в клане!", ["ClanLimitModerator"] = "Превышено количество модераторов в клане!", ["AcceptInvite"] = "Вы успешно присоединились к клану {0}", ["DenyInvite"] = "Вы успешно отклонили предложение для вступления в клан", ["PlayerStartInvite"] = "Вы получили приглашение в клан: {0}\n/clan accept- принять приглашение\n/clan deny - отклонить предложение", ["InitiatorStartInvite"] = "Вы успешно отправили приглашение игроку: {0}", ["ClanFFActive"] = "Вы не можете нанести урон своему напарнику.Что бы включить FF, пропишите команду /clan ff", ["ClanFFActivate"] = "Вы успешно включили FF", ["ClanFFDeactivation"] = "Вы успешно выключили FF", ["HelpNoClan"] = "Помощь:\n/clan create \"название клана\" - создать клан\n/clan help - список доступных комманд\n/clan accept - принять предложение вступить в клан\n/clan deny - отклонить предложение вступить в клан", ["HelpClanPlayer"] = "Помощь:\n/clan help - список доступных комманд\n/clan leave - покинуть клан\n/c \"сообщение\" - отправить сообщение всему клану", ["HelpClanModerator"] = "Помощь:\n/clan invite \"ник или steamid игрока\" - отправить предложение вступить в клан\n/clan kick \"ник или steamid игрока\" - исключить игрока из клана\n/clan leave - покинуть клан\n", ["HelpClanOwner"] = "Помощь:\n/clan invite \"ник или steamid игрока\" - отправить предложение вступить в клан\n/clan kick \"ник или steamid игрока\" - исключить игрока из клана\n/clan disband - расфомировать клан\n/clan task \"задача\" - установить задачу\n/clan owner \"ник или steamid игрока\" - назначить игрока главой клана", ["Cupboard"] = "Осталось доступных шкафов: {0} из {1}", ["Turret"] = "Осталось доступных турелей: {0} из {1}", ["SamSite"] = "Осталось доступных ПВО: {0} из {1}", ["UI_TaskContent"] = "ТЕКУЩАЯ ЗАДАЧА", ["UI_ClothContent"] = "НАБОР КЛАНОВОЙ ОДЕЖДЫ", ["UI_GatherContent"] = "ДОБЫЧА РЕСУРСОВ", ["UI_NameContent"] = "НИК ИГРОКА", ["UI_ActivityContent"] = "АКТИВНОСТЬ", ["UI_StandartContent"] = "НОРМА", ["UI_ScoresContent"] = "ОЧКИ ТОПА", ["UI_TaskMessageContent"] = "Глава клана еще не указал текущую задачу", ["UI_GatherStart"] = "Установка нормы", ["UI_GatherComment"] = "Укажите количество которое должен добыть участник группы", ["UI_SkinContent"] = "ВЫБЕРИТЕ СКИН", ["UI_TopName"] = "НАЗВАНИЕ КЛАНА", ["UI_TopTournament"] = "ШКАФ", ["UI_TopReward"] = "НАГРАДА", ["UI_TopScores"] = "ОЧКИ", ["UI_TopPlayer"] = "ИГРОКОВ", ["UI_TopInformation"] = "Очки даются:\nУбийство - 25, добыча руды - 2, разрушение бочки - 1, сбитие вертолета - 750, уничтожение танка - 500\nОчки отнимаются:\nСмерть - 20, самоубийство - 20", ["UI_InfoClanName"] = "ИМЯ ИГРОКА", ["UI_InfoClanScores"] = "ОЧКОВ", ["UI_InfoClanFarm"] = "НОРМА", ["UI_InfoClanKill"] = "УБИЙСТВ", ["UI_InfoClanDeath"] = "СМЕРТЕЙ"
}
, this);
}
#endregion
#region StartCommand
[ConsoleCommand("Clan_Command")]
void RunCommand(ConsoleSystem.Arg args) {
var player = args.Player();
if (player == null) return;
if (args.FullString.Contains("/")) player.Command("chat.say", args.FullString);
else player.Command(args.FullString);
}
#endregion
#region ItemEditSkinID
public void ItemEditSkinID(Item item, ulong SkinID) {
item.skin = SkinID;
item.MarkDirty();
var heldEntity = item.GetHeldEntity();
if (heldEntity == null) return;
heldEntity.skinID = SkinID;
heldEntity.SendNetworkUpdate();
}
#endregion
#endregion
#region Command
#region ChatCommand
private void ClanTopCmd(IPlayer cov, string command, string[] args) {
var player = cov?.Object as BasePlayer;
if (player == null) return;
if (args.Length == 0) {
if (playerActive.Contains(player.userID)) return;
MainTopUI(player);
return;
}
}
private void ClanCmd(IPlayer cov, string command, string[] args) {
var player = cov?.Object as BasePlayer;
if (player == null) return;
if (args.Length == 0) {
var clan = FindClanByUser(player.userID);
if (clan == null) {
player.ChatMessage(GetLang("ClanNotFound", player.UserIDString));
return;
}
if (playerActive.Contains(player.userID)) return;
MainUI(player);
return;
}
switch (args[0]) {
#region Create
case "create" : {
if (args.Length < 2) {
player.ChatMessage(GetLang("ClanNotFound", player.UserIDString));
return;
}
var clan = FindClanByUser(player.userID);
if (clan != null) {
player.ChatMessage(GetLang("PlayerInClan", player.UserIDString));
return;
}
var clanTag = string.Join(" ", args.Skip(1));
if (string.IsNullOrEmpty(clanTag)) {
player.ChatMessage(GetLang("ClanNotFound", player.UserIDString));
return;
}
clanTag = clanTag.Replace(" ", "");
if (clanTag.Length < config.Main.MinNameLength || clanTag.Length > config.Main.MaxNameLength) {
player.ChatMessage(GetLang("NameClanLength", player.UserIDString, config.Main.MinNameLength, config.Main.MaxNameLength));
return;
}
if (config.Main.ForbiddenTag.Exists(word => $"[{clanTag}]".Contains(word, CompareOptions.OrdinalIgnoreCase))) // Mevent <3
{
player.ChatMessage(GetLang("ClanTagBlocked", player.UserIDString));
return;
}
var alreadyClan = FindClanByTag(clanTag);
if (alreadyClan != null) {
player.ChatMessage(GetLang("ContainsTAG", player.UserIDString));
return;
}
CreateInClan(player, clanTag);
player.ChatMessage(GetLang("PlayerStartClan", player.UserIDString, clanTag));
break;
}
#endregion
#region Accept
case "accept" : {
var clan = FindClanByUser(player.userID);
if (clan != null) {
player.ChatMessage(GetLang("PlayerInClan", player.UserIDString));
return;
}
var clanInvite = FindClanByInvite(player.userID);
if (clanInvite == null) {
player.ChatMessage(GetLang("PlayerNotInvite", player.UserIDString));
return;
}
if (clanInvite.Members.Count >= config.Main.MaxCountClan) {
player.ChatMessage(GetLang("ClanLimitPlayer", player.UserIDString));
clanInvite.PendingInvites.Remove(player.userID);
return;
}
clanInvite.InvitePlayer(player);
player.ChatMessage(GetLang("AcceptInvite", player.UserIDString, clanInvite.ClanTag));
break;
}
#endregion
#region Deny
case "deny" : {
var clan = FindClanByUser(player.userID);
if (clan != null) {
player.ChatMessage(GetLang("PlayerInClan", player.UserIDString));
return;
}
var clanInvite = FindClanByInvite(player.userID);
if (clanInvite == null) {
player.ChatMessage(GetLang("PlayerNotInvite", player.UserIDString));
return;
}
clanInvite.PendingInvites.Remove(player.userID);
player.ChatMessage(GetLang("DenyInvite", player.UserIDString));
break;
}
#endregion
#region Invite
case "invite" : {
if (args.Length < 2) {
player.ChatMessage(GetLang("ClanInviteNotFoundPlayer", player.UserIDString));
return;
}
var clan = FindClanByUser(player.userID);
if (clan == null) {
player.ChatMessage(GetLang("PlayerNotClan", player.UserIDString));
return;
}
if (!clan.IsModerator(player.userID)) {
player.ChatMessage(GetLang("PlayerNotOwnerAndModerator", player.UserIDString));
return;
}
if (clan.Members.Count >= config.Main.MaxCountClan) {
player.ChatMessage(GetLang("ClanLimitPlayer", player.UserIDString));
return;
}
string name = string.Join(" ", args.Skip(1));
var targetPlayer = BasePlayer.Find(name);
if (targetPlayer == null) {
player.ChatMessage(GetLang("PlayerNotFound", player.UserIDString, name));
return;
}
if (player == targetPlayer) return;
var clanTarget = FindClanByUser(targetPlayer.userID);
if (clanTarget != null) {
player.ChatMessage(GetLang("TargetInClan", player.UserIDString));
return;
}
clan.PendingInvites.Add(targetPlayer.userID);
targetPlayer.ChatMessage(GetLang("PlayerStartInvite", targetPlayer.UserIDString, clan.ClanTag));
player.ChatMessage(GetLang("InitiatorStartInvite", player.UserIDString, targetPlayer.displayName));
break;
}
#endregion
#region Help
case "help" : {
var clan = FindClanByUser(player.userID);
if (clan == null) {
player.ChatMessage(GetLang("HelpNoClan", player.UserIDString));
return;
}
if (!clan.IsModerator(player.userID)) {
player.ChatMessage(GetLang("HelpClanPlayer", player.UserIDString));
return;
}
if (clan.LeaderUlongID != player.userID && clan.Moderators.Contains(player.userID)) {
player.ChatMessage(GetLang("HelpClanModerator", player.UserIDString));
return;
}
if (clan.LeaderUlongID == player.userID) {
player.ChatMessage(GetLang("HelpClanOwner", player.UserIDString));
}
break;
}
#endregion
#region Leave
case "leave" : {
var clan = FindClanByUser(player.userID);
// ... [Code preview truncated due to length. Full source in attached file] ...