C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using CompanionServer.Handlers;
using Network;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("SAM Site Map", "Arainrr", "1.4.0")]
[Description("Mark all SAM sites on the map")]
internal class SamSiteMap : RustPlugin
{
#region Fields
private const string PERMISSION_USE = "samsitemap.use";
private const string PREFAB_MARKER = "assets/prefabs/tools/map/genericradiusmarker.prefab";
private const string PREFAB_TEXT = "assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab";
private static SamSiteMap _instance;
#endregion Fields
#region Oxide Hooks
private void Init()
{
_instance = this;
Unsubscribe(nameof(OnEntitySpawned));
permission.RegisterPermission(PERMISSION_USE, this);
}
private void OnServerInitialized()
{
Subscribe(nameof(OnEntitySpawned));
foreach (var severEntity in BaseNetworkable.serverEntities)
{
var samSite = severEntity as SamSite;
if (samSite != null)
{
CreateMapMarker(samSite);
}
}
foreach (var player in BasePlayer.activePlayerList)
{
OnPlayerConnected(player);
}
}
private void Unload()
{
SamSiteMapMarker.DestroyAll();
_instance = null;
}
private void OnPlayerConnected(BasePlayer player)
{
if (player == null || !player.IsConnected) return;
if (player.IsReceivingSnapshot)
{
timer.Once(1f, () => OnPlayerConnected(player));
return;
}
if (configData.usePermission)
{
SamSiteMapMarker.SendSnapshotToPlayer(player);
return;
}
SamSiteMapMarker.SendUpdateToPlayers();
}
private void OnEntitySpawned(SamSite samSite)
{
CreateMapMarker(samSite);
}
#endregion Oxide Hooks
#region Methods
private void CreateMapMarker(SamSite samSite)
{
var settings = GetSamSiteSettings(samSite);
if (!settings.enabled)
{
return;
}
if (samSite.GetComponent<SamSiteMapMarker>() != null)
{
return;
}
samSite.gameObject.AddComponent<SamSiteMapMarker>().Init(settings, configData.usePermission, configData.checkInterval);
}
private SamSiteSettings GetSamSiteSettings(SamSite samSite)
{
return samSite.OwnerID == 0 ? configData.staticSamS : configData.playerSamS;
}
#endregion Methods
#region MapMarker
private class SamSiteMapMarker : MonoBehaviour
{
#region Static
private static List<SamSiteMapMarker> _mapMarkers;
public static void DestroyAll()
{
if (_mapMarkers == null) return;
foreach (var samMapMarker in _mapMarkers)
{
Destroy(samMapMarker);
}
_mapMarkers.Clear();
_mapMarkers = null;
}
public static void SendUpdateToPlayers()
{
if (_mapMarkers == null) return;
foreach (var mapMarker in _mapMarkers)
{
if (!mapMarker.CanSeeMapMarker()) continue;
mapMarker.EnableMarkers();
}
}
private static void SendSnapshotToPlayers()
{
if (_mapMarkers == null) return;
foreach (var player in BasePlayer.activePlayerList)
{
SendSnapshotToPlayer(player);
}
}
public static void SendSnapshotToPlayer(BasePlayer player)
{
if (_mapMarkers == null) return;
if (_instance.permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
{
foreach (var mapMarker in _mapMarkers)
{
if (!mapMarker.CanSeeMapMarker()) continue;
mapMarker.UnlimitedMarkers(player.Connection);
}
}
}
#endregion Static
private SamSite _samSite;
private MapMarkerGenericRadius _mapMarker;
private MapMarkerGenericRadius _radiusMapMarker;
private VendingMachineMapMarker _textMapMarker;
private bool _usePermission;
private SamSiteSettings _setting;
private bool _tempCanShow;
private void Awake()
{
if (_mapMarkers == null) _mapMarkers = new List<SamSiteMapMarker>();
_mapMarkers.Add(this);
_samSite = GetComponent<SamSite>();
}
public void Init(SamSiteSettings settings, bool usePermission, float checkInterval)
{
_setting = settings;
_usePermission = usePermission;
SpawnMapMarkers(settings.samSiteMarkerSetting, usePermission);
_tempCanShow = CanSeeMapMarker();
if (usePermission)
{
if (_tempCanShow)
{
Show();
}
}
else
{
if (!_tempCanShow)
{
Hide();
}
}
InvokeRepeating(nameof(TimedCheck), checkInterval, checkInterval);
}
private void SpawnMapMarkers(SamSiteMarkerSetting settings, bool usePermission)
{
//Text map marker
if (!string.IsNullOrEmpty(settings.text))
{
_textMapMarker = GameManager.server.CreateEntity(PREFAB_TEXT, _samSite.transform.position) as VendingMachineMapMarker;
if (_textMapMarker != null)
{
_textMapMarker.markerShopName = settings.text;
_textMapMarker.OwnerID = _samSite.OwnerID;
if (usePermission)
{
_textMapMarker.limitNetworking = true;
}
_textMapMarker.Spawn();
if (usePermission)
{
MapMarker.serverMapMarkers.Remove(_textMapMarker);
}
}
}
//Attack range map marker
if (settings.samSiteRadiusMarker.enabled)
{
_radiusMapMarker = GameManager.server.CreateEntity(PREFAB_MARKER, _samSite.transform.position) as MapMarkerGenericRadius;
if (_radiusMapMarker != null)
{
_radiusMapMarker.alpha = settings.samSiteRadiusMarker.alpha;
var color1 = settings.samSiteRadiusMarker.colorl;
if (!ColorUtility.TryParseHtmlString(color1, out _radiusMapMarker.color1))
{
_radiusMapMarker.color1 = Color.black;
_instance.PrintError($"Invalid range map marker color1: {color1}");
}
var color2 = settings.samSiteRadiusMarker.color2;
if (!ColorUtility.TryParseHtmlString(color2, out _radiusMapMarker.color2))
{
_radiusMapMarker.color2 = Color.white;
_instance.PrintError($"Invalid range map marker color2: {color2}");
}
_radiusMapMarker.radius = _samSite.vehicleScanRadius / 145f;
_radiusMapMarker.OwnerID = _samSite.OwnerID;
if (usePermission)
{
_radiusMapMarker.limitNetworking = true;
}
_radiusMapMarker.Spawn();
if (usePermission)
{
MapMarker.serverMapMarkers.Remove(_radiusMapMarker);
}
else
{
_radiusMapMarker.SendUpdate();
}
}
}
//Sam map marker
_mapMarker = GameManager.server.CreateEntity(PREFAB_MARKER, _samSite.transform.position) as MapMarkerGenericRadius;
if (_mapMarker != null)
{
_mapMarker.alpha = settings.alpha;
var color1 = settings.colorl;
if (!ColorUtility.TryParseHtmlString(color1, out _mapMarker.color1))
{
_mapMarker.color1 = Color.black;
_instance.PrintError($"Invalid map marker color1: {color1}");
}
var color2 = settings.color2;
if (!ColorUtility.TryParseHtmlString(color2, out _mapMarker.color2))
{
_mapMarker.color2 = Color.white;
_instance.PrintError($"Invalid map marker color2: {color2}");
}
_mapMarker.radius = settings.radius;
_mapMarker.OwnerID = _samSite.OwnerID;
if (usePermission)
{
_mapMarker.limitNetworking = true;
}
_mapMarker.Spawn();
if (usePermission)
{
MapMarker.serverMapMarkers.Remove(_mapMarker);
}
else
{
_mapMarker.SendUpdate();
}
}
}
private void TimedCheck()
{
var canShow = CanSeeMapMarker();
if (canShow != _tempCanShow)
{
if (canShow)
{
Show();
}
else
{
Hide();
}
}
_tempCanShow = canShow;
}
private bool CanSeeMapMarker()
{
if (_setting.hideWhenNoPower)
{
return _samSite.IsPowered();
}
if (_setting.hideWhenNoAmmo)
{
return _samSite.HasAmmo();
}
return true;
}
private void Show()
{
// _instance.PrintError($"Show : {_usePermission} | {_samSite.OwnerID}");
if (_usePermission)
{
SendSnapshotToPlayers();
}
else
{
EnableMarkers();
}
}
private void Hide()
{
// _instance.PrintError($"Hide : {_usePermission} | {_samSite.OwnerID}");
if (_usePermission)
{
LimitedMarkers();
}
else
{
DisableMarkers();
}
}
#region Methods
private void EnableMarkers()
{
if (_mapMarker != null)
{
if (_mapMarker.limitNetworking)
{
_mapMarker.limitNetworking = false;
_mapMarker.SendNetworkUpdateImmediate();
}
_mapMarker.SendUpdate();
}
if (_radiusMapMarker != null)
{
if (_radiusMapMarker.limitNetworking)
{
_radiusMapMarker.limitNetworking = false;
_radiusMapMarker.SendNetworkUpdateImmediate();
}
_radiusMapMarker.SendUpdate();
}
if (_textMapMarker != null)
{
if (_textMapMarker.limitNetworking)
{
_textMapMarker.limitNetworking = false;
_textMapMarker.SendNetworkUpdateImmediate();
}
_textMapMarker.SendNetworkUpdate();
}
}
private void DisableMarkers()
{
if (_mapMarker != null)
{
_mapMarker.limitNetworking = true;
}
if (_radiusMapMarker != null)
{
_radiusMapMarker.limitNetworking = true;
}
if (_textMapMarker != null)
{
_textMapMarker.limitNetworking = true;
}
}
private void LimitedMarkers()
{
if (_mapMarker != null)
{
_mapMarker.limitNetworking = false;
_mapMarker.limitNetworking = true;
}
if (_radiusMapMarker != null)
{
_radiusMapMarker.limitNetworking = false;
_radiusMapMarker.limitNetworking = true;
}
if (_textMapMarker != null)
{
_textMapMarker.limitNetworking = false;
_textMapMarker.limitNetworking = true;
}
}
private void UnlimitedMarkers(Connection connection)
{
if (_mapMarker != null)
{
_mapMarker.SendAsSnapshot(connection);
_mapMarker.SendUpdate();
}
if (_radiusMapMarker != null)
{
_radiusMapMarker.SendAsSnapshot(connection);
_radiusMapMarker.SendUpdate();
}
if (_textMapMarker != null)
{
_textMapMarker.SendAsSnapshot(connection);
}
}
#endregion Methods
private void OnDestroy()
{
if (_mapMarker != null && !_mapMarker.IsDestroyed)
{
_mapMarker.Kill();
}
if (_radiusMapMarker != null && !_radiusMapMarker.IsDestroyed)
{
_radiusMapMarker.Kill();
}
if (_textMapMarker != null && !_textMapMarker.IsDestroyed)
{
_textMapMarker.Kill();
}
_mapMarkers?.Remove(this);
}
}
#endregion MapMarker
#region ConfigurationFile
private ConfigData configData;
private class ConfigData
{
[JsonProperty(PropertyName = "Use permission")]
public bool usePermission = false;
[JsonProperty(PropertyName = "Time interval to check the show of markers (seconds)")]
public float checkInterval = 5f;
[JsonProperty(PropertyName = "Static SAM settings")]
public SamSiteSettings staticSamS = new SamSiteSettings
{
enabled = true,
samSiteMarkerSetting = new SamSiteMarkerSetting
{
radius = 0.15f,
colorl = "#FF4500",
color2 = "#0000FF",
alpha = 1f,
text = "static sam",
samSiteRadiusMarker = new SamSiteRadiusMarker
{
colorl = "#FFFF00",
color2 = "#FFFFF0",
alpha = 0.5f,
}
},
};
[JsonProperty(PropertyName = "Player's SAM settings")]
public SamSiteSettings playerSamS = new SamSiteSettings
{
enabled = true,
samSiteMarkerSetting = new SamSiteMarkerSetting
{
radius = 0.08f,
colorl = "#00FF00",
color2 = "#0000FF",
alpha = 1f,
text = "player's sam",
samSiteRadiusMarker = new SamSiteRadiusMarker
{
colorl = "#FFFF00",
color2 = "#FFFFF0",
alpha = 0.5f,
}
},
};
}
private class SamSiteSettings
{
[JsonProperty(PropertyName = "Enabled map marker")]
public bool enabled = true;
[JsonProperty(PropertyName = "Hide when no power")]
public bool hideWhenNoPower = true;
[JsonProperty(PropertyName = "Hide when no ammo")]
public bool hideWhenNoAmmo = true;
[JsonProperty(PropertyName = "SAM map marker")]
public SamSiteMarkerSetting samSiteMarkerSetting = new SamSiteMarkerSetting();
}
private class SamSiteMarkerSetting
{
[JsonProperty(PropertyName = "Map marker radius")]
public float radius = 0.08f;
[JsonProperty(PropertyName = "Map marker color1")]
public string colorl = "#00FF00";
[JsonProperty(PropertyName = "Map marker color2")]
public string color2 = "#0000FF";
[JsonProperty(PropertyName = "Map marker alpha")]
public float alpha = 1f;
[JsonProperty(PropertyName = "Map marker text")]
public string text = "sam";
[JsonProperty(PropertyName = "SAM attack range map marker")]
public SamSiteRadiusMarker samSiteRadiusMarker = new SamSiteRadiusMarker();
}
private class SamSiteRadiusMarker
{
[JsonProperty(PropertyName = "Enabled Sam attack range map marker")]
public bool enabled = false;
[JsonProperty(PropertyName = "Range map marker color1")]
public string colorl = "#FFFF00";
[JsonProperty(PropertyName = "Range map marker color2")]
public string color2 = "#FFFFF0";
[JsonProperty(PropertyName = "Range map marker alpha")]
public float alpha = 0.5f;
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
configData = Config.ReadObject<ConfigData>();
if (configData == null)
LoadDefaultConfig();
}
catch
{
PrintError("The configuration file is corrupted");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig()
{
PrintWarning("Creating a new configuration file");
configData = new ConfigData();
}
protected override void SaveConfig() => Config.WriteObject(configData);
#endregion ConfigurationFile
}
}