C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
namespace Oxide.Plugins
{
[Info("Online Quarries", "mvrb/Arainrr", "1.2.8", ResourceId = 2216)]
[Description("Automatically disable players' quarries when offline")]
public class OnlineQuarries : RustPlugin
{
#region Fields
[PluginReference]
private Plugin Friends, Clans;
private readonly Dictionary<ulong, Timer> _stopEngineTimer = new Dictionary<ulong, Timer>();
private readonly HashSet<MiningQuarry> _miningQuarries = new HashSet<MiningQuarry>();
#endregion Fields
#region Oxide Hooks
private void Init()
{
Unsubscribe(nameof(OnEntityDistanceCheck));
}
private void OnServerInitialized()
{
if (configData.preventOther)
{
Subscribe(nameof(OnEntityDistanceCheck));
}
foreach (var miningQuarry in BaseNetworkable.serverEntities.OfType<MiningQuarry>())
{
OnEntitySpawned(miningQuarry);
}
CheckQuarries();
}
private void OnEntitySpawned(MiningQuarry miningQuarry)
{
if (miningQuarry == null || miningQuarry.OwnerID == 0)
{
return;
}
_miningQuarries.Add(miningQuarry);
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null)
{
return;
}
Timer value;
if (_stopEngineTimer.TryGetValue(player.userID, out value))
{
value?.Destroy();
_stopEngineTimer.Remove(player.userID);
}
if (configData.autoStart)
{
CheckQuarries(player, true);
}
}
private void OnPlayerDisconnected(BasePlayer player)
{
if (player == null)
{
return;
}
var playerId = player.userID;
Timer value;
if (_stopEngineTimer.TryGetValue(playerId, out value))
{
value?.Destroy();
_stopEngineTimer.Remove(playerId);
}
_stopEngineTimer.Add(playerId, timer.Once(configData.offlineTime, () =>
{
CheckQuarries();
_stopEngineTimer.Remove(playerId);
}));
}
private object OnEntityDistanceCheck(EngineSwitch engineSwitch, BasePlayer player, uint id, string debugName, float maximumDistance)
{
if (player == null || engineSwitch == null)
{
return null;
}
if (id == 1739656243u && debugName == "StopEngine" || id == 1249530220u && debugName == "StartEngine")
{
var parentEntity = engineSwitch.GetParentEntity();
if (parentEntity == null || !parentEntity.OwnerID.IsSteamId())
{
return null;
}
if (AreFriends(parentEntity.OwnerID, player.userID))
{
return false;
}
}
return null;
}
#endregion Oxide Hooks
#region Methods
private void CheckQuarries(BasePlayer player = null, bool isOn = false)
{
foreach (var miningQuarry in _miningQuarries)
{
if (miningQuarry == null)
{
continue;
}
if (player != null)
{
if (AreFriends(miningQuarry.OwnerID, player.userID))
{
miningQuarry.SetOn(isOn);
}
continue;
}
if (!AnyOnlineFriends(miningQuarry.OwnerID))
{
miningQuarry.SetOn(isOn);
}
}
}
private bool AnyOnlineFriends(ulong playerId)
{
foreach (var friend in BasePlayer.activePlayerList)
{
if (AreFriends(playerId, friend.userID))
{
return true;
}
}
return false;
}
#region AreFriends
private bool AreFriends(ulong playerID, ulong friendID)
{
if (playerID == friendID)
{
return true;
}
if (configData.useTeam && SameTeam(friendID, playerID))
{
return true;
}
if (configData.useFriends && HasFriend(friendID, playerID))
{
return true;
}
if (configData.useClans && SameClan(friendID, playerID))
{
return true;
}
return false;
}
private 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;
}
private bool HasFriend(ulong playerID, ulong friendID)
{
if (Friends == null)
{
return false;
}
return (bool)Friends.Call("HasFriend", playerID, friendID);
}
private bool SameClan(ulong playerID, ulong friendID)
{
if (Clans == null)
{
return false;
}
//Clans
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 AreFriends
#endregion Methods
#region ConfigurationFile
private ConfigData configData;
private class ConfigData
{
[JsonProperty(PropertyName = "Use team")]
public readonly bool useTeam = false;
[JsonProperty(PropertyName = "Use clans")]
public readonly bool useClans = false;
[JsonProperty(PropertyName = "Use friends")]
public readonly bool useFriends = false;
[JsonProperty(PropertyName = "Prevent other players from turning the quarry on or off")]
public readonly bool preventOther = false;
[JsonProperty(PropertyName = "Automatically disable the delay of quarry (seconds)")]
public readonly float offlineTime = 120f;
[JsonProperty(PropertyName = "Quarry automatically starts after players are online")]
public readonly bool autoStart = true;
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
configData = Config.ReadObject<ConfigData>();
if (configData == null)
{
LoadDefaultConfig();
}
}
catch (Exception ex)
{
PrintError($"The configuration file is corrupted.\n{ex}");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig()
{
PrintWarning("Creating a new configuration file");
configData = new ConfigData();
}
protected override void SaveConfig()
{
Config.WriteObject(configData);
}
#endregion ConfigurationFile
}
}