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

FREE CCTVControl : 1.0.14 1.0.14

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
#region License (GPL v2)
/*
    CCTV Control
    Copyright (c) 2020-2023 RFC1920 <desolationoutpostpve@gmail.com>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the license only.This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
    GNU General Public License for more details.You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.Optionally you can also view the license at <http://www.gnu.org/licenses/>.*/
#endregion License Information (GPL v2)
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("CCTVControl", "RFC1920", "1.0.14")]
    [Description("Allows players to add CCTV cameras to a Computer Station and control them remotely")]
    internal class CCTVControl : RustPlugin
    {
        #region vars
        private ConfigData configData;
        private readonly Plugin Clans, Friends, RustIO;
        private const string permCCTV = "cctvcontrol.use";
        private const string permCCTVAdmin = "cctvcontrol.admin";
        private const string permCCTVList = "cctvcontrol.list";
        private readonly string moveSound = "assets/prefabs/deployable/playerioents/detectors/hbhfsensor/effects/detect_up.prefab";
        private readonly int targetLayer = LayerMask.GetMask("Construction", "Construction Trigger", "Default", "Trigger", "Deployed", "AI", "Deployable");

        private float mapSize;
        #endregion

        #region Message
        private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
        private void Message(IPlayer player, string key, params object[] args) => player.Reply(Lang(key, player.Id, args));
        #endregion

        #region init
        private void Init()
        {
            AddCovalenceCommand("cctv", "cmdCCTV");
            AddCovalenceCommand("cctvlist", "cmdCCTVList");

            permission.RegisterPermission(permCCTV, this);
            permission.RegisterPermission(permCCTVAdmin, this);
            permission.RegisterPermission(permCCTVList, this);
        }

        private void DestroyAll<T>()
        {
            Object[] objects = UnityEngine.Object.FindObjectsOfType(typeof(T));
            if (objects != null)
            {
                foreach (Object gameObj in objects)
                {
                    UnityEngine.Object.Destroy(gameObj);
                }
            }
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["notauthorized"] = "You are not authorized to use this command!",
                ["foundCamera"] = "Found Camera {0} owned by {1}",
                ["foundDrone"] = "Found Drone {0} owned by {1}",
                ["foundCameras"] = "Found Cameras:",
                ["foundDrones"] = "Found Drones:",
                ["cameraexists"] = "Camera {0} already in station",
                ["ownedby"] = " owned by ",
                ["server"] = "Server",
                ["unknown"] = "Unknown",
                ["foundStation"] = "Found ComputerStation...",
                ["noStation"] = "No ComputerStation found...",
                ["helptext1"] = "CCTV Control Instructions:",
                ["helptext2"] = "  type /cctv to add your local cameras",
            }, this);
        }

        private void Loaded()
        {
            mapSize = ConVar.Server.worldsize > 0 ? ConVar.Server.worldsize : 4000f;
            LoadVariables();
        }
        #endregion

        #region Config
        public class ConfigData
        {
            public bool debug;
            public float userRange;
            public float adminRange;
            public bool useFriends;
            public bool useClans;
            public bool useTeams;
            public bool userMapWide;
            public bool blockServerCams;
            public bool playSound;
            public bool playAtCamera;

            public VersionNumber Version;
        }

        protected override void LoadDefaultConfig()
        {
            Puts("Creating new config file.");
            ConfigData config = new()
            {
                debug = false,
                userRange = 200f,
                adminRange = 4000f,
                useFriends = false,
                useClans = false,
                useTeams = false,
                userMapWide = false,
                blockServerCams = false,
                playSound = true,
                playAtCamera = true,
                Version = Version
            };
            SaveConfig(config);
        }

        private void LoadConfigVariables()
        {
            configData = Config.ReadObject<ConfigData>();
            configData.Version = Version;
            SaveConfig(configData);
        }

        private void SaveConfig(ConfigData config)
        {
            Config.WriteObject(config, true);
        }

        private void LoadVariables()
        {
            LoadConfigVariables();
            SaveConfig();
        }
        #endregion

        #region Main
        //private object OnCCTVDirectionChange(CCTV_RC camera, BasePlayer player)
        //{
        //    Puts("Moving light to match camera");
        //    BaseEntity sl = camera.gameObject.GetComponentInChildren<SimpleLight>() as BaseEntity;
        //    //sl.transform.forward = new Vector3(camera.pivotOrigin.forward.x, sl.transform.forward.y, camera.pivotOrigin.forward.z);
        //    sl.transform.forward = new Vector3(camera.transform.forward.x, sl.transform.forward.y, camera.transform.forward.z);
        //    return null;
        //}

        private void OnEntityMounted(BaseMountable mountable, BasePlayer player)
        {
            ComputerStation station = mountable.GetComponentInParent<ComputerStation>();
            if (station != null && (configData.blockServerCams && !player.IPlayer.HasPermission(permCCTVAdmin)))
            {
                if (configData.debug) Puts("OnEntityMounted: player mounted CS!");
                List<string> toremove = new();
                foreach (string bm in station.controlBookmarks)
                {
                    IRemoteControllable realcam = RemoteControlEntity.FindByID(bm);
                    BaseEntity ent = realcam.GetEnt();
                    if (ent == null) continue;
                    string cname = realcam.GetIdentifier();
                    if (cname == null) continue;
                    if (ent.OwnerID == 0)
                    {
                        toremove.Add(cname);
                    }
                }
                foreach (string cn in toremove)
                {
                    station.controlBookmarks.Remove(cn);
                }
                station.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                station.SendControlBookmarks(player);
            }
        }

        private void OnEntityDismounted(BaseMountable mountable, BasePlayer player)
        {
            ComputerStation station = mountable.GetComponentInParent<ComputerStation>();
            if (station != null)
            {
                if (configData.debug) Puts("OnEntityMounted: player dismounted CS!");
            }
        }

        public void RemoveComps(BaseEntity obj)
        {
            UnityEngine.Object.DestroyImmediate(obj.GetComponent<DestroyOnGroundMissing>());
            UnityEngine.Object.DestroyImmediate(obj.GetComponent<GroundWatch>());
            foreach (MeshCollider mesh in obj.GetComponentsInChildren<MeshCollider>())
            {
                UnityEngine.Object.DestroyImmediate(mesh);
            }
        }

        [Command("cctv")]
        private void cmdCCTV(IPlayer iplayer, string command, string[] args)
        {
            if (!(iplayer.Object is BasePlayer)) return;
            if (!iplayer.HasPermission(permCCTV)) { Message(iplayer, "notauthorized"); return; }
            BasePlayer player = iplayer.Object as BasePlayer;

            List<ComputerStation> stations = new();
            Vis.Entities(player.transform.position, 2f, stations);
            bool foundS = false;

            string cmd;
            if (args.Length == 0) cmd = null;
            else cmd = args[0];

            switch (cmd)
            {
                case "clear":
                    foreach (ComputerStation station in stations)
                    {
                        station.controlBookmarks.Clear();
                        station.SendControlBookmarks(player);
                    }
                    break;
                //case "rename":
                //    {
                //        List<CCTV_RC> cameras = new();
                //        Vis.Entities(player.transform.position, 2f, cameras);
                //        foreach (CCTV_RC cam in cameras)
                //        {
                //            cam.UpdateIdentifier(args[1]);
                //            break;
                //        }
                //    }
                //    break;
                case "add":
                    if (args.Length > 1)
                    {
                        List<string> cameras = new();
                        if (args[1].Contains(","))
                        {
                            string newargs = string.Concat(args);
                            newargs = newargs.Replace("add", "");
                            cameras = newargs.Split(',').ToList();
                        }
                        else
                        {
                            cameras.Add(args[1].Trim());
                        }

                        foreach (ComputerStation station in stations)
                        {
                            foreach (string cname in cameras)
                            {
                                string cam = cname.Trim();
                                if (station.controlBookmarks.Contains(cam))
                                {
                                    Message(iplayer, "cameraexists", cam);
                                    continue;
                                }
                                AddCamera(player, station, cam);
                            }
                        }
                    }
                    break;
                case "drones":
                    foreach (ComputerStation station in stations)
                    {
                        foundS = true;
                        Message(iplayer, "foundStation");
                        List<Drone> drones = new();

                        float range = configData.userRange;
                        if (configData.userMapWide || iplayer.HasPermission(permCCTVAdmin)) range = mapSize;

                        Vis.Entities(player.transform.position, range, drones, targetLayer);
                        List<string> foundCameras = new();

                        foreach (Drone camera in drones)
                        {
                            //IRemoteControllable realcam = camera as IRemoteControllable;
                            if (camera is not IRemoteControllable realcam) continue;
                            if (realcam == null) continue;
                            BaseEntity ent = realcam.GetEnt();
                            if (ent == null) continue;
                            string cname = realcam.GetIdentifier();
                            if (cname == null) continue;
                            if (foundCameras.Contains(cname)) continue;
                            if (configData.debug) Puts($"Found drone {cname} at {ent.transform.position}.");
                            if (ent.OwnerID.ToString() == iplayer.Id || IsFriend(player.userID, ent.OwnerID) || iplayer.HasPermission(permCCTVAdmin))
                            {
                                if (station.controlBookmarks.Contains(cname))
                                {
                                    Message(iplayer, "cameraexists", cname);
                                    continue;
                                }
                                foundCameras.Add(cname);

                                string displayName = Lang("unknown");
                                if ((ent.OwnerID == 0) && (configData.blockServerCams && !player.IPlayer.HasPermission(permCCTVAdmin)))
                                {
                                    if (configData.debug) Puts($"Disabling server-owned drone {cname} {ent.OwnerID}.");
                                    continue;
                                }
                                else if (ent.OwnerID == 0)
                                {
                                    displayName = Lang("server");
                                }
                                else
                                {
                                    BasePlayer pl = BasePlayer.Find(ent.OwnerID.ToString());
                                    if (pl != null) displayName = pl.displayName;
                                }

                                Message(iplayer, "foundDrone", cname, displayName);
                                AddCamera(player, station, cname);
                            }
                        }
                        break;
                    }
                    if (!foundS)
                    {
                        Message(iplayer, "noStation");
                    }
                    break;
                default:
                    foreach (ComputerStation station in stations)
                    {
                        foundS = true;
                        Message(iplayer, "foundStation");
                        List<CCTV_RC> cameras = new();

                        float range = configData.userRange;
                        if (configData.userMapWide || iplayer.HasPermission(permCCTVAdmin)) range = mapSize;

                        Vis.Entities(player.transform.position, range, cameras, targetLayer);
                        List<string> foundCameras = new();
                        if (configData.debug) Puts($"Searching for cameras over a {range}m radius.");
                        foreach (CCTV_RC camera in cameras)
                        {
                            //IRemoteControllable realcam = camera as IRemoteControllable;
                            if (camera is not IRemoteControllable realcam) continue;
                            if (realcam == null) continue;
                            BaseEntity ent = realcam.GetEnt();
                            if (ent == null) continue;
                            string cname = realcam.GetIdentifier();
                            if (cname == null) continue;
                            if (foundCameras.Contains(cname)) continue;
                            if (configData.debug) Puts($"Found camera {cname} at {ent.transform.position}.");
                            if (ent.OwnerID.ToString() == iplayer.Id || IsFriend(player.userID, ent.OwnerID) || iplayer.HasPermission(permCCTVAdmin))
                            {
                                if (station.controlBookmarks.Contains(cname))
                                {
                                    Message(iplayer, "cameraexists", cname);
                                    continue;
                                }
                                foundCameras.Add(cname);

                                string displayName = Lang("unknown");
                                if ((ent.OwnerID == 0) && (configData.blockServerCams && !player.IPlayer.HasPermission(permCCTVAdmin)))
                                {
                                    if (configData.debug) Puts($"Disabling server-owned camera {cname} {ent.OwnerID}.");
                                    continue;
                                }
                                else if (ent.OwnerID == 0)
                                {
                                    displayName = Lang("server");
                                }
                                else
                                {
                                    BasePlayer pl = BasePlayer.Find(ent.OwnerID.ToString());
                                    if (pl != null) displayName = pl.displayName;
                                }

                                Message(iplayer, "foundCamera", cname, displayName);
                                AddCamera(player, station, cname);
                            }
                        }
                        break;
                    }
                    if (!foundS)
                    {
                        Message(iplayer, "noStation");
                    }
                    break;
            }
        }

        [Command("cctvlist")]
        private void cmdCCTVList(IPlayer iplayer, string command, string[] args)
        {
            List<CCTV_RC> cameras = new();
            List<Drone> drones = new();
            List<string> foundCameras = new();
            string msg = null;

            Vis.Entities(Vector3.zero, mapSize, cameras);
            Vis.Entities(Vector3.zero, mapSize, drones);

            msg += Lang("foundCameras") + "\n";
            foreach (CCTV_RC camera in cameras)
            {
                //IRemoteControllable realcam = camera as IRemoteControllable;
                if (camera is not IRemoteControllable realcam) continue;
                if (realcam == null) continue;
                Transform loc = realcam.GetEyes();
                BaseEntity ent = realcam.GetEnt();
                if (ent == null) continue;
                string cname = realcam.GetIdentifier();
                if (cname == null) continue;
                if (foundCameras.Contains(cname)) continue;
                foundCameras.Add(cname);
                msg += cname + " @ " + loc.position.ToString() + Lang("ownedby") + ent.OwnerID.ToString() + "\n";
            }
            msg += Lang("foundDrones") + "\n";
            foreach (Drone camera in drones)
            {
                //IRemoteControllable realcam = camera as IRemoteControllable;
                if (camera is not IRemoteControllable realcam) continue;
                if (realcam == null) continue;
                Transform loc = realcam.GetEyes();
                BaseEntity ent = realcam.GetEnt();
                if (ent == null) continue;
                string cname = realcam.GetIdentifier();
                if (cname == null) continue;
                if (foundCameras.Contains(cname)) continue;
                foundCameras.Add(cname);
                msg += cname + " @ " + loc.position.ToString() + Lang("ownedby") + ent.OwnerID.ToString() + "\n";
            }

            if (!(iplayer.Object is BasePlayer))
            {
                Puts(msg);
            }
            else
            {
                Message(iplayer, msg);
            }
        }

        private void AddCamera(BasePlayer basePlayer, ComputerStation station, string str)
        {
            if (configData.debug) Puts($"Trying to add camera {str}");
            uint d = 0;
            BaseNetworkable baseNetworkable;
            IRemoteControllable component;
            foreach (IRemoteControllable allControllable in RemoteControlEntity.allControllables)
            {
                string curr = allControllable.GetIdentifier();
                if (allControllable == null)
                {
                    if (configData.debug) Puts($"  skipping null camera {curr}");
                    continue;
                }
                if (curr != str) continue;

                if (allControllable.GetEnt() != null)
                {
                    d = (uint)allControllable.GetEnt().net.ID.Value;
                    baseNetworkable = BaseNetworkable.serverEntities.Find(new NetworkableId(d));

                    if (baseNetworkable == null)
                    {
                        if (configData.debug) Puts("  baseNetworkable null");
                        return;
                    }
                    component = baseNetworkable.GetComponent<IRemoteControllable>();
                    if (component == null)
                    {
                        if (configData.debug) Puts("  component null");
                        return;
                    }
                    if (str == component.GetIdentifier())
                    {
                        if (configData.debug) Puts("  adding to station...");
                        station.controlBookmarks.Add(str);
                    }
                    station.SendControlBookmarks(basePlayer);
                    return;
                }
                else
                {
                    if (configData.debug) Puts("Computer station added bookmark with missing ent, likely a static CCTV (wipe the server)");
                    return;
                }
            }
            if (configData.debug) Puts($"  {str} cannot be controlled.Check power!");
        }

        // playerid = active player, ownerid = owner of camera, who may be offline
        private bool IsFriend(ulong playerid, ulong ownerid)
        {
            if (configData.useFriends && Friends != null)
            {
                object fr = Friends?.CallHook("AreFriends", playerid, ownerid);
                if (fr != null && (bool)fr)
                {
                    return true;
                }
            }
            if (configData.useClans && Clans != null)
            {
                string playerclan = (string)Clans?.CallHook("GetClanOf", playerid);
                string ownerclan = (string)Clans?.CallHook("GetClanOf", ownerid);
                if (playerclan == ownerclan && playerclan != null && ownerclan != null)
                {
                    return true;
                }
            }
            if (configData.useTeams)
            {
                RelationshipManager.PlayerTeam playerTeam = RelationshipManager.ServerInstance.FindPlayersTeam(playerid);
                if (playerTeam?.members.Contains(ownerid) == true)
                {
                    return true;
                }
            }
            return false;
        }

        private void OnPlayerInput(BasePlayer player, InputState input)
        {
            if (player == null || input == null) return;

            if (input.IsDown(BUTTON.FORWARD) || input.IsDown(BUTTON.BACKWARD) || input.IsDown(BUTTON.LEFT) || input.IsDown(BUTTON.RIGHT))
            {
                try
                {
                    ComputerStation activeCamera = player.GetMounted().GetComponentInParent<ComputerStation>();
                    if (activeCamera != null)
                    {
                        CCTV_RC cctv = activeCamera.currentlyControllingEnt.Get(true).GetComponent<CCTV_RC>();
                        if (cctv == null) return;
                        if (cctv.IsStatic() && !player.IPlayer.HasPermission(permCCTVAdmin)) return;
                        cctv.hasPTZ = true;

                        float x = input.IsDown(BUTTON.RIGHT) ? 1f : (input.IsDown(BUTTON.LEFT) ? -1f : 0f);
                        float y = input.IsDown(BUTTON.FORWARD) ? 1f : (input.IsDown(BUTTON.BACKWARD) ? -1f : 0f);

                        if (configData.debug)
                        {
                            string lr = input.IsDown(BUTTON.RIGHT) ? "right" : (input.IsDown(BUTTON.LEFT) ? "left" : "");
                            string ud = input.IsDown(BUTTON.FORWARD) ? "up" : (input.IsDown(BUTTON.BACKWARD) ? "down" : "");
                            string udlr = ud + lr;
                            Puts($"Trying to move camera {udlr}.");
                        }
                        float speed = 0.1f;
                        if (input.IsDown(BUTTON.SPRINT)) speed *= 3;

                        InputState inputState = new();
                        inputState.current.mouseDelta.y = y * speed;
                        inputState.current.mouseDelta.x = x * speed;

                        CameraViewerId cv = new(player.userID, 0);
                        cctv.UserInput(inputState, cv);

                        if (configData.playSound)
                        {
                            Effect effect = new(moveSound, new Vector3(0, 0, 0), Vector3.forward);
                            if (configData.playAtCamera)
                            {
                                effect.worldPos = cctv.transform.position;
                                effect.origin = cctv.transform.position;
                            }
                            else
                            {
                                effect.worldPos = player.transform.position;
                                effect.origin = player.transform.position;
                            }
                            EffectNetwork.Send(effect);
                        }
                    }
                }
                catch { }
            }
        }
        #endregion

        public class MovingLight : FacepunchBehaviour
        {
            public CCTV_RC camera;
            public SimpleLight light;

            public void Awake()
            {
                camera = GetComponentInParent<CCTV_RC>();
                light = GetComponentInParent<SimpleLight>();
            }

            public void Update()
            {
                if (light == null) return;
                if (camera == null) return;
                light.transform.localEulerAngles = new Vector3(camera.pivotOrigin.rotation.x, camera.pivotOrigin.rotation.y, camera.pivotOrigin.rotation.z);
                //sl.transform.localEulerAngles = new Vector3(0, 0, 0);

                //Vector3 vector3 = Vector3Ex.Direction(cctv.transform.position, cctv.yaw.transform.position);
                //vector3 = cctv.transform.InverseTransformDirection(vector3);
                //sl.transform.localRotation = Quaternion.Euler(vector3);
                light.SendNetworkUpdateImmediate();// BasePlayer.NetworkQueue.Update);
            }
        }
    }
}

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