Пример #1
0
        private void HandleLocalCommand(string msg, ref bool sendToOthers)
        {
            if (msg.Length == 0 || msg[0] != '/')
            {
                return;
            }
            var cmdFeedback = new CommandFeedback((format, fields) =>
            {
                MyAPIGateway.Utilities.ShowMessage("EqUtils", string.Format(format, fields));
            });

            try
            {
                var     args = ParseArguments(msg, 1);
                Command cmd;
                lock (m_commands)
                    if (!m_commands.TryGetValue(args[0], out cmd))
                    {
                        Log(MyLogSeverity.Debug, "Unknown command {0}", args[0]);
                        return;
                    }

                var player = MyAPIGateway.Session.Player;
                if (player == null)
                {
                    Log(MyLogSeverity.Warning, "Attempted to run a local command without a player.");
                    return;
                }
                sendToOthers = false;
                if (!cmd.AllowedSessionType.Flagged(MyAPIGateway.Session.SessionType()))
                {
                    Log(MyLogSeverity.Debug, "Unable to run {0} on a session of type {1}; it requires type {2}", args[0], MyAPIGateway.Session.SessionType(), cmd.AllowedSessionType);
                    return;
                }
                if (!cmd.CanPromotionLevelUse(player.PromoteLevel))
                {
                    cmdFeedback.Invoke("EqUtils", "You must be at least " + cmd.MinimumLevel + " to use this command");
                    return;
                }
                var result = cmd.Process(cmdFeedback, args);
                if (result != null)
                {
                    cmdFeedback.Invoke(result);
                }
            }
            catch (ArgumentException e)
            {
                Log(MyLogSeverity.Debug, "Failed to parse \"{0}\".  Error:\n{1}", msg, e.ToString());
            }
            catch (Exception e)
            {
                Log(MyLogSeverity.Critical, "Failed to process \"{0}\".  Error:\n{1}", msg, e.ToString());
            }
        }
