public override void HandleCallback(string callback) { switch (callback) { case "unicast": MyIGCMessage message = Drone.NetworkService.GetUnicastListener().AcceptMessage(); if (message.Data == null) { Drone.LogToLcd($"\nNo Message"); } if (message.Tag == DockingRequestChannel) { Drone.LogToLcd("\nReceived Docking Request"); IMyShipConnector dockingPort = GetFreeDockingPort(); if (dockingPort == null) { Drone.LogToLcd("\nNo Free Docking Port"); } else { MyTuple <Vector3D, Vector3D, Vector3D> payload = new MyTuple <Vector3D, Vector3D, Vector3D>(); payload.Item1 = dockingPort.GetPosition() + dockingPort.WorldMatrix.Forward * 40; payload.Item2 = dockingPort.GetPosition() + 1.5 * dockingPort.WorldMatrix.Forward; Drone.LogToLcd($"\nClearance granted: {message.Source}"); Drone.LogToLcd($"\nApproach: {payload.Item1.ToString()}"); Drone.LogToLcd($"\nDocking Port: { payload.Item2.ToString()}"); Drone.Program.IGC.SendUnicastMessage(message.Source, DockingRequestChannel, payload); } } else if (message.Tag == "Notifications") { Drone.LogToLcd($"Received notification:{message.Data.ToString()}"); DroneKlaxon.LoopPeriod = 2f; DroneKlaxon.Play(); } else if (message.Tag == "survey_reports") { MyTuple <long, string, double, Vector3D, Vector3D, Vector3D> report = (MyTuple <long, string, double, Vector3D, Vector3D, Vector3D>)message.Data; Drone.LogToLcd($"Received survey_report: {report.ToString()}"); //TODO: This needs to be in a persistence layer, not the CustomData MyIni ini = new MyIni(); MyIniParseResult config; if (!ini.TryParse(Drone.Program.Me.CustomData, out config)) { throw new Exception($"Error parsing config: {config.ToString()}"); } //TODO: what about multiple deposits? ini.Set($"deposit {report.Item1.ToString()}", "deposit_type", report.Item2.ToString()); ini.Set($"deposit {report.Item1.ToString()}", "deposit_depth", report.Item3.ToString()); ini.Set($"deposit {report.Item1.ToString()}", "top_left_corner", report.Item4.ToString()); ini.Set($"deposit {report.Item1.ToString()}", "top_right_corner", report.Item5.ToString()); ini.Set($"deposit {report.Item1.ToString()}", "bottom_left_corner", report.Item6.ToString()); ini.Set($"deposit {report.Item1.ToString()}", "index", 0); Drone.Program.Me.CustomData = ini.ToString(); } else if (message.Tag == "tunnel_complete") { MyIni ini = new MyIni(); MyIniParseResult config; if (!ini.TryParse(Drone.Program.Me.CustomData, out config)) { throw new Exception($"Error parsing config: {config.ToString()}"); } int completedIndex = (int)message.Data; List <string> sections = new List <string>(); ini.GetSections(sections); IEnumerable <string> deposits = sections.Where(record => record.StartsWith("deposit")); string deposit; if (deposits != null && deposits.Count() != 0) { deposit = deposits.First(); } else { throw new Exception("No deposit data found!"); } ini.Set(deposit, "index", completedIndex + 1); Drone.Program.Me.CustomData = ini.ToString(); } break; case "docking_request_pending": ProcessDockingRequest(); break; case "recall_miner": Drone.LogToLcd("Recalling miner"); Drone.Program.IGC.SendUnicastMessage(MinerAddress, "recall", "recall"); break; case "recall_surveyor": Drone.LogToLcd("Recalling surveyor"); Drone.Program.IGC.SendUnicastMessage(SurveyorAddress, "recall", "recall"); break; case "deploy_miner": Drone.LogToLcd("Launching miner"); List <IMyProgrammableBlock> miners = new List <IMyProgrammableBlock>(); Drone.Grid().GetBlocksOfType(miners, pb => MyIni.HasSection(pb.CustomData, "miner")); //We only support one miner for now // Set the deposit details in the miners config IMyProgrammableBlock miner = miners.First(); MyIni minerConfig = new MyIni(); MyIniParseResult result; if (!minerConfig.TryParse(miner.CustomData, out result)) { Drone.LogToLcd(miner.CustomData); throw new Exception($"Error parsing config: {result.ToString()}"); } //Vector3D MiningSite = DepositCentre + 10 * Vector3D.Normalize(DepositNormal); //Vector3D TunnelEnd = DepositCentre - DepositDepth * Vector3D.Normalize(DepositNormal); //get deposit data from catalogue //calculate mining_site for next tunnel //calculate tunnel_end from mining_site and depth MyIni asteroidCatalogue = new MyIni(); asteroidCatalogue.TryParse(Drone.Program.Me.CustomData); Tunnel tunnel = new Tunnel(asteroidCatalogue); minerConfig.Set("miner", "mining_site", tunnel.StartingPoint.ToString()); minerConfig.Set("miner", "tunnel_end", tunnel.EndPoint.ToString()); minerConfig.Set("miner", "index", tunnel.TunnelIndex); miner.CustomData = minerConfig.ToString(); miner.TryRun("launch"); break; case "deploy_surveyor": Drone.LogToLcd("Launching surveyor"); List <IMyProgrammableBlock> surveyors = new List <IMyProgrammableBlock>(); Drone.Grid().GetBlocksOfType(surveyors, pb => MyIni.HasSection(pb.CustomData, "surveyor")); IMyProgrammableBlock surveyor = surveyors.First(); surveyor.TryRun("launch"); break; case "echo": Drone.LogToLcd("Echo"); DroneKlaxon.Play(); break; case "": // Just Ignore empty arguments break; default: Drone.LogToLcd($"\nDrone received unrecognized callback: {callback}"); break; } }