Иконка ресурса

FREE HeliNetworkFix : 0.0.1 0.0.1

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using ConVar;
using Newtonsoft.Json;
using UnityEngine;
using System.Linq;
using Debug = UnityEngine.Debug;

namespace Oxide.Plugins
{
    [Info("Heli Network Fix", "ViolationHandler", "0.0.1")]
    [Description("Fixes networking issues while speeding in helicopters.")]
    public class HeliNetworkFix : RustPlugin
    {
	    private HashSet<NetworkFix> componentList = new HashSet<NetworkFix>();
	    
	    private Configuration config;
	    
	    #region Configuration

	    private class Configuration
	    {
		    [JsonProperty("The minimum speed required for this to take effect. (Increasing this will make it so the helicopter needs to be faster to trigger this effect)")]
		    public double speedMinimum = 20;

		    [JsonProperty("Distance forward to render.")]
		    public float renderDistance = 3.75f;

		    [JsonProperty("The minimum amount of time before attempting to load the area in front of the player.")]
		    public double minimumTimeSince = 1;

		    [JsonProperty("The value required to load the area in front of the player. Determined by speed.")]
		    public double minimumSpeedMultipliedValue = 37.5;

		    private string ToJson() => JsonConvert.SerializeObject(this);

		    public Dictionary<string, object> ToDictionary() =>
			    JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
	    }


	    protected override void LoadDefaultConfig() => config = new Configuration();

	    protected override void LoadConfig()
	    {
		    base.LoadConfig();
		    try
		    {
			    config = Config.ReadObject<Configuration>();
			    if (config == null)
			    {
				    throw new JsonException();
			    }

			    if (!config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys))
			    {
				    Puts("Configuration appears to be outdated; updating and saving.");
				    SaveConfig();
			    }
		    }
		    catch
		    {
			    Puts($"Configuration file {Name}.json is invalid; using defaults");
			    LoadDefaultConfig();
		    }
	    }

	    protected override void SaveConfig()
	    {
		    Puts($"Configuration changes saved to {Name}.json");
		    Config.WriteObject(config, true);
	    }
        
	    #endregion Configuration
	    
	    private void Init()
	    {
		    LoadConfig();
	    }
	    
	    private void Unload()
	    {
		    foreach (NetworkFix fix in componentList)
		    {
			    if (fix == null) continue; // if its somehow null
			    
			    fix.onUnload = true;
			    fix.OnDestroy();
		    }

		    componentList = null;
	    }
         
        #region Hooks

        private void OnEntityDismounted(BaseMountable entity, BasePlayer player)
        {
	        if (entity == null || player == null) return;
	        BaseVehicle vehicle = entity.GetParentEntity() as BaseVehicle;

	        if (vehicle == null || vehicle is not PlayerHelicopter) return;

	        NextTick(() => {RemoveComponent(vehicle, player, true);});
        }
        
        private void OnEntityMounted(BaseMountable entity, BasePlayer player)
        {
	        if (entity == null || player == null) return;
	        BaseVehicle vehicle = entity.GetParentEntity() as BaseVehicle;
        
	        if (vehicle == null || vehicle is not PlayerHelicopter) return;
	        
	        AddComponent(vehicle, player);
        }

        #endregion Hooks
        
        #region Helper Methods
        
        private bool AddComponent(BaseVehicle vehicle, BasePlayer player)
        {
	        NetworkFix fix = vehicle.GetComponent<NetworkFix>();
	        
	        if (fix != null)
	        {
		        fix.allPassengers.Add(player);
		        
		        return false;
	        }
	        
	        fix = vehicle.gameObject.AddComponent<NetworkFix>();
	        
	        fix.vehicle = vehicle;
	        fix.speedMinimum = config.speedMinimum;
	        fix.renderDistance = config.renderDistance;
	        fix.minimumTimeSince = config.minimumTimeSince;
	        fix.minimumSpeedMultipliedValue = config.minimumSpeedMultipliedValue;
	        
	        fix._instance = this;
	        
	        fix.allPassengers.Add(player);
	        
	        componentList.Add(fix);
	        return true;
        }

        private bool RemoveComponent(BaseVehicle vehicle, BasePlayer player, bool hook = false)
        {
	        if (vehicle == null)
	        {
		        ResetSecondaryNetworkGroup(player.net);
		        return false;
	        }
	        
	        NetworkFix fix = vehicle.GetComponent<NetworkFix>();
	        
	        if (fix == null) return false;
	        
	        if(hook)
	        {
		        if (vehicle.AnyMounted())
		        {
			        if(!IsPlayerMountedInVehicle(player, vehicle)) ResetSecondaryNetworkGroup(player.net);
			        
			        return false;
		        }
		        
		        componentList.Remove(fix);
		        UnityEngine.Object.Destroy(fix);
		        return true;
	        }
	        
	        componentList.Remove(fix);
	        UnityEngine.Object.Destroy(fix);
	        return true;
        }

