C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Oxide.Plugins
{
[Info("Automatic Authorization", "k1lly0u/Arainrr", "1.3.3", ResourceId = 2063)]
[Description("Shared cupboards, turrets, locks with teams, clans, friends")]
public class AutomaticAuthorization : RustPlugin
{
#region Fields
[PluginReference]
private readonly Plugin Clans, Friends, Bank;
private const string PERMISSION_USE = "automaticauthorization.use";
private readonly object _true = true;
private readonly Dictionary<ulong, EntityCache> _playerEntities = new Dictionary<ulong, EntityCache>();
private enum ShareType
{
None,
Teams,
Friends,
Clans
}
[Flags]
private enum AutoAuthType
{
Turret = 1 << 0,
Cupboard = 1 << 1,
CodeLock = 1 << 2,
All = -1,
}
private class EntityCache
{
public readonly HashSet<AutoTurret> autoTurrets = new HashSet<AutoTurret>();
public readonly HashSet<BuildingPrivlidge> buildingPrivlidges = new HashSet<BuildingPrivlidge>();
public readonly HashSet<CodeLock> codeLocks = new HashSet<CodeLock>();
}
#endregion Fields
#region Oxide Hooks
private void Init()
{
LoadData();
UpdateData();
permission.RegisterPermission(PERMISSION_USE, this);
cmd.AddChatCommand(configData.Chat.ChatCommand, this, nameof(CmdAutoAuth));
cmd.AddChatCommand(configData.Chat.UICommand, this, nameof(CmdAutoAuthUI));
Unsubscribe(nameof(OnEntitySpawned));
if (!configData.TeamsShare.Enabled)
{
Unsubscribe(nameof(OnTeamLeave));
Unsubscribe(nameof(OnTeamKick));
Unsubscribe(nameof(OnTeamDisbanded));
Unsubscribe(nameof(OnTeamAcceptInvite));
}
if (!configData.FriendsShare.Enabled)
{
Unsubscribe(nameof(OnFriendAdded));
Unsubscribe(nameof(OnFriendRemoved));
}
if (!configData.ClansShare.Enabled)
{
Unsubscribe(nameof(OnClanUpdate));
Unsubscribe(nameof(OnClanDestroy));
Unsubscribe(nameof(OnClanMemberGone));
}
}
private void OnServerInitialized()
{
Subscribe(nameof(OnEntitySpawned));
foreach (var serverEntity in BaseNetworkable.serverEntities)
{
var autoTurret = serverEntity as AutoTurret;
if (autoTurret != null)
{
CheckEntitySpawned(autoTurret);
continue;
}
var buildingPrivlidge = serverEntity as BuildingPrivlidge;
if (buildingPrivlidge != null)
{
CheckEntitySpawned(buildingPrivlidge);
}
var codeLock = serverEntity as CodeLock;
if (codeLock != null)
{
CheckEntitySpawned(codeLock);
}
}
}
private void OnServerSave()
{
timer.Once(Random.Range(0f, 60f), SaveData);
}
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
{
DestroyUI(player);
}
SaveData();
}
private void OnEntitySpawned(AutoTurret autoTurret)
{
CheckEntitySpawned(autoTurret, true);
}
private void OnEntitySpawned(BuildingPrivlidge buildingPrivlidge)
{
CheckEntitySpawned(buildingPrivlidge, true);
}
private void OnEntitySpawned(CodeLock codeLock)
{
CheckEntitySpawned(codeLock, true);
}
private void OnEntityKill(AutoTurret autoTurret)
{
CheckEntityKill(autoTurret);
}
private void OnEntityKill(BuildingPrivlidge buildingPrivlidge)
{
CheckEntityKill(buildingPrivlidge);
}
private void OnEntityKill(CodeLock codeLock)
{
CheckEntityKill(codeLock);
}
private void CanChangeCode(BasePlayer player, CodeLock codeLock, string code, bool isGuest)
{
NextFrame(() =>
{
if (!isGuest ? codeLock.code != code : codeLock.guestCode != code)
{
return;
}
var parentEntity = codeLock.GetParentEntity();
var ownerId = codeLock.OwnerID.IsSteamId() ? codeLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
if (!ownerId.IsSteamId())
{
return;
}
UpdateAuthList(ownerId, AutoAuthType.CodeLock);
});
}
private object CanUseLockedEntity(BasePlayer player, BaseLock baseLock)
{
if (player == null || baseLock == null || !baseLock.IsLocked())
{
return null;
}
var parentEntity = baseLock.GetParentEntity();
var ownerId = baseLock.OwnerID.IsSteamId() ? baseLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
if (!ownerId.IsSteamId() || ownerId == player.userID)
{
return null;
}
if (!permission.UserHasPermission(ownerId.ToString(), PERMISSION_USE))
{
return null;
}
// Ignore the bank boxes
if (IsBankBox(parentEntity))
{
return null;
}
var shareData = GetShareData(ownerId, true);
if (CanSharingLock(baseLock, parentEntity, shareData, ShareType.Teams, ownerId, player.userID))
{
return _true;
}
if (CanSharingLock(baseLock, parentEntity, shareData, ShareType.Friends, ownerId, player.userID))
{
return _true;
}
if (CanSharingLock(baseLock, parentEntity, shareData, ShareType.Clans, ownerId, player.userID))
{
return _true;
}
return null;
}
#endregion Oxide Hooks
#region Helpers
private static bool CanShareLockedEntity(BaseEntity parentEntity, StoredData.LockShareEntry lockShareEntry)
{
if (!lockShareEntry.enabled)
{
return false;
}
return parentEntity is Door ? lockShareEntry.door :
parentEntity is BoxStorage ? lockShareEntry.box : lockShareEntry.other;
}
private static void SendUnlockedEffect(CodeLock codeLock)
{
if (codeLock.effectUnlocked.isValid)
{
Effect.server.Run(codeLock.effectUnlocked.resourcePath, codeLock.transform.position);
}
}
private static void CheckShareData(StoredData.ShareEntry shareEntry, ConfigData.ShareSettings shareSettings)
{
if (!shareSettings.Enabled)
{
shareEntry.enabled = false;
}
if (!shareSettings.ShareCupboard)
{
shareEntry.cupboard = false;
}
if (!shareSettings.ShareTurret)
{
shareEntry.turret = false;
}
if (!shareSettings.KeyLock.Enabled)
{
shareEntry.keyLock.enabled = false;
}
if (!shareSettings.KeyLock.ShareDoor)
{
shareEntry.keyLock.door = false;
}
if (!shareSettings.KeyLock.ShareBox)
{
shareEntry.keyLock.box = false;
}
if (!shareSettings.KeyLock.ShareOtherEntity)
{
shareEntry.keyLock.other = false;
}
if (!shareSettings.CodeLock.Enabled)
{
shareEntry.codeLock.enabled = false;
}
if (!shareSettings.CodeLock.ShareDoor)
{
shareEntry.codeLock.door = false;
}
if (!shareSettings.CodeLock.ShareBox)
{
shareEntry.codeLock.box = false;
}
if (!shareSettings.CodeLock.ShareOtherEntity)
{
shareEntry.codeLock.other = false;
}
}
#endregion Helpers
#region Methods
#region Entity Spawn / Kill
private void CheckEntitySpawned(AutoTurret autoTurret, bool justCreated = false)
{
if (autoTurret == null || !autoTurret.OwnerID.IsSteamId())
{
return;
}
EntityCache entityCache;
if (!_playerEntities.TryGetValue(autoTurret.OwnerID, out entityCache))
{
entityCache = new EntityCache();
_playerEntities.Add(autoTurret.OwnerID, entityCache);
}
entityCache.autoTurrets.Add(autoTurret);
if (justCreated && permission.UserHasPermission(autoTurret.OwnerID.ToString(), PERMISSION_USE))
{
AuthToTurret(new HashSet<AutoTurret> { autoTurret }, autoTurret.OwnerID, true);
}
}
private void CheckEntitySpawned(BuildingPrivlidge buildingPrivlidge, bool justCreated = false)
{
if (buildingPrivlidge == null || !buildingPrivlidge.OwnerID.IsSteamId())
{
return;
}
EntityCache entityCache;
if (!_playerEntities.TryGetValue(buildingPrivlidge.OwnerID, out entityCache))
{
entityCache = new EntityCache();
_playerEntities.Add(buildingPrivlidge.OwnerID, entityCache);
}
entityCache.buildingPrivlidges.Add(buildingPrivlidge);
if (justCreated && permission.UserHasPermission(buildingPrivlidge.OwnerID.ToString(), PERMISSION_USE))
{
AuthToCupboard(new HashSet<BuildingPrivlidge> { buildingPrivlidge }, buildingPrivlidge.OwnerID, true);
}
}
private void CheckEntitySpawned(CodeLock codeLock, bool justCreated = false)
{
if (codeLock == null)
{
return;
}
var parentEntity = codeLock.GetParentEntity();
if (parentEntity != null && IsBankBox(parentEntity))
{
return;
}
var ownerId = codeLock.OwnerID.IsSteamId() ? codeLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
if (!ownerId.IsSteamId())
{
return;
}
EntityCache entityCache;
if (!_playerEntities.TryGetValue(ownerId, out entityCache))
{
entityCache = new EntityCache();
_playerEntities.Add(ownerId, entityCache);
}
entityCache.codeLocks.Add(codeLock);
if (justCreated && permission.UserHasPermission(ownerId.ToString(), PERMISSION_USE))
{
AuthToCodeLock(new HashSet<CodeLock> { codeLock }, ownerId, true);
}
}
private void CheckEntityKill(AutoTurret autoTurret)
{
if (autoTurret == null || !autoTurret.OwnerID.IsSteamId())
{
return;
}
EntityCache entityCache;
if (_playerEntities.TryGetValue(autoTurret.OwnerID, out entityCache))
{
entityCache.autoTurrets.Remove(autoTurret);
}
}
private void CheckEntityKill(BuildingPrivlidge buildingPrivlidge)
{
if (buildingPrivlidge == null || !buildingPrivlidge.OwnerID.IsSteamId())
{
return;
}
EntityCache entityCache;
if (_playerEntities.TryGetValue(buildingPrivlidge.OwnerID, out entityCache))
{
entityCache.buildingPrivlidges.Remove(buildingPrivlidge);
}
}
private void CheckEntityKill(CodeLock codeLock)
{
if (codeLock == null)
{
return;
}
var parentEntity = codeLock.GetParentEntity();
var ownerId = codeLock.OwnerID.IsSteamId() ? codeLock.OwnerID : parentEntity != null ? parentEntity.OwnerID : 0;
if (!ownerId.IsSteamId())
{
return;
}
EntityCache entityCache;
if (_playerEntities.TryGetValue(ownerId, out entityCache))
{
entityCache.codeLocks.Remove(codeLock);
}
}
#endregion Entity Spawn / Kill
private void UpdateAuthList(ulong playerId, AutoAuthType autoAuthType)
{
if (!permission.UserHasPermission(playerId.ToString(), PERMISSION_USE))
{
return;
}
EntityCache entityCache;
if (!_playerEntities.TryGetValue(playerId, out entityCache))
{
return;
}
if (autoAuthType.HasFlag(AutoAuthType.Turret))
{
AuthToTurret(entityCache.autoTurrets, playerId);
}
if (autoAuthType.HasFlag(AutoAuthType.Cupboard))
{
AuthToCupboard(entityCache.buildingPrivlidges, playerId);
}
if (autoAuthType.HasFlag(AutoAuthType.CodeLock))
{
AuthToCodeLock(entityCache.codeLocks, playerId);
}
}
private void AuthToTurret(HashSet<AutoTurret> autoTurrets, ulong playerId, bool justCreated = false)
{
if (autoTurrets.Count <= 0)
{
return;
}
var authList = GetAuthorNameIDs(playerId, AutoAuthType.Turret);
foreach (var autoTurret in autoTurrets)
{
if (autoTurret == null || autoTurret.IsDestroyed)
{
continue;
}
var isOnline = autoTurret.IsOnline();
if (isOnline)
{
autoTurret.SetIsOnline(false);
}
autoTurret.authorizedPlayers.Clear();
foreach (var friend in authList)
{
autoTurret.authorizedPlayers.Add(friend);
}
if (isOnline)
{
autoTurret.SetIsOnline(true);
}
autoTurret.SendNetworkUpdate();
}
if (justCreated && configData.Chat.SendMessage && authList.Count > 1)
{
var player = BasePlayer.FindByID(playerId);
if (player != null)
{
Print(player, Lang("TurretSuccess", player.UserIDString, authList.Count - 1, autoTurrets.Count));
}
}
}
private void AuthToCupboard(HashSet<BuildingPrivlidge> buildingPrivlidges, ulong playerId, bool justCreated = false)
{
if (buildingPrivlidges.Count <= 0)
{
return;
}
var authList = GetAuthorNameIDs(playerId, AutoAuthType.Cupboard);
foreach (var buildingPrivlidge in buildingPrivlidges)
{
if (buildingPrivlidge == null || buildingPrivlidge.IsDestroyed)
{
continue;
}
buildingPrivlidge.authorizedPlayers.Clear();
foreach (var friend in authList)
{
buildingPrivlidge.authorizedPlayers.Add(friend);
}
buildingPrivlidge.SendNetworkUpdate();
}
if (justCreated && configData.Chat.SendMessage && authList.Count > 1)
{
var player = BasePlayer.FindByID(playerId);
if (player != null)
{
Print(player, Lang("CupboardSuccess", player.UserIDString, authList.Count - 1, buildingPrivlidges.Count));
}
}
}
private void AuthToCodeLock(HashSet<CodeLock> codeLocks, ulong playerId, bool justCreated = false)
{
if (codeLocks.Count <= 0)
{
return;
}
foreach (var codeLock in codeLocks)
{
if (codeLock == null || codeLock.IsDestroyed)
{
continue;
}
codeLock.whitelistPlayers.Clear(); // only owner id
codeLock.whitelistPlayers.Add(playerId);
codeLock.guestPlayers.Clear(); // excluding owner id
var authList = GetAuthorIDsForCodeLock(playerId, codeLock);
foreach (var friend in authList)
{
codeLock.guestPlayers.Add(friend);
}
codeLock.SendNetworkUpdate();
}
}
private List<PlayerNameID> GetAuthorNameIDs(ulong playerId, AutoAuthType autoAuthType)
{
if (autoAuthType == AutoAuthType.CodeLock)
{
PrintError("Cannot be used for code locks");
return new List<PlayerNameID>();
}
var authList = GetAuthIds(playerId, autoAuthType);
return authList.Select(userid => new PlayerNameID { userid = userid, username = RustCore.FindPlayerById(userid)?.displayName ?? string.Empty }).ToList();
}
private HashSet<ulong> GetAuthorIDsForCodeLock(ulong playerId, CodeLock codeLock)
{
var sharePlayers = new HashSet<ulong>();
var parentEntity = codeLock.GetParentEntity();
if (parentEntity == null)
{
return sharePlayers;
}
var shareData = GetShareData(playerId, true);
var teamsShare = shareData.GetShareEntry(ShareType.Teams);
if (teamsShare.enabled && CanShareLockedEntity(parentEntity, teamsShare.codeLock))
{
var teamMembers = GetTeamMembers(playerId);
if (teamMembers != null)
{
foreach (var member in teamMembers)
{
sharePlayers.Add(member);
}
}
}
var friendsShare = shareData.GetShareEntry(ShareType.Friends);
if (friendsShare.enabled && CanShareLockedEntity(parentEntity, friendsShare.codeLock))
{
var friends = GetFriends(playerId);
if (friends != null)
{
foreach (var friend in friends)
{
sharePlayers.Add(friend);
}
}
}
var clansShare = shareData.GetShareEntry(ShareType.Clans);
if (clansShare.enabled && CanShareLockedEntity(parentEntity, clansShare.codeLock))
{
var clanMembers = GetClanMembers(playerId);
if (clanMembers != null)
{
foreach (var member in clanMembers)
{
sharePlayers.Add(member);
}
}
}
return sharePlayers;
}
private HashSet<ulong> GetAuthIds(ulong playerId, AutoAuthType autoAuthType)
{
var sharePlayers = new HashSet<ulong> { playerId };
var shareData = GetShareData(playerId, true);
var teamsShare = shareData.GetShareEntry(ShareType.Teams);
if (teamsShare.enabled && (autoAuthType == AutoAuthType.Turret ? teamsShare.turret : teamsShare.cupboard))
{
var teamMembers = GetTeamMembers(playerId);
if (teamMembers != null)
{
foreach (var member in teamMembers)
{
sharePlayers.Add(member);
}
}
}
var friendsShare = shareData.GetShareEntry(ShareType.Friends);
if (friendsShare.enabled && (autoAuthType == AutoAuthType.Turret ? friendsShare.turret : friendsShare.cupboard))
{
var friends = GetFriends(playerId);
if (friends != null)
{
foreach (var friend in friends)
{
sharePlayers.Add(friend);
}
}
}
var clansShare = shareData.GetShareEntry(ShareType.Clans);
if (clansShare.enabled && (autoAuthType == AutoAuthType.Turret ? clansShare.turret : clansShare.cupboard))
{
var clanMembers = GetClanMembers(playerId);
if (clanMembers != null)
{
foreach (var member in clanMembers)
{
sharePlayers.Add(member);
}
}
}
return sharePlayers;
}
private bool CanSharingLock(BaseLock baseLock, BaseEntity parentEntity, StoredData.ShareData shareData, ShareType shareType, ulong ownerId, ulong playerId)
{
var shareEntry = shareData.GetShareEntry(shareType);
if (shareEntry.enabled && AreFriends(shareType, ownerId, playerId))
{
if (baseLock is KeyLock)
{
return CanShareLockedEntity(parentEntity, shareEntry.keyLock);
}
var codeLock = baseLock as CodeLock;
if (codeLock != null && CanShareLockedEntity(parentEntity, shareEntry.codeLock))
{
SendUnlockedEffect(codeLock);
return true;
}
}
return false;
}
private IEnumerable<ShareType> GetAvailableTypes()
{
if (IsShareTypeEnabled(ShareType.Teams))
{
yield return ShareType.Teams;
}
if (IsShareTypeEnabled(ShareType.Friends))
{
yield return ShareType.Friends;
}
if (IsShareTypeEnabled(ShareType.Clans))
{
yield return ShareType.Clans;
}
}
private bool IsShareTypeEnabled(ShareType shareType)
{
var shareSettings = configData.GetShareSettings(shareType);
if (!shareSettings.Enabled)
{
return false;
}
switch (shareType)
{
case ShareType.Teams:
return RelationshipManager.TeamsEnabled();
case ShareType.Friends:
return Friends != null;
case ShareType.Clans:
return Clans != null;
}
return false;
}
private bool AreFriends(ShareType shareType, ulong ownerId, ulong playerId)
{
switch (shareType)
{
case ShareType.Teams:
return SameTeam(ownerId, playerId);
case ShareType.Friends:
return HasFriend(ownerId, playerId);
case ShareType.Clans:
return SameClan(ownerId, playerId);
}
return false;
}
#region Data
private StoredData.ShareData _defaultData;
private StoredData.ShareData DefaultData => _defaultData ?? (_defaultData = CreateDefaultData());
private StoredData.ShareData GetShareData(ulong playerId, bool readOnly = false)
{
StoredData.ShareData shareData;
if (!storedData.playerShareData.TryGetValue(playerId, out shareData))
{
if (readOnly)
{
return DefaultData;
}
shareData = CreateDefaultData();
storedData.playerShareData.Add(playerId, shareData);
}
return shareData;
}
private StoredData.ShareData CreateDefaultData()
{
return new StoredData.ShareData
{
teamsShare = CreateShareEntry(ShareType.Teams),
friendsShare = CreateShareEntry(ShareType.Friends),
clansShare = CreateShareEntry(ShareType.Clans)
};
}
private void UpdateData()
{
foreach (var shareData in storedData.playerShareData.Values)
{
CheckShareData(shareData, ShareType.Teams);
CheckShareData(shareData, ShareType.Friends);
CheckShareData(shareData, ShareType.Clans);
}
SaveData();
}
private StoredData.ShareEntry CreateShareEntry(ShareType shareType)
{
var defaultSettings = configData.GetDefaultShareSettings(shareType);
var shareEntry = new StoredData.ShareEntry
{
enabled = defaultSettings.Enabled,
turret = defaultSettings.ShareTurret,
cupboard = defaultSettings.ShareCupboard,
keyLock = new StoredData.LockShareEntry
{
enabled = defaultSettings.KeyLock.Enabled,
door = defaultSettings.KeyLock.ShareDoor,
box = defaultSettings.KeyLock.ShareBox,
other = defaultSettings.KeyLock.ShareOtherEntity
},
codeLock = new StoredData.LockShareEntry
{
enabled = defaultSettings.CodeLock.Enabled,
door = defaultSettings.CodeLock.ShareDoor,
box = defaultSettings.CodeLock.ShareBox,
other = defaultSettings.CodeLock.ShareOtherEntity
}
};
CheckShareData(shareEntry, configData.GetShareSettings(shareType));
return shareEntry;
}
private void CheckShareData(StoredData.ShareData shareData, ShareType shareType)
{
var shareSettings = configData.GetShareSettings(shareType);
var shareEntry = shareData.GetShareEntry(shareType);
CheckShareData(shareEntry, shareSettings);
}
#endregion Data
#region Conflict Resolution
private bool IsBankBox(BaseNetworkable entity)
{
return Bank != null && Bank.Call<bool>("IsBankBox", entity);
}
#endregion Conflict Resolution
#endregion Methods
#region External Plugins
#region Teams
#region Hooks
private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam playerTeam, BasePlayer player)
{
NextTick(() =>
{
if (playerTeam == null || player == null)
{
return;
}
if (playerTeam.members.Contains(player.userID))
{
UpdateTeamAuthList(playerTeam.members);
}
});
}
private void OnTeamLeave(RelationshipManager.PlayerTeam playerTeam, BasePlayer player)
{
NextTick(() =>
{
if (playerTeam == null || player == null)
{
return;
}
if (!playerTeam.members.Contains(player.userID))
{
var teamMembers = new List<ulong>(playerTeam.members) { player.userID };
UpdateTeamAuthList(teamMembers);
}
});
}
private void OnTeamKick(RelationshipManager.PlayerTeam playerTeam, BasePlayer leader, ulong target)
{
NextTick(() =>
{
if (playerTeam == null)
{
return;
}
if (!playerTeam.members.Contains(target))
{
var teamMembers = new List<ulong>(playerTeam.members) { target };
UpdateTeamAuthList(teamMembers);
}
});
}
private void OnTeamDisbanded(RelationshipManager.PlayerTeam playerTeam)
{
if (playerTeam == null)
{
return;
}
UpdateTeamAuthList(playerTeam.members);
}
#endregion Hooks
private void UpdateTeamAuthList(List<ulong> teamMembers)
{
if (teamMembers.Count <= 0)
{
return;
}
foreach (var member in teamMembers)
{
UpdateAuthList(member, AutoAuthType.All);
}
}
private static IEnumerable<ulong> GetTeamMembers(ulong playerId)
{
if (!RelationshipManager.TeamsEnabled())
{
return null;
}
var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerId);
return playerTeam?.members;
}
private static bool SameTeam(ulong playerId, ulong friendId)
{
if (!RelationshipManager.TeamsEnabled())
{
return false;
}
var playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerId);
if (playerTeam == null)
{
return false;
}
var friendTeam = RelationshipManager.ServerInstance.FindPlayersTeam(friendId);
if (friendTeam == null)
{
return false;
}
return playerTeam == friendTeam;
}
#endregion Teams
#region Friends
#region Hooks
private void OnFriendAdded(string playerId, string friendId)
{
UpdateFriendAuthList(playerId, friendId);
}
private void OnFriendRemoved(string playerId, string friendId)
{
UpdateFriendAuthList(playerId, friendId);
}
#endregion Hooks
private void UpdateFriendAuthList(string playerId, string friendId)
{
UpdateAuthList(Convert.ToUInt64(playerId), AutoAuthType.All);
UpdateAuthList(Convert.ToUInt64(friendId), AutoAuthType.All);
}
private IEnumerable<ulong> GetFriends(ulong playerId)
{
if (Friends == null)
{
return null;
}
var friends = Friends.Call("GetFriends", playerId) as ulong[];
return friends;
}
private bool HasFriend(ulong playerId, ulong friendId)
{
if (Friends == null)
{
return false;
}
var hasFriend = Friends.Call("HasFriend", playerId, friendId);
return hasFriend is bool && (bool)hasFriend;
}
#endregion Friends
#region Clans
#region Hooks
private void OnClanDestroy(string clanName)
{
UpdateClanAuthList(clanName);
}
private void OnClanUpdate(string clanName)
{
UpdateClanAuthList(clanName);
}
#region Clans Reborn Hooks
private void OnClanMemberGone(string playerId, List<string> memberUserIDs)
{
UpdateAuthList(Convert.ToUInt64(playerId), AutoAuthType.All);
}
#endregion Clans Reborn Hooks
#endregion Hooks
private void UpdateClanAuthList(string clanName)
{
var clanMembers = GetClanMembers(clanName);
if (clanMembers != null)
{
foreach (var member in clanMembers)
{
UpdateAuthList(member, AutoAuthType.All);
}
}
}
private IEnumerable<ulong> GetClanMembers(ulong playerId)
{
if (Clans == null)
{
return null;
}
//Clans Reborn
var members = Clans.Call("GetClanMembers", playerId) as List<string>;
if (members != null)
{
return members.Select(x => Convert.ToUInt64(x));
}
//Clans
var clanName = Clans.Call("GetClanOf", playerId) as string;
return clanName != null ? GetClanMembers(clanName) : null;
}
private IEnumerable<ulong> GetClanMembers(string clanName)
{
if (Clans == null)
{
return null;
}
var clan = Clans.Call("GetClan", clanName) as JObject;
var members = clan?.GetValue("members") as JArray;
return members?.Select(Convert.ToUInt64);
}
private bool SameClan(ulong playerId, ulong friendId)
{
if (Clans == null)
{
return false;
}
//Clans and Clans Reborn
var isMember = Clans.Call("IsClanMember", playerId.ToString(), friendId.ToString());
if (isMember != null)
{
return (bool)isMember;
}
//Rust:IO Clans
var playerClan = Clans.Call("GetClanOf", playerId);
if (playerClan == null)
{
return false;
}
var friendClan = Clans.Call("GetClanOf", friendId);
if (friendClan == null)
{
return false;
}
return (string)playerClan == (string)friendClan;
}
#endregion Clans
#endregion External Plugins
#region UI
private const string UINAME_MAIN = "AutoAuthUI_Main";
private const string UINAME_MENU = "AutoAuthUI_Menu";
private void CreateMainUI(BasePlayer player)
{
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
Image = { Color = "0 0 0 0.6" },
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-390 -200", OffsetMax = "390 260" },
CursorEnabled = true
}, "Hud", UINAME_MAIN);
var titlePanel = container.Add(new CuiPanel
{
Image = { Color = "0.31 0.88 0.71 1" },
RectTransform = { AnchorMin = "0 0.912", AnchorMax = "0.998 1" }
}, UINAME_MAIN);
container.Add(new CuiElement
{
Parent = titlePanel,
Components =
{
new CuiTextComponent { Text = Lang("UI_Title", player.UserIDString), FontSize = 24, Align = TextAnchor.MiddleCenter, Color = "1 0 0 1" },
new CuiOutlineComponent { Distance = "0.5 0.5", Color = "1 1 1 1" },
new CuiRectTransformComponent { AnchorMin = "0.2 0", AnchorMax = "0.8 1" }
}
});
container.Add(new CuiButton
{
Button = { Color = "0.95 0.1 0.1 0.95", Close = UINAME_MAIN },
Text = { Text = "X", Align = TextAnchor.MiddleCenter, Color = "0 0 0 1", FontSize = 22 },
RectTransform = { AnchorMin = "0.915 0", AnchorMax = "1 0.99" }
}, titlePanel);
container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.4" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.908" }
}, UINAME_MAIN, UINAME_MENU);
CuiHelper.DestroyUi(player, UINAME_MAIN);
CuiHelper.AddUi(player, container);
var shareData = GetShareData(player.userID, true);
UpdateMenuUI(player, shareData);
}
private void UpdateMenuUI(BasePlayer player, StoredData.ShareData shareData, ShareType shareType = ShareType.None)
{
if (player == null)
{
return;
}
var availableTypes = GetAvailableTypes();
var total = availableTypes.Count();
if (total <= 0)
{
return;
}
var i = 0;
var container = new CuiElementContainer();
#region Teams UI
if (availableTypes.Contains(ShareType.Teams))
{
if (shareType == ShareType.None || shareType == ShareType.Teams)
{
var anchors = GetMenuSubAnchors(i, total);
CuiHelper.DestroyUi(player, UINAME_MENU + ShareType.Teams);
CreateMenuSubUI(ref container, shareData, player.UserIDString, ShareType.Teams, $"{anchors[0]} 0.03", $"{anchors[1]} 0.97");
}
i++;
}
#endregion Teams UI
#region Friends UI
if (availableTypes.Contains(ShareType.Friends))
{
if (shareType == ShareType.None || shareType == ShareType.Friends)
{
var anchors = GetMenuSubAnchors(i, total);
CuiHelper.DestroyUi(player, UINAME_MENU + ShareType.Friends);
CreateMenuSubUI(ref container, shareData, player.UserIDString, ShareType.Friends, $"{anchors[0]} 0.03", $"{anchors[1]} 0.97");
}
i++;
}
#endregion Friends UI
#region Clans UI
if (availableTypes.Contains(ShareType.Clans))
{
if (shareType == ShareType.None || shareType == ShareType.Clans)
{
var anchors = GetMenuSubAnchors(i, total);
CuiHelper.DestroyUi(player, UINAME_MENU + ShareType.Clans);
CreateMenuSubUI(ref container, shareData, player.UserIDString, ShareType.Clans, $"{anchors[0]} 0.03", $"{anchors[1]} 0.97");
}
}
#endregion Clans UI
CuiHelper.AddUi(player, container);
}
private void CreateMenuSubUI(ref CuiElementContainer container, StoredData.ShareData shareData, string playerId, ShareType shareType, string anchorMin, string anchorMax)
{
var panelName = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.5" },
RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax }
}, UINAME_MENU, UINAME_MENU + shareType);
var titlePanel = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.5" },
RectTransform = { AnchorMin = "0 0.9", AnchorMax = "1 1" }
}, panelName);
container.Add(new CuiLabel
{
Text = { Color = "1 0.5 0 1", FontSize = 18, Align = TextAnchor.MiddleCenter, Text = Lang("UI_SubTitle", playerId, Lang("UI_" + shareType, playerId)) },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
}, titlePanel);
var contentPanel = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.55" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.895" }
}, panelName);
var i = 0;
const float entrySize = 0.08f;
const float spacingY = 0.012f;
var shareEntry = shareData.GetShareEntry(shareType);
var commandPrefix = $"AutoAuthUI {shareType} ";
var enabledMsg = Lang("Enabled", playerId);
var disabledMsg = Lang("Disabled", playerId);
var anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix, Lang("UI_SubShare", playerId, Lang("UI_" + shareType, playerId)),
shareEntry.enabled ? enabledMsg : disabledMsg, $"0 {anchors[0]}",
$"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "Cupboard", Lang("UI_SubCupboard", playerId),
shareEntry.cupboard ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "Turret", Lang("UI_SubTurret", playerId),
shareEntry.turret ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock", Lang("UI_SubKeyLock", playerId),
shareEntry.keyLock.enabled ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock Door", Lang("UI_SubKeyLockDoor", playerId),
shareEntry.keyLock.door ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock Box", Lang("UI_SubKeyLockBox", playerId),
shareEntry.keyLock.box ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "KeyLock Other", Lang("UI_SubKeyLockOther", playerId),
shareEntry.keyLock.other ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock", Lang("UI_SubCodeLock", playerId),
shareEntry.codeLock.enabled ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock Door", Lang("UI_SubCodeLockDoor", playerId),
shareEntry.codeLock.door ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock Box", Lang("UI_SubCodeLockBox", playerId),
shareEntry.codeLock.box ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
anchors = GetEntryAnchors(i++, entrySize, spacingY);
CreateEntrySubUI(ref container, contentPanel, commandPrefix + "CodeLock Other", Lang("UI_SubCodeLockOther", playerId),
shareEntry.codeLock.other ? enabledMsg : disabledMsg, $"0 {anchors[0]}", $"0.995 {anchors[1]}");
}
private static void CreateEntrySubUI(ref CuiElementContainer container, string parentName, string command, string leftText, string rightText, string anchorMin, string anchorMax)
{
var panelName = container.Add(new CuiPanel
{
Image = { Color = "0.1 0.1 0.1 0.6" },
RectTransform = { AnchorMin = anchorMin, AnchorMax = anchorMax }
}, parentName);
container.Add(new CuiLabel
{
Text = { Color = "0 1 1 1", FontSize = 12, Align = TextAnchor.MiddleLeft, Text = leftText },
RectTransform = { AnchorMin = "0.04 0", AnchorMax = "0.68 1" }
}, panelName);
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0.7", Command = command },
Text = { Text = rightText, Align = TextAnchor.MiddleCenter, Color = "1 1 1 1", FontSize = 12 },
RectTransform = { AnchorMin = "0.7 0.2", AnchorMax = "0.985 0.8" }
}, panelName);
}
private static float[] GetEntryAnchors(int i, float entrySize, float spacingY)
{
return new[] { 1f - (i + 1) * entrySize - i * spacingY, 1f - i * (entrySize + spacingY) };
}
private static float[] GetMenuSubAnchors(int i, int total)
{
switch (total)
{
case 1:
return new[] { 0.32f, 0.68f };
case 2:
return i == 0 ? new[] { 0.15f, 0.48f } : new[] { 0.52f, 0.85f };
case 3:
switch (i)
{
case 0:
return new[] { 0.01f, 0.33f };
case 1:
return new[] { 0.34f, 0.66f };
default:
return new[] { 0.67f, 0.99f };
}
default:
return null;
}
}
private static void DestroyUI(BasePlayer player)
{
CuiHelper.DestroyUi(player, UINAME_MAIN);
}
#endregion UI
#region Chat Commands
private void CmdAutoAuth(BasePlayer player, string command, string[] args)
{
if (!permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
{
Print(player, Lang("NotAllowed", player.UserIDString));
return;
}
var shareData = GetShareData(player.userID);
if (args == null || args.Length == 0)
{
var availableTypes = GetAvailableTypes();
// ... [Code preview truncated due to length. Full source in attached file] ...