public Transform SummonBarricade(Transform hit)
        {
            var barricade = new Barricade(Id, Health, State, (ItemBarricadeAsset)Assets.find(EAssetType.ITEM, Id));

            if (hit != null)
            {
                return(BarricadeManager.dropPlantedBarricade(hit, barricade, Position.ToVector3(), Quaternion.Euler(Rotation.x, Rotation.y, Rotation.z), Owner, Group));
            }
            else
            {
                return(BarricadeManager.dropNonPlantedBarricade(barricade, Position.ToVector3(), Quaternion.Euler(Rotation.x, Rotation.y, Rotation.z), Owner, Group));
            }
        }
        public void Execute(IRocketPlayer caller, string[] command)
        {
            var player = (UnturnedPlayer)caller;

            if (command == null || command.Length == 0 || string.IsNullOrWhiteSpace(command[0]))
            {
                UnturnedChat.Say(caller, "Invalid Syntax, use /Loadschematic <Name> [Optional: -KeepPos -NoState -KeepHealth -SetOwner -SetGroup, Input any Steamid64 to set owner to it]");
                return;
            }

            if (!UnityEnginePhysics::UnityEngine.Physics.Raycast(player.Player.look.aim.position, player.Player.look.aim.forward, out var hit))
            {
                UnturnedChat.Say(caller, "Cannot get what you're aiming at to spawn the schematic.");
                return;
            }


            // Trying to get better spot where they're aiming, so the schematic doesn't just spawn straight in the floor
            hit.point += new Vector3(0, 1, 0);
            var   fullcommand       = string.Join(" ", command).ToLower();
            var   keepLocation      = false;
            var   keepHealth        = false;
            var   keepState         = true;
            ulong SpecificSteamid64 = 0;
            ulong specificgroup     = 0;

            if (fullcommand.Contains("-keeppos"))
            {
                keepLocation = true;
            }
            if (keepLocation == false && Schematics.Instance.Configuration.Instance.MaxDistanceToLoadSchematic != 0 && hit.distance > Schematics.Instance.Configuration.Instance.MaxDistanceToLoadSchematic)
            {
                UnturnedChat.Say(caller, "You are aiming to somewhere past the configurable Max Distance to Load Schematic.");
                return;
            }
            if (fullcommand.Contains("-keephealth"))
            {
                keepHealth = true;
            }
            if (fullcommand.Contains("-nostate"))
            {
                keepState = false;
            }
            if (fullcommand.Contains("-setowner"))
            {
                SpecificSteamid64 = player.CSteamID.m_SteamID;
            }
            if (fullcommand.Contains("-setgroup"))
            {
                specificgroup = player.Player.quests.groupID.m_SteamID;
            }

            var match = Schematics.steamid64Regex.Match(fullcommand);

            if (match.Success && ulong.TryParse(match.Value, out var result))
            {
                SpecificSteamid64 = result;
            }
            var name = command[0].Replace(" ", "");

            if (Schematics.Instance.Configuration.Instance.UseDatabase)
            {
                var Schematic = Schematics.Instance.SchematicsDatabaseManager.GetSchematicByName(name);
                if (Schematic == null)
                {
                    UnturnedChat.Say(caller, $"Cannot find {name} in Database");
                    return;
                }

                var fs = new FileStream(ReadWrite.PATH + ServerSavedata.directory + "/" + Provider.serverID + $"/Rocket/Plugins/Schematics/Saved/{name}.dat", FileMode.Create, FileAccess.Write);
                fs.Write(Schematic.SchmeticBytes, 0, Schematic.SchmeticBytes.Length);
                fs.Close();
            }

            var river   = ServerSavedata.openRiver($"/Rocket/Plugins/Schematics/Saved/{name}.dat", true);
            var verison = river.readByte();

            if (verison == 1)
            {
                UnturnedChat.Say(caller, $"Cannot load {name} as it was saved on a different version which is no longer compatible");
                return;
            }

            var useDatabase = river.readBoolean();
            var Time        = river.readUInt32();

            if (DateTimeOffset.FromUnixTimeSeconds(Time).ToLocalTime() == DateTimeOffset.MinValue)
            {
                UnturnedChat.Say(caller, $"Cannot find {name}.");
                return;
            }

            var playerposition = river.readSingleVector3();

            UnturnedChat.Say(player, $"Loading {name} saved at {DateTimeOffset.FromUnixTimeSeconds(Time).ToLocalTime().ToString()}");
            var setgroupstring     = specificgroup == 0 ? "false" : specificgroup.ToString();
            var setsteamid64string = SpecificSteamid64 == 0 ? "false" : SpecificSteamid64.ToString();

            Logger.Log($"Loading {name} for {player.CharacterName} with parameters Keep Position: {keepLocation}, Keep Health: {keepHealth}, Keep State: {keepState}, Set Group = {setgroupstring} Set Steamid64: {setsteamid64string}.");
            var barricadecountInt32 = river.readInt32();
            var structurecountInt32 = river.readInt32();
            var error = 0;

            for (var i = 0; i < barricadecountInt32; i++)
            {
                var barricadeid     = river.readUInt16();
                var barricadehealth = river.readUInt16();
                var barricadestate  = river.readBytes();
                var point           = river.readSingleVector3();
                var angleX          = river.readByte();
                var angleY          = river.readByte();
                var angleZ          = river.readByte();
                var owner           = river.readUInt64();
                var group           = river.readUInt64();
                var barricade       = new Barricade(barricadeid);
                if (keepHealth)
                {
                    barricade.health = barricadehealth;
                }
                if (keepState)
                {
                    barricade.state = barricadestate;
                }
                if (!keepLocation)
                {
                    point = point - playerposition + hit.point;
                }
                if (SpecificSteamid64 != 0)
                {
                    owner = SpecificSteamid64;
                }
                if (specificgroup != 0)
                {
                    group = specificgroup;
                }
                var rotation = Quaternion.Euler(angleX * 2, angleY * 2, angleZ * 2);
                //rotation.eulerAngles = new Vector3(angleX, angleY, angleZ);
                var barricadetransform = BarricadeManager.dropNonPlantedBarricade(barricade, point, rotation, owner, group);
                if (barricadetransform == null)
                {
                    error++;
                    return;
                }

                var InteractableStorage = barricadetransform.GetComponent <InteractableStorage>();
                if (InteractableStorage != null)
                {
                    BarricadeManager.sendStorageDisplay(barricadetransform, InteractableStorage.displayItem, InteractableStorage.displaySkin, InteractableStorage.displayMythic, InteractableStorage.displayTags, InteractableStorage.displayDynamicProps);
                }
            }

            if (error != 0)
            {
                Logger.Log($"Unexpected Barricade Error occured {error} times");
            }
            error = 0;
            for (var i = 0; i < structurecountInt32; i++)
            {
                var structureid     = river.readUInt16();
                var structurehealth = river.readUInt16();
                var point           = river.readSingleVector3();
                var angleX          = river.readByte();
                var angleY          = river.readByte();
                var angleZ          = river.readByte();
                var owner           = river.readUInt64();
                var group           = river.readUInt64();
                var structure       = new Structure(structureid);
                if (keepHealth)
                {
                    structure.health = structurehealth;
                }
                // For when nelson adds proper way to add structures
                if (!keepLocation)
                {
                    point = point - playerposition + hit.point;
                }

                if (SpecificSteamid64 != 0)
                {
                    owner = SpecificSteamid64;
                }
                if (specificgroup != 0)
                {
                    group = specificgroup;
                }
                var rotation = Quaternion.Euler(angleX * 2, angleY * 2, angleZ * 2);
                //rotation.eulerAngles = new Vector3(angleX, angleY, angleZ);
                if (!StructureManager.dropReplicatedStructure(structure, point, rotation, owner, group))
                {
                    error++;
                }
            }

            if (error != 0)
            {
                Logger.Log($"Unexpected Barricade Error occured {error} times");
            }
            river.closeRiver();
            UnturnedChat.Say(player, $"Done, we have loaded Structures: {structurecountInt32} and Barricades: {barricadecountInt32} from {name}");
        }
        protected override async UniTask OnExecuteAsync()
        {
            if (Context.Parameters.Length == 0 || string.IsNullOrWhiteSpace(Context.Parameters[0]))
            {
                throw new CommandWrongUsageException(Context);
            }
            if (!(Context.Actor is UnturnedUser uPlayer))
            {
                throw new CommandWrongUsageException(Context);
            }

            if (!Physics.Raycast(uPlayer.Player.Player.look.aim.position, uPlayer.Player.Player.look.aim.forward,
                                 out var hit))
            {
                throw new UserFriendlyException(m_StringLocalizer["CommandLoadSchematic:no_target"]);
                return;
            }


            // Trying to get better spot where they're aiming, so the schematic doesn't just spawn straight in the floor
            hit.point += new Vector3(0, 1, 0);
            var   fullcommand       = string.Join(" ", Context.Parameters).ToLower();
            var   keepLocation      = false;
            var   keepHealth        = false;
            var   keepState         = true;
            ulong SpecificSteamid64 = 0;
            ulong specificgroup     = 0;

            if (fullcommand.Contains("-keeppos"))
            {
                keepLocation = true;
            }
            var maxdist = m_Configuration.GetSection("MaxDistanceToLoadSchematic").Get <int>();

            if (keepLocation == false && maxdist != 0 && hit.distance > maxdist)
            {
                throw new UserFriendlyException(m_StringLocalizer["CommandLoadSchematic:too_far", maxdist]);
            }
            if (fullcommand.Contains("-keephealth"))
            {
                keepHealth = true;
            }
            if (fullcommand.Contains("-nostate"))
            {
                keepState = false;
            }
            if (fullcommand.Contains("-setowner"))
            {
                SpecificSteamid64 = uPlayer.SteamId.m_SteamID;
            }
            if (fullcommand.Contains("-setgroup"))
            {
                // Strange issues if the player has no group, no idea why or how the Group ID got equal to the player's Steamid, but this breaks /checkowner and a few other things
                // [5/15/2020 4:39:04 PM] [Info] Schematics >> Loading sillysignsandstuff for Oh Wonder with parameters Keep Position: True, Keep Health: False, Keep State: True, Set Group = 76561198138254281 Set Steamid64: 76561198138254281.
                if (uPlayer.Player.Player.quests.groupID != CSteamID.Nil &&
                    uPlayer.Player.Player.quests.groupID.m_SteamID != uPlayer.SteamId.m_SteamID)
                {
                    specificgroup = uPlayer.Player.Player.quests.groupID.m_SteamID;
                }
            }

            var match = new Regex(@"[0-9]{17}", RegexOptions.IgnoreCase).Match(fullcommand);

            if (match.Success && ulong.TryParse(match.Value, out var result))
            {
                SpecificSteamid64 = result;
            }
            var name = Context.Parameters[0].Replace(" ", "");

            var           ConfigUseDB = m_Configuration.GetSection("UseDatabase").Get <bool>();
            SchematicData foundSchematic;

            if (ConfigUseDB)
            {
                var Schematic = await m_SchematicsInfoRepo.FindSchematicAsync(name);

                if (Schematic == null)
                {
                    throw new UserFriendlyException(m_StringLocalizer["CommandLoadSchematic:cannot_find_schematic",
                                                                      new { Name = name }]);
                }

                foundSchematic = Schematic;
            }
            else
            {
                var Schematics = await m_DataStore.LoadAsync <SchematicsDataStore>("Schematics");

                if (Schematics == null)
                {
                    throw new UserFriendlyException(m_StringLocalizer["CommandLoadSchematic:cannot_find_schematic",
                                                                      new { Name = name }]);
                }
                var FindTheSchematic =
                    Schematics.Schematics.FirstOrDefault(i => i.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
                if (FindTheSchematic == null)
                {
                    throw new UserFriendlyException(m_StringLocalizer["CommandLoadSchematic:cannot_find_schematic",
                                                                      new { Name = name }]);
                }

                foundSchematic = FindTheSchematic;
            }


            List <BarricadeToSpawn> barricadesToSpawn = new List <BarricadeToSpawn>();
            List <StructureToSpawn> structuresToSpawn = new List <StructureToSpawn>();



            var river = new BinaryReader(new MemoryStream(foundSchematic.Schematic));

            var verison = river.ReadByte();

            var useDatabase = river.ReadBoolean();
            var Time        = river.ReadUInt32();


            var playerposition = new Vector3(river.ReadSingle(), river.ReadSingle(), river.ReadSingle());
            //Loading {name} saved at {DateTimeOffset.FromUnixTimeSeconds(Time).ToLocalTime().ToString()}
            await Context.Actor.PrintMessageAsync(m_StringLocalizer["CommandLoadSchematic:Loading_Schematic",
                                                                    new { Name = name, TimeSaved = DateTimeOffset.FromUnixTimeSeconds(Time).ToLocalTime().ToString() }]);

            var setgroupstring     = specificgroup == 0 ? "false" : specificgroup.ToString();
            var setsteamid64string = SpecificSteamid64 == 0 ? "false" : SpecificSteamid64.ToString();

            m_Logger.LogInformation(
                $"Loading {name} for {uPlayer.DisplayName} with parameters Keep Position: {keepLocation}, Keep Health: {keepHealth}, Keep State: {keepState}, Set Group = {setgroupstring} Set Steamid64: {setsteamid64string}.");
            var barricadecountInt32 = river.ReadInt32();
            var structurecountInt32 = river.ReadInt32();
            var error = 0;

            for (var i = 0; i < barricadecountInt32; i++)
            {
                var barricadeid     = river.ReadUInt16();
                var barricadehealth = river.ReadUInt16();
                var barricadestate  = river.ReadBytes(river.ReadUInt16());
                var point           = new Vector3(river.ReadSingle(), river.ReadSingle(), river.ReadSingle());
                var angleX          = river.ReadByte();
                var angleY          = river.ReadByte();
                var angleZ          = river.ReadByte();
                var owner           = river.ReadUInt64();
                var group           = river.ReadUInt64();
                var barricade       = new Barricade(barricadeid);
                if (keepHealth)
                {
                    barricade.health = barricadehealth;
                }
                if (keepState)
                {
                    barricade.state = barricadestate;
                }
                if (!keepLocation)
                {
                    point = point - playerposition + hit.point;
                }
                if (SpecificSteamid64 != 0)
                {
                    owner = SpecificSteamid64;
                }
                if (specificgroup != 0)
                {
                    group = specificgroup;
                }
                var rotation = Quaternion.Euler(angleX * 2, angleY * 2, angleZ * 2);
                //rotation.eulerAngles = new Vector3(angleX, angleY, angleZ);
                barricadesToSpawn.Add(new BarricadeToSpawn(barricade, point, rotation, owner, group));
            }

            if (error != 0)
            {
                m_Logger.LogInformation($"Unexpected Barricade Error occured {error} times");
            }
            error = 0;
            for (var i = 0; i < structurecountInt32; i++)
            {
                var structureid     = river.ReadUInt16();
                var structurehealth = river.ReadUInt16();
                var point           = new Vector3(river.ReadSingle(), river.ReadSingle(), river.ReadSingle());
                var angleX          = river.ReadByte();
                var angleY          = river.ReadByte();
                var angleZ          = river.ReadByte();
                var owner           = river.ReadUInt64();
                var group           = river.ReadUInt64();
                var structure       = new Structure(structureid);
                if (keepHealth)
                {
                    structure.health = structurehealth;
                }
                // For when nelson adds proper way to add structures
                if (!keepLocation)
                {
                    point = point - playerposition + hit.point;
                }

                if (SpecificSteamid64 != 0)
                {
                    owner = SpecificSteamid64;
                }
                if (specificgroup != 0)
                {
                    group = specificgroup;
                }
                var rotation = Quaternion.Euler(angleX * 2, angleY * 2, angleZ * 2);
                //rotation.eulerAngles = new Vector3(angleX, angleY, angleZ);
                structuresToSpawn.Add(new StructureToSpawn(structure, point, rotation, owner, group));
            }

            await UniTask.SwitchToMainThread();

            foreach (var barricadeToSpawn in barricadesToSpawn)
            {
                var barricadetransform =
                    BarricadeManager.dropNonPlantedBarricade(barricadeToSpawn.Barricade, barricadeToSpawn.Point, barricadeToSpawn.Rotation, barricadeToSpawn.Owner, barricadeToSpawn.Group);
                if (barricadetransform == null)
                {
                    error++;
                    continue;
                }

                var InteractableStorage = barricadetransform.GetComponent <InteractableStorage>();
                if (InteractableStorage != null)
                {
                    BarricadeManager.sendStorageDisplay(barricadetransform, InteractableStorage.displayItem,
                                                        InteractableStorage.displaySkin, InteractableStorage.displayMythic,
                                                        InteractableStorage.displayTags, InteractableStorage.displayDynamicProps);
                }
            }

            foreach (var structureToSpawn in structuresToSpawn)
            {
                if (!StructureManager.dropReplicatedStructure(structureToSpawn.Structure, structureToSpawn.Point, structureToSpawn.Rotation, structureToSpawn.Owner, structureToSpawn.Group))
                {
                    error++;
                }
            }

            await UniTask.SwitchToThreadPool();

            if (error != 0)
            {
                m_Logger.LogInformation($"Unexpected Barricade Error occured {error} times");
            }
            river.Dispose();
            //UnturnedChat.Say(player, $"Done, we have loaded Structures: {structurecountInt32} and Barricades: {barricadecountInt32} from {name}");
            await Context.Actor.PrintMessageAsync(m_StringLocalizer["CommandLoadSchematic:Loading_Schematic_Finished",
                                                                    new { Name = name, StructureCount = structurecountInt32, BarricadeCount = barricadecountInt32 }]);
        }