internal static void SetContextState(ContextCommand command, string context) { Log($"Context-State-Set: {context} => {command}"); var contextInCollection = contexts.Find(ctx => ctx.ID == context); if (contextInCollection == null && !(command == ContextCommand.Download || command == ContextCommand.Install)) { return; } else if (contextInCollection == null && context != "NONE") { contextInCollection = new Context(); contextInCollection.ID = context; contexts.Add(contextInCollection); } switch (command) { case ContextCommand.NONE: contextInCollection.Downloaded = contextInCollection.Active = contextInCollection.Installed = false; tcpClient.SendChannelMessage("set-context-state", $"cleaned:{context}"); config[nameof(activeContext)] = activeContext = context = "NONE"; break; case ContextCommand.Download: contextInCollection.Downloaded = true; tcpClient.SendChannelMessage("set-context-state", $"downloaded:{context}"); break; case ContextCommand.Install: contextInCollection.Installed = true; tcpClient.SendChannelMessage("set-context-state", $"installed:{context}"); break; case ContextCommand.Switch: config[nameof(activeContext)] = activeContext = context; contexts.ForEach(ctx => ctx.Active = false); contextInCollection.Active = true; tcpClient.SendChannelMessage("set-context-state", $"active:{context}"); break; case ContextCommand.Unswitch: activeContext = "NONE"; contextInCollection.Active = false; tcpClient.SendChannelMessage("set-context-state", $"deactive:{context}"); break; case ContextCommand.Remove: contextInCollection.Installed = false; contextInCollection.Downloaded = false; tcpClient.SendChannelMessage("set-context-state", $"removed:{context}"); break; default: break; } contextInCollection.Save(Path.Combine(recipeRepository, contextInCollection.ID, "meta")); }
private void PostAddItem(string helpText, ContextCommand contextCommand, CustomMenuHandler customMenuHandler) { menuHost.OnAddMenuItem(helpText, contextCommand, customMenuHandler); indexMenu++; menuHost.IncrementCommandId(); }
private ScriptingCommand CreateContextCommand(ActionInput actionInput, string commandAlias, Thing actionOwner) { ContextCommand contextCommand = actionOwner.Commands[commandAlias]; var executeDelegate = new CommandScriptExecuteDelegate(contextCommand.CommandScript.Execute); var guardsDelegate = new CommandScriptGuardsDelegate(contextCommand.CommandScript.Guards); return(new ScriptingCommand(contextCommand.CommandKey, executeDelegate, guardsDelegate, SecurityRole.all, actionInput)); }
private void InsertMenuItem(ref MenuItemInfo menuItemInfo, string helpText, ContextCommand contextCommand, CustomMenuHandler customMenuHandler) { CheckIdSpace(); bool result = SafeNativeMethods.InsertMenuItem(hmenu, indexMenu, true, ref menuItemInfo); if (!result) { throw new Win32Exception(); } PostAddItem(helpText, contextCommand, customMenuHandler); }
//protected Dictionary<int, MappedInput> mappingDict_ = new Dictionary<int, MappedInput>(); public bool PollInput( KeyMap.GameInput input, ContextCommand.TriggerType triggerType, out float axis) { switch (triggerType) { case ContextCommand.TriggerType.Down: return mappings_[(int)input].PollInputDown(out axis); case ContextCommand.TriggerType.Changed: return mappings_[(int)input].PollInputChanged(out axis); default: return mappings_[(int)input].PollInputHold(out axis); } }
internal static int ExecuteScript(ContextCommand command, string commandFilePath) { Log("Executing script file: " + commandFilePath); SendProgressEvent(ProgressEvent.Report, $"Executing Script '{command}'..."); if (OSVersion.Platform == PlatformID.Unix) { processInfo.Arguments = commandFilePath; } else { processInfo.Arguments = @"/C " + commandFilePath; } processInfo.WorkingDirectory = Path.GetDirectoryName(commandFilePath); List <string> output = new List <string>(), error = new List <string>(); var proc = new Process(); proc.StartInfo = processInfo; DateTime lastUpdate = DateTime.Now; proc.OutputDataReceived += new DataReceivedEventHandler((sender, e) => { lastUpdate = DateTime.Now; output.Add(e.Data); }); proc.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => { lastUpdate = DateTime.Now; error.Add(e.Data); }); proc.Start(); proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); while (!proc.HasExited) { if (lastUpdate.AddMinutes(3) < DateTime.Now) { proc.Kill(); } Thread.Sleep(1000); } Log($"Job finished with exit code: {proc.ExitCode}"); return(proc.ExitCode); }
/// <summary> /// Adds the item. /// </summary> /// <param name="menuText">The text.</param> /// <param name="helpText">The help.</param> /// <param name="contextCommand">The context command.</param> public void AddItem(string menuText, string helpText, ContextCommand contextCommand) { ////Contract.Requires(helpText != null); ////Contract.Requires(contextCommand != null); var menuItemInfo = new MenuItemInfo(); menuItemInfo.InitializeSize(); menuItemInfo.Id = menuHost.GetCommandId(); menuItemInfo.Text = menuText; InsertMenuItem(ref menuItemInfo, helpText, contextCommand, null); }
static void ServiceMain() { Log("Service is starting..."); while (!quit) { if (!started || actualCommand == ContextCommand.NONE) { Log("Wait..."); commandReceivedEvent.Wait(); commandReceivedEvent.Reset(); Log("Unwait..."); continue; } else if (actualCommand != ContextCommand.NONE) { Log("Main loop"); if (tries > 0 && tries < 5) { Thread.Sleep(1000); } else if (tries >= 5) { actualCommand = ContextCommand.NONE; // failed } else { Log("New context: " + context); } SendProgressEvent(ProgressEvent.Begin, context); // Download files before install command is executed var ctx = contexts.Find(c => c.ID == context); if (actualCommand == ContextCommand.Install && (ctx == null || !ctx.Downloaded)) { ExecuteScriptFileForCommand(ContextCommand.Download).Wait(); actualCommand = ContextCommand.Install; SendProgressEvent(ProgressEvent.Begin, context); } ExecuteScriptFileForCommand(actualCommand).Wait(); } } Log("Service stopped!"); }
/// <summary> /// Adds the item. /// </summary> /// <param name="customMenuHandler">The custom menu handler.</param> /// <param name="helpText">The help.</param> /// <param name="contextCommand">The context command.</param> public void AddItem(CustomMenuHandler customMenuHandler, string helpText, ContextCommand contextCommand) { Contract.Requires(customMenuHandler != null); Contract.Requires(helpText != null); Contract.Requires(contextCommand != null); var menuItemInfo = new MenuItemInfo(); menuItemInfo.InitializeSize(); menuItemInfo.Id = menuHost.GetCommandId(); customMenuHandler.InitializeItemInfo(ref menuItemInfo); InsertMenuItem(ref menuItemInfo, helpText, contextCommand, customMenuHandler); }
/// <summary> /// Adds the item. /// </summary> /// <param name="customMenuHandler">The custom menu handler.</param> /// <param name="helpText">The help.</param> /// <param name="contextCommand">The context command.</param> public void AddItem(CustomMenuHandler customMenuHandler, string helpText, ContextCommand contextCommand) { if (customMenuHandler == null) { throw new ArgumentNullException(nameof(customMenuHandler)); } ////Contract.Requires(helpText != null); ////Contract.Requires(contextCommand != null); var menuItemInfo = new MenuItemInfo(); menuItemInfo.InitializeSize(); menuItemInfo.Id = menuHost.GetCommandId(); customMenuHandler.InitializeItemInfo(ref menuItemInfo); InsertMenuItem(ref menuItemInfo, helpText, contextCommand, customMenuHandler); }
/// <summary> /// Called when a parent has just been assigned to this behavior. (Refer to this.Parent) /// </summary> public override void OnAddBehavior() { var parent = this.Parent; if (parent != null) { // When adding this behavior to a Thing, register relevant events so we can cancel // the opening of our parent Thing while our parent Thing is "locked". parent.Eventing.MiscellaneousRequest += this.RequestHandler; // Register the "lock" and "unlock" context commands to be available to siblings of our parent, // and to the lockable/unlockable thing's children (IE in case it can be entered itself). var contextAvailability = ContextAvailability.ToSiblings | ContextAvailability.ToChildren; var lockContextCommand = new ContextCommand(this.commands, LockString, contextAvailability, SecurityRole.all); var unlockContextCommand = new ContextCommand(this.commands, UnlockString, contextAvailability, SecurityRole.all); parent.Commands.Add(LockString, lockContextCommand); parent.Commands.Add(UnlockString, unlockContextCommand); } base.OnAddBehavior(); }
/// <summary>Called when a parent has just been assigned to this behavior. (Refer to Parent)</summary> protected override void OnAddBehavior() { var parent = Parent; if (parent != null) { // When adding this behavior to a Thing, register relevant events so we can cancel // the opening of our parent Thing while our parent Thing is "locked". parent.Eventing.MiscellaneousRequest += RequestHandler; // Register the "lock" and "unlock" context commands to be available to siblings of our parent, // and to the lockable/unlockable thing's children (IE in case it can be entered itself). var contextAvailability = ContextAvailability.ToSiblings | ContextAvailability.ToChildren; var lockContextCommand = new ContextCommand(commands, LockString, contextAvailability, SecurityRole.all); var unlockContextCommand = new ContextCommand(commands, UnlockString, contextAvailability, SecurityRole.all); Debug.Assert(!parent.Commands.ContainsKey(LockString), "The Thing this LocksUnlocksBehavior attached to already had a Lock command."); Debug.Assert(!parent.Commands.ContainsKey(UnlockString), "The Thing this LocksUnlocksBehavior attached to already had an Unlock command."); parent.Commands.Add(LockString, lockContextCommand); parent.Commands.Add(UnlockString, unlockContextCommand); } base.OnAddBehavior(); }
internal static void IPCMessageReceived(string message) { Log("Message Received: " + message); var containsAdditionalInfos = message.IndexOf(CMD_SEPARATOR); string command = string.Empty; string addInfo = string.Empty; if (containsAdditionalInfos != -1) { string[] messageParts = message.Split(CMD_SEPARATOR); if (messageParts.Length != 2) { return; } command = messageParts[0]; addInfo = messageParts[1]; } else { command = message; } switch (command) { case "start": started = true; break; case "stop": started = false; break; case "quit": quit = true; break; case "verbose": verbose = !verbose; Extensions.VERBOSE = verbose; Log("Verbose Mode: " + verbose, ignoreVerbose: true); return; case "resetcontext": config[nameof(activeContext)] = activeContext = context = "NONE"; return; case "clean": Log("Cleaning all repos..."); foreach (var file in Directory.EnumerateFiles(recipeRepository, "*.*", SearchOption.AllDirectories)) { File.Delete(file); Log($"File deleted: {file}"); } contexts.ForEach(ctx => SetContextState(ContextCommand.NONE, ctx.ID)); Log("Cleanup successful!"); return; case "getcontext": tcpClient.SendChannelMessage("active-context", activeContext); return; case "getcontextdata": tcpClient.SendChannelMessage("all-context-data", Newtonsoft.Json.JsonConvert.SerializeObject(contexts.ToArray())); return; case "acontext": actualCommand = ContextCommand.Switch; context = addInfo; break; case "ucontext": actualCommand = ContextCommand.Unswitch; context = addInfo; break; case "dlcontext": actualCommand = ContextCommand.Download; context = addInfo; break; case "icontext": actualCommand = ContextCommand.Install; context = addInfo; break; case "rcontext": actualCommand = ContextCommand.Remove; context = addInfo; break; case "chhost": config[nameof(host)] = host = addInfo; UpdateClient(); return; case "chproto": config[nameof(protocol)] = protocol = addInfo; UpdateClient(); return; default: Log($"IPC => Unknow Message: {message}"); return; } if (command.IndexOf("context") != -1 && command.IndexOf("context") < 2) { tries = 0; } commandReceivedEvent.Set(); }
internal static async Task ExecuteScriptFileForCommand(ContextCommand command, bool automatic = false) { if (command == ContextCommand.Switch && activeContext != "NONE" && !string.IsNullOrWhiteSpace(activeContext) && activeContext != context) { await ExecuteScriptFileForCommand(ContextCommand.Unswitch, true); } var cmdName = Context.Commands[(int)command]; var usedContext = automatic ? activeContext : context; string commandFilePath = Path.Combine(recipeRepository, usedContext, $"{cmdName}." + (OSVersion.Platform == PlatformID.Win32NT ? "bat" : "sh")); var contextRepo = Path.Combine(recipeRepository, usedContext); if (!Directory.Exists(contextRepo)) { Directory.CreateDirectory(contextRepo); } restRequest = new RestRequest(resourcePath, Method.GET); restRequest.AddUrlSegment("lec", usedContext); restRequest.AddUrlSegment("cmd", cmdName); var targetURI = $"{protocol}://{host}{resourcePath.Replace("{lec}", usedContext).Replace("{cmd}", cmdName)}"; Log($"GET Request to {targetURI}"); SendProgressEvent(ProgressEvent.Report, $"Requesting {targetURI}..."); try { var res = await restClient.ExecuteAsync(restRequest); var script = res.Content; Log($"GET Response => {res.StatusCode} ({(int)res.StatusCode})"); if ((int)res.StatusCode >= 400) { tries++; return; } // Signature verification if (enableSignatureService && !VerifySignature(res)) { tries = 5; Log($"Script file are not properly signed by the server!"); return; } // Check if the content matches the updated script file // Content != FileContent => WriteScriptFile if (!File.Exists(commandFilePath) || !File.ReadAllText(commandFilePath).Contains(script)) { WriteScriptFile(commandFilePath, script); Log($"File written to: {commandFilePath}"); } int exitcode = ExecuteScript(command, commandFilePath); if (exitcode == 0) { SetContextState(command, usedContext); } actualCommand = ContextCommand.NONE; tries = 0; } catch (Exception e) { Log("Error during script: " + e.Message); tries++; } finally { if (!automatic && !(tries > 0 && tries < 5)) { SendProgressEvent(ProgressEvent.End, activeContext); } } }
protected void AddCommand( KeyMap.GameInput input, Action<float> callback, ContextCommand.TriggerType triggerType = ContextCommand.TriggerType.Down ) { commands_.Add(new ContextCommand( keyMap_, input, callback, triggerType ) ); }