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

FREE CopyPaste : 4.1.9 4.1.9

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
 // Reference: System.Drawing
//If debug is defined it will add a stopwatch to the paste and copydata which can be used to profile copying and pasting.//#define DEBUG
using Facepunch;
using Graphics = System.Drawing.Graphics;
using ImageFormat = System.Drawing.Imaging.ImageFormat;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Game.Rust;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using UnityEngine;
using Debug = System.Diagnostics.Debug;
namespace Oxide.Plugins {
    [Info("Copy Paste", "Reneb & MiRror & Misstake", "4.1.9", ResourceId = 716)]
    [Description("Copy and paste buildings to save them or move them")]
    public class CopyPaste : RustPlugin {
        private int copyLayer = LayerMask.GetMask("Construction", "Prevent Building", "Construction Trigger", "Trigger", "Deployed", "Default", "Ragdoll") , groundLayer = LayerMask.GetMask("Terrain", "Default") , rayCopy = LayerMask.GetMask("Construction", "Deployed", "Tree", "Resource", "Prevent Building") , rayPaste = LayerMask.GetMask("Construction", "Deployed", "Tree", "Terrain", "World", "Water", "Prevent Building");
        private string copyPermission = "copypaste.copy" , listPermission = "copypaste.list" , pastePermission = "copypaste.paste" , pastebackPermission = "copypaste.pasteback" , undoPermission = "copypaste.undo" , serverID = "Server" , subDirectory = "copypaste/";
        private Dictionary<string, Stack<List<BaseEntity>>> lastPastes = new Dictionary<string, Stack<List<BaseEntity>>>();
        private Dictionary<string, SignSize> signSizes = new Dictionary<string, SignSize>() {
            //{"spinner.wheel.deployed", new SignSize(512, 512)},
            {
                "sign.pictureframe.landscape", new SignSize(256, 128)
            }
            , {
                "sign.pictureframe.tall", new SignSize(128, 512)
            }
            , {
                "sign.pictureframe.portrait", new SignSize(128, 256)
            }
            , {
                "sign.pictureframe.xxl", new SignSize(1024, 512)
            }
            , {
                "sign.pictureframe.xl", new SignSize(512, 512)
            }
            , {
                "sign.small.wood", new SignSize(128, 64)
            }
            , {
                "sign.medium.wood", new SignSize(256, 128)
            }
            , {
                "sign.large.wood", new SignSize(256, 128)
            }
            , {
                "sign.huge.wood", new SignSize(512, 128)
            }
            , {
                "sign.hanging.banner.large", new SignSize(64, 256)
            }
            , {
                "sign.pole.banner.large", new SignSize(64, 256)
            }
            , {
                "sign.post.single", new SignSize(128, 64)
            }
            , {
                "sign.post.double", new SignSize(256, 256)
            }
            , {
                "sign.post.town", new SignSize(256, 128)
            }
            , {
                "sign.post.town.roof", new SignSize(256, 128)
            }
            , {
                "sign.hanging", new SignSize(128, 256)
            }
            , {
                "sign.hanging.ornate", new SignSize(256, 128)
            }
            ,
        }
        ;
        private List<BaseEntity.Slot> checkSlots = new List<BaseEntity.Slot>() {
            BaseEntity.Slot.Lock, BaseEntity.Slot.UpperModifier, BaseEntity.Slot.MiddleModifier, BaseEntity.Slot.LowerModifier
        }
        ;
        public enum CopyMechanics {
            Building, Proximity
        }
        private class SignSize {
            public int width;
            public int height;
            public SignSize(int width, int height) {
                this.width = width;
                this.height = height;
            }
        }
        //Config
        private ConfigData config;
        private class ConfigData {
            [JsonProperty(PropertyName = "Copy Options")]
            public CopyOptions Copy {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Paste Options")]
            public PasteOptions Paste {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Amount of entities to paste per batch.Use to tweak performance impact of pasting")]
            [DefaultValue(15)]
            public int PasteBatchSize = 15;
            [JsonProperty(PropertyName = "Amount of entities to copy per batch.Use to tweak performance impact of copying")]
            [DefaultValue(100)]
            public int CopyBatchSize = 100;
            [JsonProperty(PropertyName = "Amount of entities to undo per batch.Use to tweak performance impact of undoing")]
            [DefaultValue(15)]
            public int UndoBatchSize = 15;
            public class CopyOptions {
                [JsonProperty(PropertyName = "Check radius from each entity (true/false)")]
                [DefaultValue(true)]
                public bool EachToEach {
                    get;
                    set;
                }
                = true;
                [JsonProperty(PropertyName = "Share (true/false)")]
                [DefaultValue(false)]
                public bool Share {
                    get;
                    set;
                }
                = false;
                [JsonProperty(PropertyName = "Tree (true/false)")]
                [DefaultValue(false)]
                public bool Tree {
                    get;
                    set;
                }
                = false;
            }
            public class PasteOptions {
                [JsonProperty(PropertyName = "Auth (true/false)")]
                [DefaultValue(false)]
                public bool Auth {
                    get;
                    set;
                }
                = false;
                [JsonProperty(PropertyName = "Deployables (true/false)")]
                [DefaultValue(true)]
                public bool Deployables {
                    get;
                    set;
                }
                = true;
                [JsonProperty(PropertyName = "Inventories (true/false)")]
                [DefaultValue(true)]
                public bool Inventories {
                    get;
                    set;
                }
                = true;
                [JsonProperty(PropertyName = "Vending Machines (true/false)")]
                [DefaultValue(true)]
                public bool VendingMachines {
                    get;
                    set;
                }
                = true;
                [JsonProperty(PropertyName = "Stability (true/false)")]
                [DefaultValue(true)]
                public bool Stability {
                    get;
                    set;
                }
                = true;
                [JsonProperty(PropertyName = "EntityOwner (true/false)")]
                [DefaultValue(true)]
                public bool EntityOwner {
                    get;
                    set;
                }
                = true;
            }
        }
        private void LoadVariables() {
            Config.Settings.DefaultValueHandling = DefaultValueHandling.Populate;
            config = Config.ReadObject<ConfigData>();
            Config.WriteObject(config, true);
        }
        protected override void LoadDefaultConfig() {
            var configData = new ConfigData {
                Copy = new ConfigData.CopyOptions(), Paste = new ConfigData.PasteOptions()
            }
            ;
            Config.WriteObject(configData, true);
        }
        //Hooks
        private void Init() {
            permission.RegisterPermission(copyPermission, this);
            permission.RegisterPermission(listPermission, this);
            permission.RegisterPermission(pastePermission, this);
            permission.RegisterPermission(pastebackPermission, this);
            permission.RegisterPermission(undoPermission, this);
            Dictionary<string, Dictionary<string, string>> compiledLangs = new Dictionary<string, Dictionary<string, string>>();
            foreach (var line in messages) {
                foreach (var translate in line.Value) {
                    if (!compiledLangs.ContainsKey(translate.Key)) compiledLangs[translate.Key] = new Dictionary<string, string>();
                    compiledLangs[translate.Key][line.Key] = translate.Value;
                }
            }
            foreach (var cLangs in compiledLangs) {
                lang.RegisterMessages(cLangs.Value, this, cLangs.Key);
            }
        }
        private void OnServerInitialized() {
            LoadVariables();
            Vis.colBuffer = new Collider[8192 * 16];
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
                Formatting = Newtonsoft.Json.Formatting.Indented, ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
            }
            ;
        }
#region API
        private object TryCopyFromSteamID(ulong userID, string filename, string[] args, Action callback = null) {
            var player = BasePlayer.FindByID(userID);
            if (player == null) return Lang("NOT_FOUND_PLAYER", player.UserIDString);
            RaycastHit hit;
            if (!Physics.Raycast(player.eyes.HeadRay(), out hit, 1000f, rayCopy)) return Lang("NO_ENTITY_RAY", player.UserIDString);
            return TryCopy(hit.point, hit.GetEntity().GetNetworkRotation().eulerAngles, filename, DegreeToRadian(player.GetNetworkRotation().eulerAngles.y), args, player, callback);
        }
        private object TryPasteFromSteamID(ulong userID, string filename, string[] args, Action callback = null) {
            var player = BasePlayer.FindByID(userID);
            if (player == null) return Lang("NOT_FOUND_PLAYER", player.UserIDString);
            RaycastHit hit;
            if (!Physics.Raycast(player.eyes.HeadRay(), out hit, 1000f, rayPaste)) return Lang("NO_ENTITY_RAY", player.UserIDString);
            return TryPaste(hit.point, filename, player, DegreeToRadian(player.GetNetworkRotation().eulerAngles.y), args, callback : callback);
        }
        private object TryPasteFromVector3(Vector3 pos, float rotationCorrection, string filename, string[] args, Action callback = null) {
            return TryPaste(pos, filename, null, rotationCorrection, args, callback : callback);
        }
#endregion
        //Other methods
        private object CheckCollision(HashSet<Dictionary<string, object>> entities, Vector3 startPos, float radius) {
            foreach (var entityobj in entities) {
                if (Physics.CheckSphere((Vector3)entityobj["position"], radius, copyLayer)) return Lang("BLOCKING_PASTE", null);
            }
            return true;
        }
        private bool CheckPlaced(string prefabname, Vector3 pos, Quaternion rot) {
            List<BaseEntity> ents = new List<BaseEntity>();
            Vis.Entities<BaseEntity>(pos, 2f, ents);
            foreach (BaseEntity ent in ents) {
                if (ent.PrefabName == prefabname && ent.transform.position == pos && ent.transform.rotation == rot) return true;
            }
            return false;
        }
        private object cmdPasteBack(BasePlayer player, string[] args) {
            string userIDString = (player == null) ? serverID : player.UserIDString;
            if (args.Length < 1) return Lang("SYNTAX_PASTEBACK", userIDString);
            var success = TryPasteBack(args[0], player, args.Skip(1).ToArray());
            if (success is string) return (string)success;
            return true;
        }
        private object cmdUndo(string userIDString, string[] args) {
            var player = BasePlayer.Find(userIDString);
            if (!lastPastes.ContainsKey(userIDString)) return Lang("NO_PASTED_STRUCTURE", userIDString);
            HashSet<BaseEntity> entities = new HashSet<BaseEntity>(lastPastes[userIDString].Pop().ToList());
            UndoLoop(entities, player);
            return true;
        }
        private void UndoLoop(HashSet<BaseEntity> entities, BasePlayer player, int count = 0) {
            entities.Take(config.UndoBatchSize).ToList().ForEach(p => {
                entities.Remove(p);
                // Cleanup the hotspot beloning to the node.var ore = p as OreResourceEntity;
                if (ore != null) {
                    ore.CleanupBonus();
                }
                if (p != null && !p.IsDestroyed) p.Kill();
            }
            );
            // If it gets stuck in infinite loop break the loop.if (entities.Count == count)
            {
                if (player != null) SendReply(player, "Undo cancelled because of infinite loop.");
                else Puts("Undo cancelled because of infinite loop.");
                return;
            }
            if(entities.Count > 0) NextTick(() => UndoLoop(entities, player, entities.Count));
            else {
                if (player != null) SendReply(player, Lang("UNDO_SUCCESS", player.UserIDString));
                else Puts(Lang("UNDO_SUCCESS"));
                if (lastPastes[player?.UserIDString ?? serverID].Count == 0) lastPastes.Remove(player?.UserIDString ?? serverID);
            }
        }
        private void Copy(Vector3 sourcePos, Vector3 sourceRot, string filename, float RotationCorrection, CopyMechanics copyMechanics, float range, bool saveTree, bool saveShare, bool eachToEach, BasePlayer player, Action callback) {
            int currentLayer = copyLayer;
            if (saveTree) currentLayer |= LayerMask.GetMask("Tree");
            var copyData = new CopyData() {
                FileName = filename, CurrentLayer = currentLayer, RotCor = RotationCorrection, Range = range, SaveShare = saveShare, SaveTree = saveTree, CopyMechanics = copyMechanics, EachToEach = eachToEach, SourcePos = sourcePos, SourceRot = sourceRot, Player = player, callback = callback
            }
            ;
            copyData.CheckFrom.Push(sourcePos);
            NextTick(() => CopyLoop(copyData));
            ;
        }
        private void CopyLoop(CopyData copyData) {
            var checkFrom = copyData.CheckFrom;
            var houseList = copyData.HouseList;
            var buildingID = copyData.BuildingID;
            var copyMechanics = copyData.CopyMechanics;
            var batchSize = checkFrom.Count < config.CopyBatchSize ? checkFrom.Count : config.CopyBatchSize;
            for(int i = 0; i < batchSize; i++) {
                if (checkFrom.Count == 0) break;
                List<BaseEntity> list = Pool.GetList<BaseEntity>();
                Vis.Entities<BaseEntity>(checkFrom.Pop(), copyData.Range, list, copyData.CurrentLayer);
                foreach (var entity in list) {
                    if (!houseList.Add(entity)) continue;
                    if (copyMechanics == CopyMechanics.Building) {
                        BuildingBlock buildingBlock = entity.GetComponentInParent<BuildingBlock>();
                        if (buildingBlock != null) {
                            if (buildingID == 0) buildingID = buildingBlock.buildingID;
                            if (buildingID != buildingBlock.buildingID) continue;
                        }
                    }
                    if (copyData.EachToEach) checkFrom.Push(entity.transform.position);
                    copyData.RawData.Add(EntityData(entity, entity.transform.position, entity.transform.rotation.eulerAngles / 57.29578f, copyData));
                }
                copyData.BuildingID = buildingID;
            }
            if (checkFrom.Count > 0) {
                NextTick(() => CopyLoop(copyData));
            }
            else {
                string path = subDirectory + copyData.FileName;
                var datafile = Interface.Oxide.DataFileSystem.GetDatafile(path);
                datafile.Clear();
                var sourcePos = copyData.SourcePos;
                datafile["default"] = new Dictionary<string, object> {
                    {
                        "position", new Dictionary<string, object> {
                            {
                                "x", sourcePos.x.ToString()
                            }
                            , {
                                "y", sourcePos.y.ToString()
                            }
                            , {
                                "z", sourcePos.z.ToString()
                            }
                        }
                    }
                    , {
                        "rotationy", copyData.SourceRot.y.ToString()
                    }
                    , {
                        "rotationdiff", copyData.RotCor.ToString()
                    }
                }
                ;
                datafile["entities"] = copyData.RawData;
                datafile["protocol"] = new Dictionary<string, object> {
                    {
                        "items", 2
                    }
                    , {
                        "version", Version
                    }
                }
                ;
                Interface.Oxide.DataFileSystem.SaveDatafile(path);
                SendReply(copyData.Player, Lang("COPY_SUCCESS", copyData.Player.UserIDString, copyData.FileName));
                copyData.callback?.Invoke();
                Interface.CallHook("OnCopyFinished", copyData.RawData);
            }
        }
        private float DegreeToRadian(float angle) {
            return (float)(Math.PI * angle / 180.0f);
        }
        private Dictionary<string, object> EntityData(BaseEntity entity, Vector3 entPos, Vector3 entRot, CopyData copyData) {
            var normalizedPos = NormalizePosition(copyData.SourcePos, entPos, copyData.RotCor);
            entRot.y -= copyData.RotCor;
            var data = new Dictionary<string, object> {
                {
                    "prefabname", entity.PrefabName
                }
                , {
                    "skinid", entity.skinID
                }
                , {
                    "flags", TryCopyFlags(entity)
                }
                , {
                    "pos", new Dictionary<string, object> {
                        {
                            "x", normalizedPos.x.ToString()
                        }
                        , {
                            "y", normalizedPos.y.ToString()
                        }
                        , {
                            "z", normalizedPos.z.ToString()
                        }
                    }
                }
                , {
                    "rot", new Dictionary<string, object> {
                        {
                            "x", entRot.x.ToString()
                        }
                        , {
                            "y", entRot.y.ToString()
                        }
                        , {
                            "z", entRot.z.ToString()
                        }
                        ,
                    }
                }
                , {
                    "ownerid", entity.OwnerID
                }
            }
            ;
            TryCopySlots(entity, data, copyData.SaveShare);
            var buildingblock = entity as BuildingBlock;
            if (buildingblock != null) {
                data.Add("grade", buildingblock.grade);
            }
            var box = entity as StorageContainer;
            if (box != null) {
                var itemlist = new List<object>();
                foreach (Item item in box.inventory.itemList) {
                    var itemdata = new Dictionary<string, object> {
                        {
                            "condition", item.condition.ToString()
                        }
                        , {
                            "id", item.info.itemid
                        }
                        , {
                            "amount", item.amount
                        }
                        , {
                            "skinid", item.skin
                        }
                        , {
                            "position", item.position
                        }
                        , {
                            "blueprintTarget", item.blueprintTarget
                        }
                        ,
                    }
                    ;
                    if (!string.IsNullOrEmpty(item.text)) itemdata["text"] = item.text;
                    var heldEnt = item.GetHeldEntity();
                    if (heldEnt != null) {
                        var projectiles = heldEnt.GetComponent<BaseProjectile>();
                        if (projectiles != null) {
                            var magazine = projectiles.primaryMagazine;
                            if (magazine != null) {
                                itemdata.Add("magazine", new Dictionary<string, object> {
                                    {
                                        magazine.ammoType.itemid.ToString(), magazine.contents
                                    }
                                }
                                );
                            }
                        }
                    }
                    if (item?.contents?.itemList != null) {
                        var contents = new List<object>();
                        foreach (Item itemContains in item.contents.itemList) {
                            contents.Add(new Dictionary<string, object> {
                                {
                                    "id", itemContains.info.itemid
                                }
                                , {
                                    "amount", itemContains.amount
                                }
                                ,
                            }
                            );
                        }
                        itemdata["items"] = contents;
                    }
                    itemlist.Add(itemdata);
                }
                data.Add("items", itemlist);
            }
            var sign = entity as Signage;
            if (sign != null) {
                var imageByte = FileStorage.server.Get(sign.textureID, FileStorage.Type.png, sign.net.ID);
                data.Add("sign", new Dictionary<string, object> {
                    {
                        "locked", sign.IsLocked()
                    }
                }
                );
                if (sign.textureID > 0 && imageByte != null) ((Dictionary<string, object>)data["sign"]).Add("texture", Convert.ToBase64String(imageByte));
            }
            if (copyData.SaveShare) {
                var sleepingBag = entity as SleepingBag;
                if (sleepingBag != null) {
                    data.Add("sleepingbag", new Dictionary<string, object> {
                        {
                            "niceName", sleepingBag.niceName
                        }
                        , {
                            "deployerUserID", sleepingBag.deployerUserID
                        }
                        , {
                            "isPublic", sleepingBag.IsPublic()
                        }
                        ,
                    }
                    );
                }
                var cupboard = entity as BuildingPrivlidge;
                if (cupboard != null) {
                    data.Add("cupboard", new Dictionary<string, object> {
                        {
                            "authorizedPlayers", cupboard.authorizedPlayers.Select(y => y.userid).ToList()
                        }
                    }
                    );
                }
                var autoTurret = entity as AutoTurret;
                if (autoTurret != null) {
                    data.Add("autoturret", new Dictionary<string, object> {
                        {
                            "authorizedPlayers", autoTurret.authorizedPlayers.Select(p => p.userid).ToList()
                        }
                    }
                    );
                }
            }
            var vendingMachine = entity as VendingMachine;
            if (vendingMachine != null) {
                var sellOrders = new List<object>();
                foreach (var vendItem in vendingMachine.sellOrders.sellOrders) {
                    sellOrders.Add(new Dictionary<string, object> {
                        {
                            "itemToSellID", vendItem.itemToSellID
                        }
                        , {
                            "itemToSellAmount", vendItem.itemToSellAmount
                        }
                        , {
                            "currencyID", vendItem.currencyID
                        }
                        , {
                            "currencyAmountPerItem", vendItem.currencyAmountPerItem
                        }
                        , {
                            "inStock", vendItem.inStock
                        }
                        , {
                            "currencyIsBP", vendItem.currencyIsBP
                        }
                        , {
                            "itemToSellIsBP", vendItem.itemToSellIsBP
                        }
                        ,
                    }
                    );
                }
                data.Add("vendingmachine", new Dictionary<string, object> {
                    {
                        "shopName", vendingMachine.shopName
                    }
                    , {
                        "isBroadcasting", vendingMachine.IsBroadcasting()
                    }
                    , {
                        "sellOrders", sellOrders
                    }
                }
                );
            }
            var ioEntity = entity as IOEntity;
            if (ioEntity != null) {
                var ioData = new Dictionary<string, object>();
                List<object> inputs = ioEntity.inputs.Select(input => new Dictionary<string, object> {
                    {
                        "connectedID", input.connectedTo.entityRef.uid
                    }
                    , {
                        "connectedToSlot", input.connectedToSlot
                    }
                    , {
                        "niceName", input.niceName
                    }
                    , {
                        "type", (int) input.type
                    }
                    ,
                }
                ).Cast<object>().ToList();
                ioData.Add("inputs", inputs);
                List<object> outputs = new List<object>();
                foreach (IOEntity.IOSlot output in ioEntity.outputs) {
                    Dictionary<string, object> ioConnection = new Dictionary<string, object> {
                        {
                            "connectedID", output.connectedTo.entityRef.uid
                        }
                        , {
                            "connectedToSlot", output.connectedToSlot
                        }
                        , {
                            "niceName", output.niceName
                        }
                        , {
                            "type", (int)output.type
                        }
                        ,
                    }
                    ;
                    var linePoints = new List<Vector3>();
                    if (output.linePoints != null) {
                        // Since Vector3 is struct should be able to simply save the Vecot directly.foreach (Vector3 linePoint in output.linePoints)
                        {
                            linePoints.Add(NormalizePosition(copyData.SourcePos, linePoint, copyData.RotCor));
                        }
                    }
                    ioConnection.Add("linePoints", linePoints);
                    outputs.Add(ioConnection);
                }
                ioData.Add("outputs", outputs);
                ioData.Add("oldID", ioEntity.net.ID);
                var electricalBranch = ioEntity.GetComponentInParent<ElectricalBranch>();
                if (electricalBranch != null) {
                    ioData.Add("branchAmount", electricalBranch.branchAmount);
                }
                /*var counter = ioEntity.GetComponentInParent<PowerCounter>();
                if (counter != null)
                {
                    ioData.Add("targetNumber", counter.GetTarget());
                }*/
                var timer = ioEntity.GetComponentInParent<TimerSwitch>();
                if (timer != null) {
                    ioData.Add("timerLength", timer.timerLength);
                }
                data.Add("IOEntity", ioData);
            }
            return data;
        }
        private object FindBestHeight(HashSet<Dictionary<string, object>> entities, Vector3 startPos) {
            float maxHeight = 0f;
            foreach (var entity in entities) {
                if (((string)entity["prefabname"]).Contains("/foundation/")) {
                    var foundHeight = GetGround((Vector3)entity["position"]);
                    if (foundHeight != null) {
                        var height = (Vector3)foundHeight;
                        if (height.y > maxHeight) maxHeight = height.y;
                    }
                }
            }
            maxHeight += 1f;
            return maxHeight;
        }
        private bool FindRayEntity(Vector3 sourcePos, Vector3 sourceDir, out Vector3 point, out BaseEntity entity, int rayLayer) {
            RaycastHit hitinfo;
            entity = null;
            point = Vector3.zero;
            if (!Physics.Raycast(sourcePos, sourceDir, out hitinfo, 1000f, rayLayer)) return false;
            entity = hitinfo.GetEntity();
            point = hitinfo.point;
            return true;
        }
        private void FixSignage(Signage sign, byte[] imageBytes) {
            if (!signSizes.ContainsKey(sign.ShortPrefabName)) return;
            byte[] resizedImage = ImageResize(imageBytes, signSizes[sign.ShortPrefabName].width, signSizes[sign.ShortPrefabName].height);
            sign.textureID = FileStorage.server.Store(resizedImage, FileStorage.Type.png, sign.net.ID);
        }
        private object GetGround(Vector3 pos) {
            RaycastHit hitInfo;
            if (Physics.Raycast(pos, Vector3.up, out hitInfo, groundLayer)) return hitInfo.point;
            if (Physics.Raycast(pos, Vector3.down, out hitInfo, groundLayer)) return hitInfo.point;
            return null;
        }
        private int GetItemID(int itemID) {
            if(replaceItemID.ContainsKey(itemID)) return replaceItemID[itemID];
            return itemID;
        }
        private bool HasAccess(BasePlayer player, string permName) {
            return player.IsAdmin || permission.UserHasPermission(player.UserIDString, permName);
        }
        private byte[] ImageResize(byte[] imageBytes, int width, int height) {
            Bitmap resizedImage = new Bitmap(width, height), sourceImage = new Bitmap(new MemoryStream(imageBytes));
            Graphics.FromImage(resizedImage).DrawImage(sourceImage, new Rectangle(0, 0, width, height), new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), GraphicsUnit.Pixel);
            MemoryStream ms = new MemoryStream();
            resizedImage.Save(ms, ImageFormat.Png);
            return ms.ToArray();
        }
        private string Lang(string key, string userID = null, params object[] args) => string.Format(lang.GetMessage(key, this, userID), args);
        private Vector3 NormalizePosition(Vector3 InitialPos, Vector3 CurrentPos, float diffRot) {
            var transformedPos = CurrentPos - InitialPos;
            var newX = (transformedPos.x * (float)System.Math.Cos(-diffRot)) + (transformedPos.z * (float)System.Math.Sin(-diffRot));
            var newZ = (transformedPos.z * (float)System.Math.Cos(-diffRot)) - (transformedPos.x * (float)System.Math.Sin(-diffRot));
            transformedPos.x = newX;
            transformedPos.z = newZ;
            return transformedPos;
        }
        private void Paste(ICollection<Dictionary<string, object>> entities, Dictionary<string, object> protocol, Vector3 startPos, BasePlayer player, bool stability, float RotationCorrection, float heightAdj, bool auth, Action callback) {
            var ioEntities = new Dictionary<uint, Dictionary<string, object>>();
            uint buildingID = 0;
            //Settings
            bool isItemReplace = !protocol.ContainsKey("items");
            var eulerRotation = new Vector3(0f, RotationCorrection * 57.2958f, 0f);
            var quaternionRotation = Quaternion.Euler(eulerRotation);
            var pasteData = new PasteData() {
                HeightAdj = heightAdj, IsItemReplace = isItemReplace, Entities = entities, Player = player, QuaternionRotation = quaternionRotation, StartPos = startPos, Stability = stability, Auth = auth, callback = callback
            }
            ;
            NextTick(() => PasteLoop(pasteData));
        }
        private void PasteLoop(PasteData pasteData) {
            var entities = pasteData.Entities;
            var todo = entities.Take(config.PasteBatchSize).ToArray();
            var player = pasteData.Player;
            foreach (var data in todo) {
                entities.Remove(data);
                var prefabname = (string)data["prefabname"];
                ulong skinid = ulong.Parse(data["skinid"].ToString());
                var pos = (Vector3)data["position"];
                var rot = (Quaternion)data["rotation"];
                ulong ownerId = player?.userID ?? 0;
                if (data.ContainsKey("ownerid")) {
                    ownerId = Convert.ToUInt64(data["ownerid"]);
                }
                if (CheckPlaced(prefabname, pos, rot)) continue;
                if (prefabname.Contains("pillar")) continue;
                var entity = GameManager.server.CreateEntity(prefabname, pos, rot, true);
                if (entity == null) continue;
                entity.transform.position = pos;
                entity.transform.rotation = rot;
                if (player != null) entity.SendMessage("SetDeployedBy", player, SendMessageOptions.DontRequireReceiver);
                entity.OwnerID = ownerId;
                BuildingBlock buildingBlock = entity as BuildingBlock;
                if (buildingBlock != null) {
                    buildingBlock.blockDefinition = PrefabAttribute.server.Find<Construction>(buildingBlock.prefabID);
                    buildingBlock.SetGrade((BuildingGrade.Enum)data["grade"]);
                    if(!pasteData.Stability) buildingBlock.grounded = true;
                }
                DecayEntity decayEntity = entity as DecayEntity;
                if (decayEntity != null) {
                    if (pasteData.BuildingID == 0) pasteData.BuildingID = BuildingManager.server.NewBuildingID();
                    decayEntity.AttachToBuilding(pasteData.BuildingID);
                }
                StabilityEntity stabilityEntity = entity as StabilityEntity;
                if (stabilityEntity != null) {
                    if (!stabilityEntity.grounded) {
                        stabilityEntity.grounded = true;
                        pasteData.StabilityEntities.Add(stabilityEntity);
                    }
                }
                entity.skinID = skinid;
                entity.Spawn();
                var baseCombat = entity as BaseCombatEntity;
                if (baseCombat != null) baseCombat.ChangeHealth(baseCombat.MaxHealth());
                pasteData.PastedEntities.AddRange(TryPasteSlots(entity, data, pasteData));
                var box = entity as StorageContainer;
                if (box != null) {
                    Locker locker = box as Locker;
                    if (locker != null) locker.equippingActive = true;
                    box.inventory.Clear();
                    var items = new List<object>();
                    if (data.ContainsKey("items")) items = data["items"] as List<object>;
                    foreach (var itemDef in items) {
                        var item = itemDef as Dictionary<string, object>;
                        var itemid = Convert.ToInt32(item["id"]);
                        var itemamount = Convert.ToInt32(item["amount"]);
                        var itemskin = ulong.Parse(item["skinid"].ToString());
                        var itemcondition = Convert.ToSingle(item["condition"]);
                        if (pasteData.IsItemReplace) itemid = GetItemID(itemid);
                        var i = ItemManager.CreateByItemID(itemid, itemamount, itemskin);
                        if (i != null) {
                            i.condition = itemcondition;
                            if (item.ContainsKey("text")) i.text = item["text"].ToString();
                            if (item.ContainsKey("blueprintTarget")) {
                                int blueprintTarget = Convert.ToInt32(item["blueprintTarget"]);
                                if (pasteData.IsItemReplace) blueprintTarget = GetItemID(blueprintTarget);
                                i.blueprintTarget = blueprintTarget;
                            }
                            if (item.ContainsKey("magazine")) {
                                var heldent = i.GetHeldEntity();
                                if (heldent != null) {
                                    var projectiles = heldent.GetComponent<BaseProjectile>();
                                    if (projectiles != null) {
                                        var magazine = item["magazine"] as Dictionary<string, object>;
                                        var ammotype = int.Parse(magazine.Keys.ToArray()[0]);
                                        var ammoamount = int.Parse(magazine[ammotype.ToString()].ToString());
                                        if (pasteData.IsItemReplace) ammotype = GetItemID(ammotype);
                                        projectiles.primaryMagazine.ammoType = ItemManager.FindItemDefinition(ammotype);
                                        projectiles.primaryMagazine.contents = ammoamount;
                                    }
                                    //TODO Doesn't add water to some containers
                                    if (item.ContainsKey("items")) {
                                        var itemContainsList = item["items"] as List<object>;
                                        foreach (var itemContains in itemContainsList) {
                                            var contents = itemContains as Dictionary<string, object>;
                                            int contentsItemID = Convert.ToInt32(contents["id"]);
                                            if (pasteData.IsItemReplace) contentsItemID = GetItemID(contentsItemID);
                                            i.contents.AddItem(ItemManager.FindItemDefinition(contentsItemID), Convert.ToInt32(contents["amount"]));
                                        }
                                    }
                                }
                            }
                            int targetPos = -1;
                            if (item.ContainsKey("position")) targetPos = Convert.ToInt32(item["position"]);
                            i.MoveToContainer(box.inventory, targetPos);
                        }
                    }
                    if (locker != null) locker.equippingActive = false;
                }
                var sign = entity as Signage;
                if (sign != null && data.ContainsKey("sign")) {
                    var signData = data["sign"] as Dictionary<string, object>;
                    if (signData.ContainsKey("texture")) {
                        byte[] imageBytes = Convert.FromBase64String(signData["texture"].ToString());
                        FixSignage(sign, imageBytes);
                    }
                    if (Convert.ToBoolean(signData["locked"])) sign.SetFlag(BaseEntity.Flags.Locked, true);
                    sign.SendNetworkUpdate();
                }
                var sleepingBag = entity as SleepingBag;
                if (sleepingBag != null && data.ContainsKey("sleepingbag")) {
                    var bagData = data["sleepingbag"] as Dictionary<string, object>;
                    sleepingBag.niceName = bagData["niceName"].ToString();
                    sleepingBag.deployerUserID = ulong.Parse(bagData["deployerUserID"].ToString());
                    sleepingBag.SetPublic(Convert.ToBoolean(bagData["isPublic"]));
                }
                var autoturret = entity as AutoTurret;
                if (autoturret != null) {
                    List<ulong> authorizedPlayers = new List<ulong>();
                    if (data.ContainsKey("autoturret")) {
                        var autoTurretData = data["autoturret"] as Dictionary<string, object>;
                        authorizedPlayers = (autoTurretData["authorizedPlayers"] as List<object>).Select(Convert.ToUInt64).ToList();
                    }
                    if (player != null && !authorizedPlayers.Contains(player.userID) && pasteData.Auth) authorizedPlayers.Add(player.userID);
                    foreach (var userID in authorizedPlayers) {
                        autoturret.authorizedPlayers.Add(new PlayerNameID() {
                            userid = Convert.ToUInt64(userID), username = "Player"
                        }
                        );
                    }
                    autoturret.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                }
                var cupboard = entity as BuildingPrivlidge;
                if (cupboard != null) {
                    List<ulong> authorizedPlayers = new List<ulong>();
                    if (data.ContainsKey("cupboard")) {
                        var cupboardData = data["cupboard"] as Dictionary<string, object>;
                        authorizedPlayers = (cupboardData["authorizedPlayers"] as List<object>).Select(Convert.ToUInt64).ToList();
                    }
                    if (player != null && !authorizedPlayers.Contains(player.userID) && pasteData.Auth) authorizedPlayers.Add(player.userID);
                    foreach (var userID in authorizedPlayers) {
                        cupboard.authorizedPlayers.Add(new PlayerNameID() {
                            userid = Convert.ToUInt64(userID), username = "Player"
                        }
                        );
                    }
                    cupboard.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                }
                var vendingMachine = entity as VendingMachine;
                if (vendingMachine != null && data.ContainsKey("vendingmachine")) {
                    var vendingData = data["vendingmachine"] as Dictionary<string, object>;
                    vendingMachine.shopName = vendingData["shopName"].ToString();
                    vendingMachine.SetFlag(BaseEntity.Flags.Reserved4, Convert.ToBoolean(vendingData["isBroadcasting"]));
                    var sellOrders = vendingData["sellOrders"] as List<object>;
                    foreach (var orderPreInfo in sellOrders) {
                        var orderInfo = orderPreInfo as Dictionary<string, object>;
                        if (!orderInfo.ContainsKey("inStock")) {
                            orderInfo["inStock"] = 0;
                            orderInfo["currencyIsBP"] = false;
                            orderInfo["itemToSellIsBP"] = false;
                        }
                        int itemToSellID = Convert.ToInt32(orderInfo["itemToSellID"]), currencyID = Convert.ToInt32(orderInfo["currencyID"]);
                        if (pasteData.IsItemReplace) {
                            itemToSellID = GetItemID(itemToSellID);
                            currencyID = GetItemID(currencyID);
                        }
                        vendingMachine.sellOrders.sellOrders.Add(new ProtoBuf.VendingMachine.SellOrder() {
                            ShouldPool = false, itemToSellID = itemToSellID, itemToSellAmount = Convert.ToInt32(orderInfo["itemToSellAmount"]), currencyID = currencyID, currencyAmountPerItem = Convert.ToInt32(orderInfo["currencyAmountPerItem"]), inStock = Convert.ToInt32(orderInfo["inStock"]), currencyIsBP = Convert.ToBoolean(orderInfo["currencyIsBP"]), itemToSellIsBP = Convert.ToBoolean(orderInfo["itemToSellIsBP"]),
                        }
                        );
                    }
                    vendingMachine.FullUpdate();
                }
                var ioEntity = entity as IOEntity;
                if (ioEntity != null) {
                    var ioData = new Dictionary<string, object>();
                    if (data.ContainsKey("IOEntity")) {
                        ioData = data["IOEntity"] as Dictionary<string, object> ?? new Dictionary<string, object>();
                    }
                    ioData.Add("entity", ioEntity);
                    ioData.Add("newId", ioEntity.net.ID);
                    object oldIdObject = 0;
                    if (ioData.TryGetValue("oldID", out oldIdObject)) {
                        var oldId = Convert.ToUInt32(oldIdObject);
                        pasteData.IoEntities.Add(oldId, ioData);
                    }
                }
                var flagsData = new Dictionary<string, object>();
                if (data.ContainsKey("flags")) flagsData = data["flags"] as Dictionary<string, object>;
                var flags = new Dictionary<BaseEntity.Flags, bool>();
                foreach (var flagData in flagsData) {
                    BaseEntity.Flags baseFlag;
                    if(Enum.TryParse(flagData.Key, out baseFlag)) flags.Add(baseFlag, Convert.ToBoolean(flagData.Value));
                }
                foreach (var flag in flags) {
                    entity.SetFlag(flag.Key, flag.Value);
                }
                pasteData.PastedEntities.Add(entity);
            }
            if (entities.Count > 0) NextTick(() => PasteLoop(pasteData));
            else {
                foreach (var ioData in pasteData.IoEntities.Values.ToArray()) {
                    if (!ioData.ContainsKey("entity")) continue;
                    var ioEntity = ioData["entity"] as IOEntity;
                    List<object> inputs = null;
                    if (ioData.ContainsKey("inputs")) inputs = ioData["inputs"] as List<object>;
                    var electricalBranch = ioEntity as ElectricalBranch;
                    if (electricalBranch != null && ioData.ContainsKey("branchAmount")) {
                        electricalBranch.branchAmount = Convert.ToInt32(ioData["branchAmount"]);
                    }
                    // Realized counter.targetCounterNumber is
// ... [Code preview truncated due to length. Full source in attached file] ...

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