Пример #2
0
        private void HandleGlobalCommand(ulong steamID, string msg)
        {
            if (msg.Length == 0 || msg[0] != '/')
            {
                return;
            }
            try
            {
                var     args = ParseArguments(msg, 1);
                Command cmd;
                lock (m_commands)
                    if (!m_commands.TryGetValue(args[0], out cmd))
                    {
                        Log(MyLogSeverity.Debug, "Unknown command {0}", args[0]);
                        return;
                    }

                var player = MyAPIGateway.Players.GetPlayerBySteamId(steamID);
                if (player == null)
                {
                    Log(MyLogSeverity.Warning, "Attempted unable to determine player instance for Steam ID {0}", steamID);
                    return;
                }
                if (!MyAPIGateway.Session.SessionType().Flagged(cmd.AllowedSessionType))
                {
                    Log(MyLogSeverity.Debug, "Unable to run {0} on a session of type {1}; it requires type {2}", args[0], MyAPIGateway.Session.SessionType(), cmd.AllowedSessionType);
                    return;
                }
                var cmdFeedback = new CommandFeedback((format, fields) =>
                {
                    var content = string.Format(format, fields);
                    MyVisualScriptLogicProvider.SendChatMessage(content, "EqProcUtils", player.IdentityId);
                });
                if (!cmd.CanPromotionLevelUse(player.PromoteLevel))
                {
                    cmdFeedback.Invoke("You must be at least a {0} to use the {1} command.  You are are {2}", cmd.MinimumLevel, args[0], player.PromoteLevel);
                    Log(MyLogSeverity.Debug, "Player {0} ({1}) attempted to run {2} at level {3}", player.DisplayName, player.PromoteLevel, args[0], cmd.MinimumLevel);
                    return;
                }
                var result = cmd.Process(cmdFeedback, args);
                if (result != null)
                {
                    cmdFeedback.Invoke(result);
                }
            }
            catch (ArgumentException e)
            {
                Log(MyLogSeverity.Debug, "Failed to parse \"{0}\".  Error:\n{1}", msg, e.ToString());
            }
            catch (Exception e)
            {
                Log(MyLogSeverity.Critical, "Failed to process \"{0}\".  Error:\n{1}", msg, e.ToString());
            }
        }
        private string ProcessSpawn(CommandFeedback feedback, Dictionary <string, object> kwargs)
        {
            var generatorModule = Manager.GetDependencyProvider <StationGeneratorManager>();

            if (generatorModule == null)
            {
                return("No station generator module means no stations");
            }
            var factionModule = Manager.GetDependencyProvider <ProceduralFactions>();

            if (factionModule == null)
            {
                return("No faction module means no stations");
            }

            var debugMode  = (bool)kwargs["debug"];
            var roomCount  = (int?)kwargs["rooms"];
            var seedVal    = (long)kwargs["seed"];
            var population = (int?)kwargs["population"];
            var position   = MyAPIGateway.Session.Camera.Position + MyAPIGateway.Session.Camera.WorldMatrix.Forward * 100;
            var seed       = new ProceduralConstructionSeed(factionModule.SeedAt(position), new Vector4D(position, 0.5), null, seedVal, population);

            MyAPIGateway.Parallel.Start(() =>
            {
                ProceduralConstruction construction = null;
                ConstructionCopy grids;
                if (!generatorModule.GenerateFromSeedAndRemap(seed, ref construction, out grids, roomCount))
                {
                    this.Error("Failed to generate");
                    feedback.Invoke("Failed to generate");
                    return;
                }
                if (grids == null)
                {
                    this.Error("Failed to generate: Output grids are null");
                    feedback.Invoke("Failed to generate: Output grids are null");
                    return;
                }
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                {
                    var result             = grids.SpawnAsync();
                    result.ForceDebugDraw |= debugMode;
                });
            });
            return(null);
        }
        private string ProcessInfo(CommandFeedback feedback, string partName)
        {
            LogMux logger = (level, format, args) =>
            {
                this.Log(level, format, args);
                feedback?.Invoke(format, args);
            };
            var part = m_partManager.FirstOrDefault(test => test.Prefab.Id.SubtypeName.ToLower().Contains(partName.ToLower()));

            if (part == null)
            {
                return("Unable to find part with name \"" + partName + "\"");
            }
            var info = part.BlockSetInfo;

            logger(MyLogSeverity.Info, "Part info for {0}\nBlock type counts:", part.Name);
            foreach (var kv in info.BlockCountByType)
            {
                logger(MyLogSeverity.Info, "{0}: {1}", kv.Key, kv.Value);
            }
            logger(MyLogSeverity.Info, "Total power consumption/storage: {0:e}:{1:e}  Groups:", info.TotalPowerNetConsumption, info.TotalPowerStorage);
            foreach (var kv in info.PowerConsumptionByGroup)
            {
                logger(MyLogSeverity.Info, "{0}: {1}", kv.Key, kv.Value);
            }
            logger(MyLogSeverity.Info, "Total inventory capacity: {0:e}", info.TotalInventoryCapacity);
            logger(MyLogSeverity.Info, "Total component cost:");
            foreach (var kv in info.ComponentCost)
            {
                logger(MyLogSeverity.Info, "{0}: {1}", kv.Key.Id.SubtypeName, kv.Value);
            }
            logger(MyLogSeverity.Info, "Production quotas:");
            foreach (var pi in MyDefinitionManager.Static.GetPhysicalItemDefinitions())
            {
                logger(MyLogSeverity.Info, "{0}: {1}", pi.Id, info.TotalProduction(pi.Id));
            }
            foreach (var pi in MyDefinitionManager.Static.GetDefinitionsOfType <MyComponentDefinition>())
            {
                logger(MyLogSeverity.Info, "{0}: {1}", pi.Id, info.TotalProduction(pi.Id));
            }
            foreach (var gas in MyDefinitionManager.Static.GetDefinitionsOfType <MyGasProperties>())
            {
                logger(MyLogSeverity.Info, "{0}: {1}", gas.Id, info.TotalProduction(gas.Id));
            }
            logger(MyLogSeverity.Info, "Gas storage");
            foreach (var gas in MyDefinitionManager.Static.GetDefinitionsOfType <MyGasProperties>())
            {
                logger(MyLogSeverity.Info, "{0}: {1}", gas.Id, info.TotalGasStorage(gas.Id));
            }
            return(null);
        }
Пример #5
0
        private string RunSideload(CommandFeedback feedback, string prefabKey)
        {
            var partManager = Manager.GetDependencyProvider <PartManager>();

            if (partManager == null)
            {
                return("Can't sideload parts when there is no part manager");
            }
            var fileName = prefabKey;

            if (!fileName.EndsWith(".sbc", StringComparison.OrdinalIgnoreCase))
            {
                fileName += ".sbc";
            }
            if (!MyAPIGateway.Utilities.FileExistsInLocalStorage(fileName, typeof(DesignTools)))
            {
                return($"File {fileName} has not been exported.");
            }
            using (var stream = MyAPIGateway.Utilities.ReadFileInLocalStorage(fileName, typeof(DesignTools)))
            {
                var content = stream.ReadToEnd();
                try
                {
                    var data = MyAPIGateway.Utilities.SerializeFromXML <MyObjectBuilder_Definitions>(content);
                    if (data.Prefabs == null || data.Prefabs.Length < 1)
                    {
                        return("The specified file doesn't seem to contain prefabs");
                    }
                    foreach (var prefab in data.Prefabs)
                    {
                        var lks = new MyPrefabDefinition();
                        // We don't actually link this into the definition manager so we can have a null mod context.
                        lks.Init(prefab, null);
                        lks.InitLazy(prefab);
                        partManager.Load(lks, true);
                        this.Debug("Sideloaded {0}", prefab.Id.SubtypeName);
                        feedback.Invoke("Sideloaded {0}", prefab.Id.SubtypeName);
                    }
                }
                catch (Exception e)
                {
                    this.Error("Failed to sideload prefab {0}.  Error:\n{1}", prefabKey, e.ToString());
                    return($"Failed to load: {e.Message}");
                }
            }
            return(null);
        }
Пример #6
0
        private void Process(CommandFeedback feedback, IMyCubeGrid grid)
        {
            if (grid.CustomName == null || !grid.CustomName.StartsWithICase("EqProcBuild"))
            {
                return;
            }
            var ob = grid.GetObjectBuilder(true) as MyObjectBuilder_CubeGrid;

            if (ob == null)
            {
                return;
            }
            this.Info("Begin processing {0}", grid.CustomName);
            feedback?.Invoke("Processing {0}", grid.CustomName);
            try
            {
                var dummyDel  = new List <MyTuple <MyObjectBuilder_CubeBlock, string> >();
                var blockKeep = new List <MyObjectBuilder_CubeBlock>();
                var blockMap  = new Dictionary <Vector3I, MyObjectBuilder_CubeBlock>(Vector3I.Comparer);
                foreach (var block in ob.CubeBlocks)
                {
                    var mount = false;
                    foreach (var name in block.ConfigNames())
                    {
                        if (!name.StartsWithICase(MountDelegated) && !name.StartsWithICase(ReservedSpaceDelegated))
                        {
                            continue;
                        }
                        dummyDel.Add(MyTuple.Create(block, name));
                        mount = true;
                        break;
                    }
                    if (mount)
                    {
                        continue;
                    }

                    var      blockMin = (Vector3I)block.Min;
                    Vector3I blockMax;
                    BlockTransformations.ComputeBlockMax(block, out blockMax);
                    for (var rangeItr = new Vector3I_RangeIterator(ref blockMin, ref blockMax); rangeItr.IsValid(); rangeItr.MoveNext())
                    {
                        blockMap[rangeItr.Current] = block;
                    }
                    blockKeep.Add(block);
                }
                this.Info("Found {0} blocks to keep, {1} block mounts to remap", blockKeep.Count, dummyDel.Count);
                foreach (var pair in dummyDel)
                {
                    var block   = pair.Item1;
                    var useName = pair.Item2;

                    IEnumerable <Base6Directions.Direction> dirs = Base6Directions.EnumDirections;
                    var def       = MyDefinitionManager.Static.GetCubeBlockDefinition(pair.Item1);
                    var transform = new MatrixI(block.BlockOrientation);
                    if (def?.MountPoints != null)
                    {
                        var mountDirs = new HashSet <Base6Directions.Direction>();
                        foreach (var mount in def.MountPoints)
                        {
                            mountDirs.Add(Base6Directions.GetDirection(Vector3I.TransformNormal(mount.Normal, ref transform)));
                        }
                    }

                    var args     = useName.Split(' ');
                    var keepArgs = new List <string>(args.Length);
                    foreach (var arg in args)
                    {
                        if (arg.StartsWithICase(PartDummyUtils.ArgumentMountDirection))
                        {
                            Base6Directions.Direction dir;
                            if (Enum.TryParse(arg.Substring(2), out dir))
                            {
                                dirs = new[] { transform.GetDirection(Base6Directions.GetOppositeDirection(dir)) }
                            }
                            ;
                            else
                            {
                                this.Error("Failed to parse direction argument \"{0}\"", arg);
                                feedback?.Invoke("Error: Failed to parse direction argument \"{0}\"", arg);
                            }
                        }
                        else
                        {
                            keepArgs.Add(arg);
                        }
                    }
                    useName = string.Join(" ", keepArgs);

                    MyObjectBuilder_CubeBlock outputBlock = null;
                    var outputDir = Base6Directions.Direction.Forward;
                    foreach (var dir in dirs)
                    {
                        MyObjectBuilder_CubeBlock tmp;
                        if (!blockMap.TryGetValue(block.Min + Base6Directions.GetIntVector(dir), out tmp))
                        {
                            continue;
                        }
                        if (tmp.ConfigNames().Any(x => x.StartsWithICase(MountDelegated)))
                        {
                            continue;
                        }
                        if (outputBlock != null)
                        {
                            this.Error("Multiple directions found for {0}", pair.Item2);
                            feedback?.Invoke("Error: Multiple directions found for {0}", pair.Item2);
                        }
                        outputBlock = tmp;
                        outputDir   = dir;
                    }
                    if (outputBlock == null || !ApplyDelegate(ob, block, useName, outputBlock, outputDir))
                    {
                        this.Error("Failed to find delegated mount point for {0}", pair.Item2);
                        feedback?.Invoke("Error: Failed to find delegated mount point for {0}", pair.Item2);
                    }
                }
                ob.CubeBlocks = blockKeep;

                // Grab related grids!
                var relatedGrids = new HashSet <IMyCubeGrid> {
                    grid
                };
                var scanRelated           = new Queue <IMyCubeGrid>();
                var relatedGridController = new Dictionary <IMyCubeGrid, IMyCubeBlock>();
                scanRelated.Enqueue(grid);
                while (scanRelated.Count > 0)
                {
                    var          subGrid = scanRelated.Dequeue();
                    IMyCubeBlock controllerForThisGrid = null;
                    relatedGridController.TryGetValue(subGrid, out controllerForThisGrid);

                    subGrid.GetBlocks(null, (y) =>
                    {
                        var x = y?.FatBlock;
                        if (x == null)
                        {
                            return(false);
                        }
                        var childGrid = (x as IMyMechanicalConnectionBlock)?.TopGrid;
                        if (childGrid != null && relatedGrids.Add(childGrid))
                        {
                            scanRelated.Enqueue(childGrid);
                            relatedGridController[childGrid] = x.CubeGrid == grid ? x : controllerForThisGrid;
                        }
                        var parentGrid = (x as IMyAttachableTopBlock)?.Base?.CubeGrid;
                        // ReSharper disable once InvertIf
                        if (parentGrid != null && relatedGrids.Add(parentGrid))
                        {
                            scanRelated.Enqueue(parentGrid);
                            relatedGridController[parentGrid] = x.CubeGrid == grid ? x : controllerForThisGrid;
                        }
                        return(false);
                    });
                }
                relatedGrids.Remove(grid);
                var removedNoController = relatedGrids.RemoveWhere(x => !relatedGridController.ContainsKey(x));
                if (removedNoController > 0)
                {
                    this.Error("Failed to find the mechanical connection block for all subgrids.  {0} will be excluded",
                               removedNoController);
                    feedback?.Invoke("Error: Failed to find the mechanical connection block for all subgrids.  {0} will be excluded",
                                     removedNoController);
                }
                // Need to add reserved space for subgrids so they don't overlap.  So compute that.  Yay!
                foreach (var rel in relatedGrids)
                {
                    IMyCubeBlock root;
                    if (!relatedGridController.TryGetValue(rel, out root))
                    {
                        this.Error("Unable to find the mechanical connection for grid {0}", rel.CustomName);
                        feedback?.Invoke("Error: Unable to find the mechanical connection for grid {0}",
                                         rel.CustomName);
                        continue;
                    }
                    MyObjectBuilder_CubeBlock blockDest;
                    if (blockMap.TryGetValue(root.Min, out blockDest))
                    {
                        var blockLocal = (MatrixD) new MatrixI(blockDest.BlockOrientation).GetFloatMatrix();
                        blockLocal.Translation = (Vector3I)blockDest.Min * grid.GridSize;
                        var blockWorld = MatrixD.Multiply(blockLocal, grid.WorldMatrix);

                        var worldAABB = rel.WorldAABB;
                        worldAABB = Utilities.TransformBoundingBox(worldAABB, MatrixD.Invert(blockWorld));
                        var gridAABB = new BoundingBoxI(Vector3I.Floor(worldAABB.Min / grid.GridSize), Vector3I.Ceiling(worldAABB.Max / grid.GridSize));
                        var code     = $"{PartMetadata.ReservedSpacePrefix} NE:{gridAABB.Min.X}:{gridAABB.Min.Y}:{gridAABB.Min.Z} PE:{gridAABB.Max.X}:{gridAABB.Max.Y}:{gridAABB.Max.Z}";
                        this.Info("Added reserved space for subgrid {0}: Spec is \"{1}\"", rel.CustomName, code);
                        if (blockDest.Name == null || blockDest.Name.Trim().Length == 0)
                        {
                            blockDest.Name = code;
                        }
                        else
                        {
                            blockDest.Name += PartMetadata.MultiUseSentinel + code;
                        }
                    }
                    else
                    {
                        this.Error("Unable to find the OB for grid block {0} ({1}, {2}, {3}).  Is it a delegate?", (root as IMyTerminalBlock)?.CustomName ?? root.Name, root.Min.X, root.Min.Y, root.Min.Z);
                        feedback?.Invoke("Unable to the find OB for grid block {0} ({1}, {2}, {3}).  Was it a delegate?", (root as IMyTerminalBlock)?.CustomName ?? root.Name, root.Min.X, root.Min.Y, root.Min.Z);
                    }
                }

                var allGrids = new List <MyObjectBuilder_CubeGrid>(relatedGrids.Count + 1)
                {
                    ob
                };
                allGrids.AddRange(relatedGrids.Select(relGrid => relGrid.GetObjectBuilder(false)).OfType <MyObjectBuilder_CubeGrid>());

                // Compose description: TODO I'd love if this actually worked :/
                // var storage = new MyPartMetadata();
                // storage.InitFromGrids(ob, allGrids);
                // var data = Convert.ToBase64String(MyAPIGateway.Utilities.SerializeToBinary(storage.GetObjectBuilder()));

                var defOut = new MyObjectBuilder_PrefabDefinition()
                {
                    Id        = new SerializableDefinitionId(typeof(MyObjectBuilder_PrefabDefinition), grid.CustomName),
                    CubeGrids = allGrids.ToArray()
                };

                var fileName = grid.CustomName + ".sbc";
                this.Info("Saving {1} grids as {0}", fileName, defOut.CubeGrids.Length);
                feedback?.Invoke("Saving {1} grids as {0}", fileName, defOut.CubeGrids.Length);

                var mishMash = new MyObjectBuilder_Definitions()
                {
                    Prefabs = new MyObjectBuilder_PrefabDefinition[] { defOut }
                };
                var writer = MyAPIGateway.Utilities.WriteBinaryFileInLocalStorage(fileName, typeof(DesignTools));
                var obCode = MyAPIGateway.Utilities.SerializeToXML(mishMash);
                obCode = obCode.Replace("encoding=\"utf-16\"", "encoding=\"utf-8\"");
                writer.Write(Encoding.UTF8.GetBytes(obCode));
                writer.Close();
            }
            catch (Exception e)
            {
                this.Error("Failed to parse.  Error:\n{0}", e.ToString());
            }
        }