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()); } }
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); }
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); }
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()); } }