        public bool IsPlayerMountedInVehicle(BasePlayer player, BaseVehicle vehicle)
        {
	        if (vehicle.mountPoints?.Count <= 0) return false;
	        foreach (BaseVehicle.MountPointInfo mountPoint in vehicle.mountPoints)
	        {
		        if (player == mountPoint.mountable?.GetMounted()) return true;
	        }
	        return false;
        }

        public bool ResetSecondaryNetworkGroup(Network.Networkable net)
        {
	        if (net == null) return false;
	        net.SwitchSecondaryGroup(null);
	        net.OnSubscriptionChange();
	        return true;
        }
        #endregion Helper Methods
        
        #region Custom Class
        public class NetworkFix : FacepunchBehaviour
        {
            public BasePlayer player;
            private Network.Visibility.Group group;
            public BaseVehicle vehicle;

            public HeliNetworkFix _instance;

            public HashSet<BasePlayer> allPassengers = new HashSet<BasePlayer>();
            
            private Vector3 projectedPosition = Vector3.zero;

            public bool onUnload = false;
            
            private float lastCalled;
            public float SinceCalled;

            public double minimumTimeSince = 1;
            public double minimumSpeedMultipliedValue = 37.5;

            public float renderDistance = 4;
            
            public float speed;
            public double speedMinimum;
            public void Awake()
            {
	            lastCalled = UnityEngine.Time.realtimeSinceStartup;
            }

            public void FixedUpdate()
            {
	            if (vehicle == null || !vehicle.IsOn()) return;
	            
	            SinceCalled = UnityEngine.Time.realtimeSinceStartup - lastCalled;
	            
	            speed = Vector3.Dot(vehicle.GetLocalVelocity(), vehicle.transform.forward);

	            if (SinceCalled > 5 && speed < speedMinimum)
		        {
			        foreach (BaseVehicle.MountPointInfo mountPoint in vehicle.mountPoints)
			        {
				        player = mountPoint.mountable.GetMounted();
				        
				        if ((object)player == null) continue;
				        
				        ResetSecondaryNetworkGroup(player.net);
			        }

			        foreach (BaseEntity child in vehicle.children)
			        {
				        player = child as BasePlayer;
				        
				        if ((object)player == null) continue;

				        ResetSecondaryNetworkGroup(player.net);
			        }

			        SinceCalled = 0;
			        return;
		        }
	            
	            
		        if (speed < speedMinimum || SinceCalled < minimumTimeSince || speed * SinceCalled < minimumSpeedMultipliedValue) return;

		        
		        Vector3 position = Vector3.zero;
		        
		        foreach (BaseVehicle.MountPointInfo mountPoint in vehicle.mountPoints)
		        {
			        player = mountPoint.mountable.GetMounted();
			        
			        if ((object)player == null) continue;
			        
			        if(position == Vector3.zero) position = player.transform.position;
			        
			        if(projectedPosition == Vector3.zero) projectedPosition = position + player.eyes.HeadForward() * (speed * renderDistance);
			        
			        projectedPosition.y = position.y-5;
			        
			        if (group == null) group = player.net.sv.visibility.GetGroup(projectedPosition);

			        if (group.networkables.Contains(player.net)) continue; 
			        
			        player.net.SwitchSecondaryGroup(group);
			        player.net.OnSubscriptionChange();
		        }
		        
		        foreach (BaseEntity child in vehicle.children)
		        {
			        player = child as BasePlayer;
			        if ((object)player == null) continue;
			        
			        allPassengers.Add(player);
			        
			        if (projectedPosition == Vector3.zero || group.networkables.Contains(player.net)) continue; 
			        
			        player.net.SwitchSecondaryGroup(group);
			        player.net.OnSubscriptionChange();
		        }
		        
		        projectedPosition = Vector3.zero;
		        group = null;
	            lastCalled = UnityEngine.Time.realtimeSinceStartup;
            }
            
            public bool ResetSecondaryNetworkGroup(Network.Networkable net)
            {
	            if (net == null) return false;
	            net.SwitchSecondaryGroup(null);
	            net.OnSubscriptionChange();
	            return true;
            }

            public void OnDestroy()
            {
	            vehicle = null;
	            group = null;
	            
	            if(allPassengers != null)
	            {
		            foreach (BasePlayer foundPlayer in allPassengers)
		            {
			            ResetSecondaryNetworkGroup(foundPlayer?.net);
		            }
	            }

	            allPassengers = null;
	            player = null;

	            if(!onUnload) _instance.componentList.Remove(this);
                Destroy(this);
            }
        }
        #endregion Custom Class
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху