From 9a31bbade23ac698f1216a5c3c2656ce22f92d56 Mon Sep 17 00:00:00 2001 From: Allen Wolf <63997543+aaw3@users.noreply.github.com> Date: Wed, 10 Jan 2024 00:16:59 -0600 Subject: [PATCH] Add project --- src/App.config | 6 + src/AudioPlaybackEngine.cs | 111 +++ src/CachedSound.cs | 34 + src/CachedSoundSampleProvider.cs | 30 + src/Form1.Designer.cs | 198 +++++ src/Form1.cs | 1002 ++++++++++++++++++++++++++ src/Form1.resx | 120 +++ src/Form2.Designer.cs | 68 ++ src/Form2.cs | 319 ++++++++ src/Form2.resx | 120 +++ src/InputBox.Designer.cs | 112 +++ src/InputBox.cs | 113 +++ src/InputBox.resx | 120 +++ src/KeyboardHook.cs | 335 +++++++++ src/Program.cs | 22 + src/Properties/AssemblyInfo.cs | 36 + src/Properties/Resources.Designer.cs | 71 ++ src/Properties/Resources.resx | 117 +++ src/Properties/Settings.Designer.cs | 30 + src/Properties/Settings.settings | 7 + src/SpeechBot.csproj | 121 ++++ src/SpeechBot.sln | 25 + src/packages.config | 4 + 23 files changed, 3121 insertions(+) create mode 100755 src/App.config create mode 100755 src/AudioPlaybackEngine.cs create mode 100755 src/CachedSound.cs create mode 100755 src/CachedSoundSampleProvider.cs create mode 100755 src/Form1.Designer.cs create mode 100755 src/Form1.cs create mode 100755 src/Form1.resx create mode 100755 src/Form2.Designer.cs create mode 100755 src/Form2.cs create mode 100755 src/Form2.resx create mode 100755 src/InputBox.Designer.cs create mode 100755 src/InputBox.cs create mode 100755 src/InputBox.resx create mode 100755 src/KeyboardHook.cs create mode 100755 src/Program.cs create mode 100755 src/Properties/AssemblyInfo.cs create mode 100755 src/Properties/Resources.Designer.cs create mode 100755 src/Properties/Resources.resx create mode 100755 src/Properties/Settings.Designer.cs create mode 100755 src/Properties/Settings.settings create mode 100755 src/SpeechBot.csproj create mode 100755 src/SpeechBot.sln create mode 100755 src/packages.config diff --git a/src/App.config b/src/App.config new file mode 100755 index 0000000..5754728 --- /dev/null +++ b/src/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/AudioPlaybackEngine.cs b/src/AudioPlaybackEngine.cs new file mode 100755 index 0000000..7269ebc --- /dev/null +++ b/src/AudioPlaybackEngine.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using NAudio.Wave; +using NAudio.Wave.SampleProviders; +using System.Linq; +using System.Diagnostics; + +namespace SpeechBot +{ + class AudioPlaybackEngine : IDisposable + { + private IWavePlayer outputDevice; + private readonly MixingSampleProvider mixer; + private IDictionary cachedSounds = new Dictionary(); + + public AudioPlaybackEngine(int sampleRate = 44100, int channelCount = 2) + { + mixer = new MixingSampleProvider(WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channelCount)); + mixer.ReadFully = true; + mixer.MixerInputEnded += OnMixerInputEnded; + } + + public event EventHandler AllInputEnded; + + private void OnMixerInputEnded(object sender, SampleProviderEventArgs e) + { + // check if there are any inputs left + // OnMixerInputEnded gets invoked before the corresponding source is removed from the List so there should be exactly one source left + if (mixer.MixerInputs.Count() == 1) + { + AllInputEnded?.Invoke(this, EventArgs.Empty); + } + } + + public void Init(int deviceNumber) + { + + if (outputDevice != null) outputDevice.Dispose(); + + var output = new WaveOutEvent(); + output.DeviceNumber = deviceNumber; + output.Init(mixer); + output.Play(); + + outputDevice = output; + } + + public void PlaySound(string fileName, float volume = 1) + { + try + { + var input = new AudioFileReader(fileName); //System.FormatException (mp3) + CachedSound cachedSound = null; + + if (!cachedSounds.TryGetValue(fileName, out cachedSound)) + { + cachedSound = new CachedSound(fileName); //System.FormatException (mp3) + cachedSounds.Add(fileName, cachedSound); + } + + var resultingSampleProvider = new VolumeSampleProvider(new CachedSoundSampleProvider(cachedSound)); + + resultingSampleProvider.Volume = volume; + + AddMixerInput(resultingSampleProvider); + + + input.Dispose(); //see if this fixes formaterrors + } + catch (System.FormatException ex) + { + Debug.WriteLine(ex.GetType() + " : " + ex.Message); + } + } + + public void StopAllSounds() + { + mixer.RemoveAllMixerInputs(); + } + + private ISampleProvider ConvertToRightChannelCount(ISampleProvider input) + { + if (input.WaveFormat.Channels == mixer.WaveFormat.Channels) + { + return input; + } + + if (input.WaveFormat.Channels == 1 && mixer.WaveFormat.Channels == 2) + { + return new MonoToStereoSampleProvider(input); + } + + throw new NotImplementedException("Not yet implemented this channel count conversion"); + } + + private void AddMixerInput(ISampleProvider input) + { + var resampled = new WdlResamplingSampleProvider(input, mixer.WaveFormat.SampleRate); + mixer.AddMixerInput(ConvertToRightChannelCount(resampled)); + } + + public void Dispose() + { + if (outputDevice != null) + { + outputDevice.Dispose(); + outputDevice = null; + } + } + } +} diff --git a/src/CachedSound.cs b/src/CachedSound.cs new file mode 100755 index 0000000..b1a5f89 --- /dev/null +++ b/src/CachedSound.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Linq; +using NAudio.Wave; + +// https://mark-dot-net.blogspot.de/2014/02/fire-and-forget-audio-playback-with.html +// Mark Heath 2014 + +namespace SpeechBot +{ + class CachedSound + { + public float[] AudioData { get; private set; } + public WaveFormat WaveFormat { get; private set; } + + public CachedSound(string audioFileName) + { + using (var audioFileReader = new AudioFileReader(audioFileName)) + { + // TODO: could add resampling in here if required + WaveFormat = audioFileReader.WaveFormat; + var wholeFile = new List((int)(audioFileReader.Length / 4)); + var readBuffer = new float[audioFileReader.WaveFormat.SampleRate * audioFileReader.WaveFormat.Channels]; + int samplesRead; + + while ((samplesRead = audioFileReader.Read(readBuffer, 0, readBuffer.Length)) > 0) + { + wholeFile.AddRange(readBuffer.Take(samplesRead)); + } + + AudioData = wholeFile.ToArray(); + } + } + } +} diff --git a/src/CachedSoundSampleProvider.cs b/src/CachedSoundSampleProvider.cs new file mode 100755 index 0000000..bb626fd --- /dev/null +++ b/src/CachedSoundSampleProvider.cs @@ -0,0 +1,30 @@ +using System; +using NAudio.Wave; + +namespace SpeechBot +{ + class CachedSoundSampleProvider : ISampleProvider + { + private readonly CachedSound cachedSound; + private long position; + + public CachedSoundSampleProvider(CachedSound cachedSound) + { + this.cachedSound = cachedSound; + } + + public int Read(float[] buffer, int offset, int count) + { + var availableSamples = cachedSound.AudioData.Length - position; + var samplesToCopy = Math.Min(availableSamples, count); + + Array.Copy(cachedSound.AudioData, position, buffer, offset, samplesToCopy); + + position += samplesToCopy; + + return (int)samplesToCopy; + } + + public WaveFormat WaveFormat { get { return cachedSound.WaveFormat; } } + } +} diff --git a/src/Form1.Designer.cs b/src/Form1.Designer.cs new file mode 100755 index 0000000..9debb06 --- /dev/null +++ b/src/Form1.Designer.cs @@ -0,0 +1,198 @@ +namespace SpeechBot +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.HelpButton = new System.Windows.Forms.Button(); + this.CommandNameTBox = new System.Windows.Forms.TextBox(); + this.CommandDataTBox = new System.Windows.Forms.TextBox(); + this.CategoriesCoBox = new System.Windows.Forms.ComboBox(); + this.CreateCommand = new System.Windows.Forms.Button(); + this.ReloadButton = new System.Windows.Forms.Button(); + this.ReloadCreateChBox = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.ShowChart = new System.Windows.Forms.Button(); + this.SaveButton = new System.Windows.Forms.Button(); + this.SaveTimeLabel = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // HelpButton + // + this.HelpButton.Location = new System.Drawing.Point(2, 2); + this.HelpButton.Name = "HelpButton"; + this.HelpButton.Size = new System.Drawing.Size(104, 34); + this.HelpButton.TabIndex = 0; + this.HelpButton.Text = "Show Commands"; + this.HelpButton.UseVisualStyleBackColor = true; + this.HelpButton.Click += new System.EventHandler(this.HelpButton_Click); + // + // CommandNameTBox + // + this.CommandNameTBox.Location = new System.Drawing.Point(42, 123); + this.CommandNameTBox.Name = "CommandNameTBox"; + this.CommandNameTBox.Size = new System.Drawing.Size(326, 20); + this.CommandNameTBox.TabIndex = 1; + // + // CommandDataTBox + // + this.CommandDataTBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CommandDataTBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.CommandDataTBox.Location = new System.Drawing.Point(374, 123); + this.CommandDataTBox.Multiline = true; + this.CommandDataTBox.Name = "CommandDataTBox"; + this.CommandDataTBox.Size = new System.Drawing.Size(434, 270); + this.CommandDataTBox.TabIndex = 2; + // + // CategoriesCoBox + // + this.CategoriesCoBox.FormattingEnabled = true; + this.CategoriesCoBox.Location = new System.Drawing.Point(42, 96); + this.CategoriesCoBox.Name = "CategoriesCoBox"; + this.CategoriesCoBox.Size = new System.Drawing.Size(170, 21); + this.CategoriesCoBox.TabIndex = 3; + this.CategoriesCoBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboBox1_DrawItem); + this.CategoriesCoBox.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + this.CategoriesCoBox.DropDownClosed += new System.EventHandler(this.comboBox1_DropDownClosed); + // + // CreateCommand + // + this.CreateCommand.Location = new System.Drawing.Point(279, 165); + this.CreateCommand.Name = "CreateCommand"; + this.CreateCommand.Size = new System.Drawing.Size(89, 42); + this.CreateCommand.TabIndex = 4; + this.CreateCommand.Text = "Create Command"; + this.CreateCommand.UseVisualStyleBackColor = true; + this.CreateCommand.Click += new System.EventHandler(this.CreateCommand_Click); + // + // ReloadButton + // + this.ReloadButton.Location = new System.Drawing.Point(279, 237); + this.ReloadButton.Name = "ReloadButton"; + this.ReloadButton.Size = new System.Drawing.Size(89, 42); + this.ReloadButton.TabIndex = 5; + this.ReloadButton.Text = "Reload Dictionary"; + this.ReloadButton.UseVisualStyleBackColor = true; + this.ReloadButton.Click += new System.EventHandler(this.Reload_Button); + // + // ReloadCreateChBox + // + this.ReloadCreateChBox.AutoSize = true; + this.ReloadCreateChBox.Location = new System.Drawing.Point(162, 174); + this.ReloadCreateChBox.Name = "ReloadCreateChBox"; + this.ReloadCreateChBox.Size = new System.Drawing.Size(111, 17); + this.ReloadCreateChBox.TabIndex = 6; + this.ReloadCreateChBox.Text = "Reload On Create"; + this.ReloadCreateChBox.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label1.Location = new System.Drawing.Point(374, 81); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(434, 36); + this.label1.TabIndex = 7; + this.label1.Text = "You can access Form class called \'form\' to access the SpeechBot Application\'s int" + + "ernals."; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.label1.Visible = false; + // + // ShowChart + // + this.ShowChart.Location = new System.Drawing.Point(112, 2); + this.ShowChart.Name = "ShowChart"; + this.ShowChart.Size = new System.Drawing.Size(104, 34); + this.ShowChart.TabIndex = 8; + this.ShowChart.Text = "Show Chart"; + this.ShowChart.UseVisualStyleBackColor = true; + this.ShowChart.Click += new System.EventHandler(this.ShowChart_Click); + // + // SaveButton + // + this.SaveButton.Location = new System.Drawing.Point(222, 2); + this.SaveButton.Name = "SaveButton"; + this.SaveButton.Size = new System.Drawing.Size(104, 34); + this.SaveButton.TabIndex = 9; + this.SaveButton.Text = "Save Commands"; + this.SaveButton.UseVisualStyleBackColor = true; + this.SaveButton.Click += new System.EventHandler(this.SaveButton_Click); + // + // SaveTimeLabel + // + this.SaveTimeLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.SaveTimeLabel.Location = new System.Drawing.Point(332, 5); + this.SaveTimeLabel.Name = "SaveTimeLabel"; + this.SaveTimeLabel.Size = new System.Drawing.Size(135, 28); + this.SaveTimeLabel.TabIndex = 10; + this.SaveTimeLabel.Text = "Last Save:\r\nNone"; + this.SaveTimeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(844, 450); + this.Controls.Add(this.SaveTimeLabel); + this.Controls.Add(this.SaveButton); + this.Controls.Add(this.ShowChart); + this.Controls.Add(this.label1); + this.Controls.Add(this.ReloadCreateChBox); + this.Controls.Add(this.ReloadButton); + this.Controls.Add(this.CreateCommand); + this.Controls.Add(this.CategoriesCoBox); + this.Controls.Add(this.CommandDataTBox); + this.Controls.Add(this.CommandNameTBox); + this.Controls.Add(this.HelpButton); + this.Name = "Form1"; + this.Text = "SpeechBot"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); + this.Load += new System.EventHandler(this.Form1_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button HelpButton; + private System.Windows.Forms.TextBox CommandNameTBox; + private System.Windows.Forms.ComboBox CategoriesCoBox; + private System.Windows.Forms.Button ReloadButton; + private System.Windows.Forms.CheckBox ReloadCreateChBox; + private System.Windows.Forms.Button CreateCommand; + private System.Windows.Forms.TextBox CommandDataTBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button ShowChart; + private System.Windows.Forms.Button SaveButton; + public System.Windows.Forms.Label SaveTimeLabel; + } +} + diff --git a/src/Form1.cs b/src/Form1.cs new file mode 100755 index 0000000..364c048 --- /dev/null +++ b/src/Form1.cs @@ -0,0 +1,1002 @@ +using Microsoft.CSharp; +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Media; +using System.Speech.Recognition; +using System.Speech.Synthesis; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml; +using System.Xml.Serialization; +using WMPLib; +using Hook = KeyboardHooker.KeyboardHook; + +namespace SpeechBot +{ + public partial class Form1 : Form + { + + public Hook listener = new Hook(); + + public SpeechSynthesizer synth = new SpeechSynthesizer(); + public SpeechRecognitionEngine rec = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("en-US")); + + public string beginListen, endListen, repeat; + public string[] ActivationKeywords; + + public string[] categories; + + + public List steamGameList; + public List steamGameToken; + + + public List appList; + public List appToken; + + public string[] arguments; + + + public List questionList; + public List questionToken; + + public List commandList; + public List commandToken; + + public List scriptList; + public List scriptToken; + public Dictionary codeDict = new Dictionary(); + + public List[] categoryList; + + public Dictionary steamGameDict = new Dictionary(); + public Dictionary appDict = new Dictionary(); + public Dictionary questionDict = new Dictionary(); + public Dictionary commandDict = new Dictionary(); + + public Dictionary scriptDict = new Dictionary(); + + public int steamStartIndex, appStartIndex; + + public dynamic[] dictArray; + + + public Grammar currentCommands; + + private bool l; + public bool listening + { + get { return l; } + set { Debug.WriteLine("setting to: " + value); l = value; } + } + + public string saveLocation = Environment.ExpandEnvironmentVariables(@"%Public%\Documents\SpeechBot\Data\Save.dat"); + + public Form1() + { + InitializeComponent(); + } + + public WindowsMediaPlayer player = new WindowsMediaPlayer(); + + public string SoundsLocation = Environment.ExpandEnvironmentVariables(@"%Public%\Documents\SpeechBot\Sounds\"); + + Form2 form2; + + SaveData sd; + + AudioPlaybackEngine ape1; + AudioPlaybackEngine ape2; + public void Form1_Load(object sender, EventArgs e) + { + InputBox.Instance = new InputBox(); + InputBox.Instance.StealthHide(); + InputBox.Instance.Visible = true; + InputBox.Instance.Visible = false; + InputBox.Instance.Init(); + + this.MinimumSize = new Size(860, 375); + + form2 = new Form2(this); + form2.Show(); + + + + + beginListen = "start"; endListen = "end"; repeat = "again"; + + ActivationKeywords = new string[] { beginListen, endListen, repeat }; + + categories = new string[] { "open steam game", "open app", "question", "command", "script" }; + + steamGameList = new List { "rainbow six siege", "counter strike" }; + steamGameToken = new List { 359550, 730 }; + + appList = new List { "explorer", "notepad", "command prompt", "chrome", "chrome incognito", "brave", "brave incognito", "computer lock", "widget embed" }; + appToken = new List { "explorer.exe", "notepad.exe", "cmd.exe", @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe", @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --incognito", @"C:\Program Files (x86)\BraveSoftware\Brave-Browser\Application\brave.exe", @"C:\Program Files (x86)\BraveSoftware\Brave-Browser\Application\brave.exe --incognito", @"F:\Program Files\VS Project Files\ComputerLock\bin\Debug\ComputerLock.exe", @"F:\Program Files\VS Project Files\WidgetEmbed\bin\x64\Debug\WidgetEmbed.exe" }; + + + arguments = new string[] { "--incognito" }; + + + questionList = new List { "enter a question here" }; + questionToken = new List { new Action(() => { }), new Action(() => { }) }; + + commandList = new List { "fix my display", "time check", "play me a sound" }; + commandToken = new List { new Action(() => { FixDisplay(); }), new Action(() => { TellTime(); }), new Action(() => { PlayASound(); }) }; + + scriptList = new List(); + scriptToken = new List(); + + categoryList = new List[] { steamGameList, appList, questionList, commandList, scriptList }; + dictArray = new dynamic[] { steamGameDict, appDict, questionDict, commandDict, scriptDict }; + + + steamStartIndex = steamGameList.Count; + appStartIndex = appList.Count; + + + this.CategoriesCoBox.DrawMode = DrawMode.OwnerDrawFixed; + CategoriesCoBox.DropDownStyle = ComboBoxStyle.DropDownList; + for (int i = 0; i < categories.Length; i++) + { + CategoriesCoBox.Items.Add(categories[i]); + } + + string appDir = Environment.ExpandEnvironmentVariables(@"%Public%\Documents\SpeechBot"); + + if (!Directory.Exists(appDir)) + { + Directory.CreateDirectory(appDir); + + if (!Directory.Exists(appDir + @"\Sounds")) + Directory.CreateDirectory(appDir + @"\Sounds"); + + if (!Directory.Exists(appDir + @"\Data")) + Directory.CreateDirectory(appDir + @"\Data"); + + } + + if (!File.Exists(saveLocation)) + { + File.Create(saveLocation); + } + else + { + sd = Extensions.Deserialize(saveLocation); + for (int i = 0; i < sd.SteamGameList.Count; i++) + { + steamGameList.Add(sd.SteamGameList[i]); + steamGameToken.Add(sd.SteamGameToken[i]); + + form2.dataGridView1.Rows.Add(Category.SteamGame, sd.SteamGameList[i], sd.SteamGameToken[i], "■", "■"); + } + + for (int i = 0; i < sd.AppList.Count; i++) + { + appList.Add(sd.AppList[i]); + appToken.Add(sd.AppToken[i]); + + form2.dataGridView1.Rows.Add(Category.App, sd.AppList[i], sd.AppToken[i], "■", "■"); + } + + for (int i = 0; i < sd.ScriptList.Count; i++) + { + scriptList.Add(sd.ScriptList[i]); + codeDict.Add(sd.ScriptList[i], sd.CodeToken[i]); + + scriptDict.Add(sd.ScriptList[i], null); + + form2.dataGridView1.Rows.Add(Category.Script, sd.ScriptList[i], sd.CodeToken[i], "■", "■"); + } + } + + listener.Install(); + listener.KeyDown += KeyDown; + listener.KeyUp += KeyUp; + + + + + synth.SetOutputToDefaultAudioDevice(); + + + for (int i = 0; i < steamGameList.Count; i++) + { + steamGameDict.Add(steamGameList[i], steamGameToken[i]); + } + + for (int i = 0; i < appList.Count; i++) + { + appDict.Add(appList[i], appToken[i]); + } + + for (int i = 0; i < questionList.Count; i++) + { + questionDict.Add(questionList[i], questionToken[i]); + } + + for (int i = 0; i < commandList.Count; i++) + { + commandDict.Add(commandList[i], commandToken[i]); + } + + DictationGrammar dg = new DictationGrammar("grammar:dictation#pronunciation"); + dg.Name = "Random"; + + + LoadCommands(); + + rec.LoadGrammar(dg); + rec.MaxAlternates = 1; + + rec.SpeechRecognized += rec_SpeechRecognized; + rec.SetInputToDefaultAudioDevice(); + + } + + public void LoadCommands() + { + Choices gb = new Choices(new string[] { beginListen, endListen, repeat }); + for (int i = 0; i < categories.Length; i++) + { + for (int j = 0; j < categoryList[i].Count; j++) + { + gb.Add(categories[i] + " " + categoryList[i][j]); + + } + } + + currentCommands = new Grammar(gb); + + currentCommands.Name = "commands"; + + rec.LoadGrammar(currentCommands); + + preparedHelp = false; + } + + public void ReloadCommands() + { + rec.UnloadGrammar(currentCommands); + + LoadCommands(); + } + + + public static Random r = new Random(); + public void FixDisplay() + { + Process.Start(@"F:\program Files\vs Project Files\displaySettingsMenu\bin\Debug\DisplaySettingsMenu.exe", "--FixDisplay"); + } + + public void TellTime() + { + synth.SpeakAsync("The time is currently " + DateTime.Now.ToString("dddd, MMMM dd, hh:mm tt")); + } + + public void PlaySoundsThroughMic(params string[][] sounds) + { + if (ape1 == null && ape2 == null) + { + ape1 = new AudioPlaybackEngine(); + ape2 = new AudioPlaybackEngine(); + + InitAPE(ape1, 1, 1); + InitAPE(ape2, 0, 2); + } + else + { + ape1.StopAllSounds(); + ape2.StopAllSounds(); + } + + string sound = sounds[r.Next(0, sounds.Length)].GetRandomValue(); + if (!File.Exists(sound)) + { + sound = SoundsLocation + sound; + } + + ape1.PlaySound(sound); + ape2.PlaySound(sound); + + } + + public void PlaySoundThroughMic(string sound) + { + if (ape1 == null && ape2 == null) + { + ape1 = new AudioPlaybackEngine(); + ape2 = new AudioPlaybackEngine(); + + InitAPE(ape1, 1, 1); + InitAPE(ape2, 0, 2); + } + else + { + ape1.StopAllSounds(); + ape2.StopAllSounds(); + } + + ape1.PlaySound(sound); + ape2.PlaySound(sound); + } + + private void InitAPE(AudioPlaybackEngine ape, int PlaybackDevice, int PlaybackDeviceNumber) + { + try + { + ape.Init(PlaybackDevice); + } + catch (NAudio.MmException ex) + { + SystemSounds.Beep.Play(); + + string msg = ex.ToString(); + + if (msg.Contains("AlreadyAllocated calling waveOutOpen")) + { + msg = "Failed to open device. Already in exclusive use by another application? \n\n" + msg; + } + + MessageBox.Show("Playback " + PlaybackDeviceNumber + msg); + } + } + + public bool VoiceKeyDown; + public bool RepeatKeyDown; + public bool TryingToRecognize; + Hook.VKeys RequiredKey = Hook.VKeys.RSHIFT; + Hook.VKeys RepeatKey = Hook.VKeys.PRIOR; + private void KeyDown(Hook.VKeys key) + { + + if (key == RequiredKey && !VoiceKeyDown) + { + rec.RecognizeAsync(RecognizeMode.Multiple); + TryingToRecognize = true; + VoiceKeyDown = true; + } + + if (key == RepeatKey && !RepeatKeyDown) + { + if (data == null) + return; + + RunCommand(data); + return; + } + } + private void KeyUp(Hook.VKeys key) + { + if (key == Hook.VKeys.APPS) + { + Debug.WriteLine("KeyIsDown: " + VoiceKeyDown); + Debug.WriteLine("TryingToRecognize: " + TryingToRecognize); + } + + if (key == RequiredKey) + { + rec.RecognizeAsyncStop(); + VoiceKeyDown = false; + } + + if (key == RepeatKey) + { + RepeatKeyDown = false; + } + } + + void Beep(int freq, int ms) + { + Thread t = new Thread(() => + { + Console.Beep(freq, ms); + }); + t.Start(); + } + + void rec_SpeechRecognized(object sender, SpeechRecognizedEventArgs e) + { + TryingToRecognize = false; + + if (e.Result.Grammar.Name == "Random") + return; + + + + Debug.WriteLine("Confidence: " + e.Result.Confidence); + + Debug.WriteLine("Recognized Text: " + e.Result.Text); + string text = e.Result.Text.ToLower(); + + if (text == beginListen) + { + if (listening) + return; + + listening = true; + Beep(1750, 250); + return; + } + if (text == endListen) + { + if (!listening) + return; + + listening = false; + Beep(1000, 250); + return; + } + + if (listening) + { + CheckCommand(text); + } + } + + public enum Category + { + SteamGame, + App, + Question, + Command, + Script + } + + Query QueryData = new Query(); + Query GetData(string text) + { + for (int i = 0; i < categories.Length; i++) + if (text.Length >= categories[i].Length) + if (text.Substring(0, categories[i].Length) == categories[i]) + QueryData.Category = (Category)i; + + QueryData.Data = text.Substring(categories[(int)QueryData.Category].Length + 1); + + return QueryData; + } + + Query data; + void CheckCommand(string text) + { + if (text == repeat) + { + if (data == null) + return; + + RunCommand(data); + return; + } + + data = GetData(text); + + RunCommand(data); + } + + private bool HelpShown; + private bool preparedHelp; + private string helpInfo; + private void HelpButton_Click(object sender, EventArgs e) + { + if (!preparedHelp) + helpInfo = PrepareHelp(); + + if (HelpShown) + return; + + HelpShown = true; + + Task.Run(() => + { + MessageBox.Show(helpInfo, "Commands", MessageBoxButtons.OK, MessageBoxIcon.Information); + HelpShown = false; + }); + } + + private string PrepareHelp() + { + preparedHelp = true; + string test = ""; + + test += "Activation Keywords:\n\n"; + + for (int i = 0; i < ActivationKeywords.Length; i++) + test += ActivationKeywords[i] + "\n"; + + test += "\n\n\n"; + + + for (int i = 0; i < categories.Length; i++) + { + test += categories[i] + ":\n\n"; + for (int j = 0; j < categoryList[i].Count; j++) + { + test += categoryList[i][j] + "\n"; + } + + if (!(categories.Length - 1 == i)) + test += "\n\n\n"; + } + return test; + } + + + string defaultScriptText = +@" + + + +"; + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + if (CategoriesCoBox.SelectedIndex == 2 || CategoriesCoBox.SelectedIndex == 3) + { + CategoriesCoBox.SelectedIndex = -1; + return; + } + + if (!(CategoriesCoBox.SelectedIndex == 4)) + { + CommandDataTBox.Text = ""; + label1.Hide(); + } + else + { + CommandDataTBox.Text = defaultScriptText; + label1.Show(); + } + + } + + Font FontEnabled = new Font("Aerial", 10, FontStyle.Regular); + Font FontDisabled = new Font("Aerial", 10, FontStyle.Strikeout); + private void comboBox1_DrawItem(object sender, DrawItemEventArgs e) + { + if (e.Index == 2 || e.Index == 3) + { + e.Graphics.DrawString(CategoriesCoBox.Items[e.Index].ToString(), FontDisabled, Brushes.Red, e.Bounds); + } + else + { + if (e.Index == -1) + return; + + e.DrawBackground(); + e.Graphics.DrawString(CategoriesCoBox.Items[e.Index].ToString(), FontEnabled, Brushes.Black, e.Bounds); + e.DrawFocusRectangle(); + } + } + + private void comboBox1_DropDownClosed(object sender, EventArgs e) + { + HelpButton.Focus(); + } + + int steamIDParse; + string DataText; + string CommandName; + + List DLLs = new List(); + string[] defaultDLLs = new string[] { "mscorlib.dll", "System.Windows.Forms.dll", "System.dll", "System.Drawing.dll", "System.Core.dll", "Microsoft.VisualBasic.dll", "Microsoft.CSharp.dll" }; + string[] UserDLLs; + + string beginningCode = @" + using System.Windows.Forms; + using System.Drawing; + public class Script + { + public void Function(dynamic form) + { +"; + string endingCode = + @"} + }"; + + public string Code; + CSharpCodeProvider csc = new CSharpCodeProvider(); + CompilerParameters parameters; + + string[] ExistsTitles = new string[] { "Steam Game", "Application", "Question", "Command", "Script" }; + private void CreateCommand_Click(object sender, EventArgs e) + { + if (CategoriesCoBox.SelectedIndex < 0 || CategoriesCoBox.SelectedIndex >= CategoriesCoBox.Items.Count) + { + DisplayError("Invalid ComboBox Index"); + return; + } + + CommandName = CommandNameTBox.Text.ToLower().Trim(); + + for (int i = 0; i < dictArray.Length; i++) + { + if (CategoriesCoBox.SelectedIndex == i && dictArray[i].ContainsKey(CommandName)) + { + DisplayError(ExistsTitles[i] + " - Name Already Exists"); + return; + } + } + + if (string.IsNullOrWhiteSpace(CommandName)) + { + DisplayError("Command Name was [Empty]"); + return; + } + + DataText = CommandDataTBox.Text; + switch (CategoriesCoBox.SelectedIndex) + { + + case 0: + DataText = DataText.Replace(" ", "").Replace(Environment.NewLine, ""); + + if (int.TryParse(DataText, out steamIDParse)) + { + steamGameList.Add(CommandName); + steamGameDict.Add(CommandName, steamIDParse); + + string[] keys = steamGameDict.Keys.ToArray(); + int[] values = steamGameDict.Values.ToArray(); + + } + else + { + DisplayError("Text is not an [Integer]"); + return; + } + + break; + + case 1: + if (File.Exists(DataText)) + { + appList.Add(CommandName); + appDict.Add(CommandName, DataText); + } + else + { + DisplayError("Text does not point to a [File Location]"); + return; + } + + break; + + case 2: //not implemented + break; + + case 3: //not implemented + break; + + case 4: + string randomName = CommandName.Replace(" ", "_") + r.Next(10000, 100000); + + CompilerResults results = CompileCode(DataText, "public class " + randomName); + + if (results == null) + return; + + if (!results.Errors.HasErrors) + { + codeDict.Add(CommandName, DataText); + + scriptList.Add(CommandName); + + scriptDict.Add(CommandName, MakeScriptObject(results, randomName)); + } + else + { + var errors = string.Join(Environment.NewLine, + results.Errors.Cast().Select(x => x.ErrorText)); + MessageBox.Show(errors); + return; + } + + break; + + } + if (ReloadCreateChBox.Checked) + ReloadCommands(); + + form2.dataGridView1.Rows.Add((Category)CategoriesCoBox.SelectedIndex, CommandName, DataText, "■", "■"); + } + + /// + /// Compiles Code based on Text Input. - (Make sure to null check as it will return null on error) + /// + /// + /// + public CompilerResults CompileCode(string Data, string replaceText) + { + if (!(Data.Contains("") && Data.Contains("") && Data.Contains("") && Data.Contains(""))) + { + DisplayError("Improper Script Formatting"); + if (MessageBox.Show("Would you like to reset the scripting textbox to the default text?", "Reset Scripting Textbox", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + CommandDataTBox.Text = defaultScriptText; + + return null; + } + + Code = getBetween(Data, "", " blacklistResult = ReturnIfContains(Code.ToLower(), "file.delete", "directory.delete", "del *", "erase *", "rd *", "rmdir *", "rename *", "replace *"); + + if (blacklistResult.Count > 0) + { + string blacklistString = ""; + for (int i = 0; i < blacklistResult.Count; i++) + { + blacklistString += "\r\n\"" + blacklistResult[i] + "\""; + } + + DisplayError("Code contains blacklisted keywords:" + blacklistString); + return null; + } + + UserDLLs = getBetween(Data, "", "").SplitToLines().ToArray(); + + DLLs.Clear(); + DLLs.AddRange(defaultDLLs); + DLLs.AddRange(UserDLLs); + parameters = new CompilerParameters(DLLs.ToArray()); + + return csc.CompileAssemblyFromSource(parameters, beginningCode.Replace("public class Script", replaceText) + Code + endingCode); + } + + public object MakeScriptObject(CompilerResults results, string TypeAsString = "Script") + { + Type t = results.CompiledAssembly.GetType(TypeAsString); + return Activator.CreateInstance(t); + } + + public bool CheckIfContains(string input, params string[] strings) + { + for (int i = 0; i < strings.Length; i++) + { + if (input.Contains(strings[i])) + return true; + } + + return false; + } + + List ContainedWords = new List(); + public List ReturnIfContains(string input, params string[] strings) + { + ContainedWords.Clear(); + for (int i = 0; i < strings.Length; i++) + { + if (input.Contains(strings[i])) + { + ContainedWords.Add(strings[i]); + } + } + + return ContainedWords; + } + + private void Reload_Button(object sender, EventArgs e) + { + ReloadCommands(); + } + + public void DisplayError(string msg, string title = "Command Creation - Error") + { + MessageBox.Show(msg, title, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + public void RunCommand(Query data) + { + Debug.WriteLine("Category: " + data.Category); + + switch (data.Category) + { + case Category.SteamGame: + synth.SpeakAsync("Starting Game, " + data.Data); + Process.Start("steam://rungameid/" + (int)Parse(data.Category, data.Data)); + break; + + case Category.App: + synth.SpeakAsync("Starting Application, " + data.Data); + + string AppLocation = appDict[data.Data]; + string Arguments = ""; + + for (int i = 0; i < arguments.Length; i++) + if (AppLocation.Contains(arguments[i])) + { + Debug.WriteLine("CONTAINS"); + Arguments += arguments[i] + " "; + AppLocation = AppLocation.Replace(arguments[i], ""); + } + + Arguments = Arguments.Trim(); + AppLocation = AppLocation.Trim(); + Debug.WriteLine(AppLocation); + Debug.WriteLine(Arguments); + + + if (Arguments.Length > 0) + Process.Start((string)AppLocation, Arguments); + else + Process.Start((string)Parse(data.Category, data.Data)); + break; + + case Category.Question: + Parse(data.Category, data.Data); + break; + + case Category.Command: + Parse(data.Category, data.Data); + break; + + case Category.Script: + Parse(data.Category, data.Data); + break; + } + } + + private void ShowChart_Click(object sender, EventArgs e) + { + if (!form2.Visible) + form2.Show(); + + form2.BringToFront(); + } + + private void Form1_FormClosing(object sender, FormClosingEventArgs e) + { + synth.Dispose(); + rec.RecognizeAsyncStop(); + rec.Dispose(); + listener.KeyDown -= KeyDown; + listener.KeyUp -= KeyUp; + listener.Uninstall(); + player.close(); + + ape1?.Dispose(); + ape2?.Dispose(); + + form2.Save(false); + } + + private void SaveButton_Click(object sender, EventArgs e) + { + form2.Save(); + } + + public object Parse(Category cat, string data) + { + switch (cat) + { + case Category.SteamGame: + return steamGameDict[data]; + + case Category.App: + return appDict[data]; + + case Category.Question: + questionDict[data](); + return null; + + case Category.Command: + commandDict[data](); + return null; + + case Category.Script: + if (scriptDict[data] == null) + { + scriptDict.Remove(data); + + string randomName = data.Replace(" ", "_") + r.Next(10000, 100000); + + + scriptDict.Add(data, (object)MakeScriptObject(CompileCode(codeDict[data], "public class " + randomName), randomName)); + } + ((dynamic)scriptDict[data]).Function(this); + return null; + } + + return null; + } + + + public static string getBetween(string strSource, string strStart, string strEnd) + { + int Start, End; + if (strSource.Contains(strStart) && strSource.Contains(strEnd)) + { + Start = strSource.IndexOf(strStart, 0) + strStart.Length; + End = strSource.IndexOf(strEnd, Start); + return strSource.Substring(Start, End - Start); + } + else + { + return ""; + } + } + } + + public static class Extensions + { + public static T GetRandomValue(this T[] array) + { + return array[Form1.r.Next(0, array.Length)]; + } + + public static IEnumerable SplitToLines(this string input) + { + if (input == null) + { + yield break; + } + + using (System.IO.StringReader reader = new System.IO.StringReader(input)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + yield return line; + } + } + } + + public static void Serialize(this T value, string outputFile) + { + + if (value == null) + MessageBox.Show("The object submitted for serialization was null", "Serialization - Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + + try + { + XmlSerializer s = new XmlSerializer(typeof(T)); + + using (TextWriter tw = new StreamWriter(outputFile)) + { + s.Serialize(tw, value); + tw.Close(); + } + } + catch (Exception ex) + { + throw new Exception("An error occurred", ex); + } + } + + public static T Deserialize(string fileLocation) + { + T deserializedObject = default(T); + + try + { + var xmlSerializer = new XmlSerializer(typeof(T)); + using (TextReader tr = new StreamReader(fileLocation)) + { + deserializedObject = (T)xmlSerializer.Deserialize(tr); + tr.Close(); + } + } + catch (Exception ex) + { + throw new Exception("An error occured", ex); + } + + return deserializedObject; + } + } + + public class Query + { + public Form1.Category Category; + public string Data; + } + +} diff --git a/src/Form1.resx b/src/Form1.resx new file mode 100755 index 0000000..29dcb1b --- /dev/null +++ b/src/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Form2.Designer.cs b/src/Form2.Designer.cs new file mode 100755 index 0000000..aa5c9d1 --- /dev/null +++ b/src/Form2.Designer.cs @@ -0,0 +1,68 @@ +namespace SpeechBot +{ + partial class Form2 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.SuspendLayout(); + // + // dataGridView1 + // + this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dataGridView1.BackgroundColor = System.Drawing.SystemColors.ActiveCaption; + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Location = new System.Drawing.Point(1, -1); + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.Size = new System.Drawing.Size(801, 451); + this.dataGridView1.TabIndex = 0; + this.dataGridView1.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick); + this.dataGridView1.ColumnAdded += new System.Windows.Forms.DataGridViewColumnEventHandler(this.dataGridView1_ColumnAdded); + // + // Form2 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.dataGridView1); + this.Name = "Form2"; + this.Text = "Chart"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form2_FormClosing); + this.Load += new System.EventHandler(this.Form2_Load); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + public System.Windows.Forms.DataGridView dataGridView1; + } +} \ No newline at end of file diff --git a/src/Form2.cs b/src/Form2.cs new file mode 100755 index 0000000..d6d9b75 --- /dev/null +++ b/src/Form2.cs @@ -0,0 +1,319 @@ +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SpeechBot +{ + public partial class Form2 : Form + { + Form1 form1; + public Form2(Form1 f1Instance) + { + InitializeComponent(); + form1 = f1Instance; + } + + private void Form2_Load(object sender, EventArgs e) + { + this.MinimumSize = new Size(560, 380); + + dataGridView1.Columns.Add("Command Type", "Command Type"); + dataGridView1.Columns.Add("Command Name", "Command Name"); + dataGridView1.Columns.Add("Command Value", "Command Value"); + dataGridView1.Columns.Add("Edit Command", "Edit Command"); + dataGridView1.Columns.Add("Delete Command", "Delete Command"); + + foreach (DataGridViewColumn column in dataGridView1.Columns) + { + column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; + + } + + //dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells; //don't know what this does (or if it affects anything) + dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + dataGridView1.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; + dataGridView1.Columns[3].DefaultCellStyle.Font = new Font("Microsoft Sans Serif", 16f); + dataGridView1.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; + dataGridView1.Columns[4].DefaultCellStyle.Font = new Font("Microsoft Sans Serif", 16f); + dataGridView1.AllowUserToResizeColumns = false; + dataGridView1.AllowUserToResizeRows = false; + + dataGridView1.Dock = DockStyle.Fill; + dataGridView1.ReadOnly = true; + + + //dataGridView1.Rows.RemoveAt(0); + dataGridView1.AllowUserToAddRows = false; + } + + EditData ed; + int currentlyEditing = -1; + int newSteamID; + //I don't re-add the tokens when the name is changed because the order doesn't really matter if we are just saving the dictionaries. + private async void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) + { + if (e.ColumnIndex < 0 || e.RowIndex < 0 || e.ColumnIndex > dataGridView1.Columns.Count - 1 || e.RowIndex > dataGridView1.Rows.Count - 1) + return; + + if (e.ColumnIndex == 3) + { + currentlyEditing = e.RowIndex; + string cmdName = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString(); + string cmdData = dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString(); + ed = await InputBox.Instance.Show("Enter new Command Name or Data", "Edit Menu", dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString(), 0, dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString(), 0); + + currentlyEditing = -1; + + if (ed == null) + { + return; //Edit cancelled + } + + string newName = ed.Name.ToLower(); + string newData = ed.Data; + switch ((Form1.Category)Enum.Parse(typeof(Form1.Category), dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString())) + { + + + case Form1.Category.SteamGame: + + if (cmdName != newName && cmdData == newData) + { + form1.steamGameList.Remove(cmdName); + form1.steamGameList.Add(newName); + + form1.steamGameDict.Add(newName, form1.steamGameDict[cmdName]); + form1.steamGameDict.Remove(cmdName); + dataGridView1.Rows[e.RowIndex].Cells[1].Value = newName; + } + else if (cmdData != newData) + { + if (int.TryParse(newData, out newSteamID)) + { + if (cmdName != newName) + { + form1.steamGameList.Remove(cmdName); + form1.steamGameList.Add(newName); + } + + MessageBox.Show("After Parse: " + newSteamID); + + form1.steamGameDict.Remove(cmdName); + form1.steamGameDict.Add(newName, newSteamID); + + dataGridView1.Rows[e.RowIndex].Cells[1].Value = newName; + dataGridView1.Rows[e.RowIndex].Cells[2].Value = newData; + } + else + { + form1.DisplayError("Text is not an [Integer]"); + return; + } + } + + break; + + case Form1.Category.App: + if (cmdName != newName && cmdData == newData) + { + form1.appList.Remove(cmdName); + form1.appList.Add(newName); + + form1.appDict.Add(newName, form1.appDict[cmdName]); + form1.appDict.Remove(cmdName); + + dataGridView1.Rows[e.RowIndex].Cells[1].Value = newName; + } + else if (cmdData != newData) + { + if (File.Exists(newData)) + { + if (cmdName != newName) + { + form1.appList.Remove(cmdName); + form1.appList.Add(newName); + + } + form1.appDict.Remove(cmdName); + form1.appDict.Add(newName, newData); + + dataGridView1.Rows[e.RowIndex].Cells[1].Value = newName; + dataGridView1.Rows[e.RowIndex].Cells[2].Value = newData; + } + else + { + form1.DisplayError("Text does not point to a [File Location]"); + return; + } + } + + break; + + case Form1.Category.Question: //not implemented + break; + + case Form1.Category.Command: //not implemented + break; + + case Form1.Category.Script: + + if (cmdName != newName && cmdData == newData) + { + form1.scriptList.Remove(cmdName); + form1.scriptList.Add(newName); + + form1.scriptDict.Add(newName, form1.scriptDict[cmdName]); + form1.scriptDict.Remove(cmdName); + + form1.codeDict.Add(newName, form1.codeDict[cmdName]); + form1.codeDict.Remove(cmdName); + + dataGridView1.Rows[e.RowIndex].Cells[1].Value = newName; + } + else if (cmdData != newData) //name is getting changed anyways so two seperate statements is redundant + { + string randomName = newName.Replace(" ", "_") + Form1.r.Next(10000, 100000); + MessageBox.Show(randomName); + CompilerResults results = form1.CompileCode(newData, "public class " + randomName); + + if (results == null) + return; + + if (cmdName != newName) + { + form1.scriptList.Remove(cmdName); + form1.scriptList.Add(newName); + } + + form1.scriptDict.Remove(cmdName); + form1.scriptDict.Add(newName, form1.MakeScriptObject(results, randomName)); + + form1.codeDict.Remove(cmdName); + form1.codeDict.Add(newName, newData); + + dataGridView1.Rows[e.RowIndex].Cells[1].Value = newName; + dataGridView1.Rows[e.RowIndex].Cells[2].Value = newData; + } + + #region note + //if (cmdData != ed.Data && cmdName == ed.Name) //two seperate ways to do so, but is redundant (can do both in one) + //{ + // CompilerResults results = form1.CompileCode(ed.Data); + + // if (results == null) + // return; + + // form1.scriptDict.Remove(cmdName); + // form1.scriptDict.Add(cmdName, form1.MakeScriptDynamic(results)); + //} + + //if (cmdData != ed.Data && cmdName != ed.Name) + //{ + // CompilerResults results = form1.CompileCode(ed.Data); + + // if (results == null) + // return; + + // form1.scriptDict.Remove(cmdName); + // form1.scriptDict.Add(ed.Name, form1.MakeScriptDynamic(results)); + //} + #endregion + + break; + + } + form1.ReloadCommands(); + + + } + else if (e.ColumnIndex == 4) + { + if (MessageBox.Show($"Are you sure you want to delete {dataGridView1.Rows[e.RowIndex].Cells[0].Value}: \"{dataGridView1.Rows[e.RowIndex].Cells[1].Value}\" ?", "Command Deletion", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + string cmdName = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString(); + + int CategoryNumber = (int)Enum.Parse(typeof(Form1.Category), dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString()); + + + form1.categoryList[CategoryNumber].Remove(cmdName); + + form1.dictArray[CategoryNumber].Remove(cmdName); + + if (CategoryNumber == 4) + { + form1.codeDict.Remove(cmdName); + } + + form1.ReloadCommands(); + + dataGridView1.Rows.RemoveAt(e.RowIndex); + + if (e.RowIndex == currentlyEditing) + { + InputBox.Instance.Cancel(); + currentlyEditing = -1; + } + } + } + } + + SaveData sd = new SaveData(); + public void Save(bool updateSavedTime = true) + { + sd.SteamGameList = form1.steamGameDict.Keys.ToList().GetRange(form1.steamStartIndex, form1.steamGameDict.Count - form1.steamStartIndex); + sd.SteamGameToken = form1.steamGameDict.Values.ToList().GetRange(form1.steamStartIndex, form1.steamGameDict.Count - form1.steamStartIndex); + + sd.AppList = form1.appDict.Keys.ToList().GetRange(form1.appStartIndex, form1.appDict.Count - form1.appStartIndex); + sd.AppToken = form1.appDict.Values.ToList().GetRange(form1.appStartIndex, form1.appDict.Count - form1.appStartIndex); + + sd.ScriptList = form1.codeDict.Keys.ToList(); + sd.CodeToken = form1.codeDict.Values.ToList(); + + sd.Serialize(form1.saveLocation); + + if (updateSavedTime) + { + form1.SaveTimeLabel.Text = $"Last Saved:{Environment.NewLine} {DateTime.Now.ToString("MM'-'dd'-'yyyy'@'HH':'mm':'ss")}"; + } + } + + private void dataGridView1_ColumnAdded(object sender, DataGridViewColumnEventArgs e) + { + e.Column.SortMode = DataGridViewColumnSortMode.NotSortable; + } + + private void Form2_FormClosing(object sender, FormClosingEventArgs e) + { + this.Hide(); + e.Cancel = true; + } + } + + public class SaveData + { + public List SteamGameList; + public List SteamGameToken; + + public List AppList; + public List AppToken; + + public List ScriptList; + public List CodeToken; + } + + + public class EditData + { + public string Name; + public string Data; + } +} diff --git a/src/Form2.resx b/src/Form2.resx new file mode 100755 index 0000000..29dcb1b --- /dev/null +++ b/src/Form2.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/InputBox.Designer.cs b/src/InputBox.Designer.cs new file mode 100755 index 0000000..edf04bc --- /dev/null +++ b/src/InputBox.Designer.cs @@ -0,0 +1,112 @@ +namespace SpeechBot +{ + partial class InputBox + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.OKButton = new System.Windows.Forms.Button(); + this.CancelButton = new System.Windows.Forms.Button(); + this.NameInput = new System.Windows.Forms.TextBox(); + this.MessageLabel = new System.Windows.Forms.Label(); + this.DataInput = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // OKButton + // + this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.OKButton.Location = new System.Drawing.Point(268, 21); + this.OKButton.Name = "OKButton"; + this.OKButton.Size = new System.Drawing.Size(75, 23); + this.OKButton.TabIndex = 0; + this.OKButton.Text = "OK"; + this.OKButton.UseVisualStyleBackColor = true; + // + // CancelButton + // + this.CancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.CancelButton.Location = new System.Drawing.Point(268, 50); + this.CancelButton.Name = "CancelButton"; + this.CancelButton.Size = new System.Drawing.Size(75, 23); + this.CancelButton.TabIndex = 1; + this.CancelButton.Text = "Cancel"; + this.CancelButton.UseVisualStyleBackColor = true; + // + // NameInput + // + this.NameInput.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.NameInput.Location = new System.Drawing.Point(12, 104); + this.NameInput.Name = "NameInput"; + this.NameInput.Size = new System.Drawing.Size(331, 20); + this.NameInput.TabIndex = 2; + // + // MessageLabel + // + this.MessageLabel.AutoSize = true; + this.MessageLabel.Location = new System.Drawing.Point(9, 9); + this.MessageLabel.Name = "MessageLabel"; + this.MessageLabel.Size = new System.Drawing.Size(50, 13); + this.MessageLabel.TabIndex = 3; + this.MessageLabel.Text = "Message"; + // + // DataInput + // + this.DataInput.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.DataInput.Location = new System.Drawing.Point(12, 145); + this.DataInput.Multiline = true; + this.DataInput.Name = "DataInput"; + this.DataInput.Size = new System.Drawing.Size(331, 239); + this.DataInput.TabIndex = 4; + // + // InputBox + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(355, 396); + this.ControlBox = false; + this.Controls.Add(this.DataInput); + this.Controls.Add(this.MessageLabel); + this.Controls.Add(this.NameInput); + this.Controls.Add(this.CancelButton); + this.Controls.Add(this.OKButton); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Name = "InputBox"; + this.Text = "InputBox"; + this.Load += new System.EventHandler(this.InputBox_Load); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button OKButton; + private System.Windows.Forms.Button CancelButton; + private System.Windows.Forms.TextBox NameInput; + private System.Windows.Forms.Label MessageLabel; + private System.Windows.Forms.TextBox DataInput; + } +} \ No newline at end of file diff --git a/src/InputBox.cs b/src/InputBox.cs new file mode 100755 index 0000000..1c5854f --- /dev/null +++ b/src/InputBox.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SpeechBot +{ + public partial class InputBox : Form + { + public InputBox() + { + InitializeComponent(); + } + + public static InputBox Instance; + private void InputBox_Load(object sender, EventArgs e) + { + + this.TopMost = true; + + + + NameInput.TextChanged += (s, eargs) => + { + if (NameInput.TextLength == 0) + OKButton.Enabled = false; + else + OKButton.Enabled = true; + }; + + DataInput.TextChanged += (s, eargs) => + { + if (DataInput.TextLength == 0) + OKButton.Enabled = false; + else + OKButton.Enabled = true; + }; + + OKButton.Click += (s, eargs) => + { + ed.Name = NameInput.Text; + ed.Data = DataInput.Text; + returnMessage.SetResult(ed); + }; + + CancelButton.Click += (s, eargs) => + { + returnMessage.SetResult(null); + }; + + this.FormClosing += (s, eargs) => + { + eargs.Cancel = true; + + if (returnMessage != null) + returnMessage.SetResult(null); + }; + } + + public void StealthHide() + { + Opacity = 0; + ShowInTaskbar = false; + } + + public void Init() + { + this.Opacity = 1; + this.ShowInTaskbar = true; + } + + public void Cancel() + { + this.Hide(); + } + + TaskCompletionSource returnMessage; + EditData ed = new EditData(); + public async Task Show(string Message, string Title, string DefaultName = "", int maxTextLength = 0, string DefaultData = "", int maxDataLength = 0) //Check if there are issues and things that need to be invoked. + { + + Location = new Point((Screen.PrimaryScreen.WorkingArea.Width - this.Size.Width) / 2, (Screen.PrimaryScreen.WorkingArea.Height - this.Size.Height) / 2); + OKButton.Enabled = false; + + if (DefaultName.Length > 0 && DefaultData.Length > 0) + OKButton.Enabled = true; + + MessageLabel.Text = Message; + this.Text = Title; + NameInput.MaxLength = maxTextLength; + NameInput.Text = DefaultName; + DataInput.MaxLength = maxDataLength; + DataInput.Text = DefaultData; + + this.ShowInTaskbar = true; + this.Visible = true; + + + returnMessage = new TaskCompletionSource(); + await returnMessage.Task; + + this.Visible = false; + this.ShowInTaskbar = false; + + return returnMessage.Task.Result; + } + } +} diff --git a/src/InputBox.resx b/src/InputBox.resx new file mode 100755 index 0000000..29dcb1b --- /dev/null +++ b/src/InputBox.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/KeyboardHook.cs b/src/KeyboardHook.cs new file mode 100755 index 0000000..0717966 --- /dev/null +++ b/src/KeyboardHook.cs @@ -0,0 +1,335 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.Windows.Input; +using System.Security.Permissions; + +namespace KeyboardHooker +{ + + /// + /// Class for intercepting low level keyboard hooks + /// + public class KeyboardHook + { + + /// + /// Virtual Keys + /// + public enum VKeys + { + // Losely based on http://www.pinvoke.net/default.aspx/Enums/VK.html + //NULL = 0x00, //I ADDED THIS ONE MYSELF <----------------------------------- + LBUTTON = 0x01, // Left mouse button + RBUTTON = 0x02, // Right mouse button + CANCEL = 0x03, // Control-break processing + MBUTTON = 0x04, // Middle mouse button (three-button mouse) + XBUTTON1 = 0x05, // Windows 2000/XP: X1 mouse button + XBUTTON2 = 0x06, // Windows 2000/XP: X2 mouse button + // 0x07 // Undefined + BACK = 0x08, // BACKSPACE key + TAB = 0x09, // TAB key + // 0x0A-0x0B, // Reserved + CLEAR = 0x0C, // CLEAR key + RETURN = 0x0D, // ENTER key + // 0x0E-0x0F, // Undefined + SHIFT = 0x10, // SHIFT key + CONTROL = 0x11, // CTRL key + MENU = 0x12, // ALT key + PAUSE = 0x13, // PAUSE key + CAPITAL = 0x14, // CAPS LOCK key + KANA = 0x15, // Input Method Editor (IME) Kana mode + HANGUL = 0x15, // IME Hangul mode + // 0x16, // Undefined + JUNJA = 0x17, // IME Junja mode + FINAL = 0x18, // IME final mode + HANJA = 0x19, // IME Hanja mode + KANJI = 0x19, // IME Kanji mode + // 0x1A, // Undefined + ESCAPE = 0x1B, // ESC key + CONVERT = 0x1C, // IME convert + NONCONVERT = 0x1D, // IME nonconvert + ACCEPT = 0x1E, // IME accept + MODECHANGE = 0x1F, // IME mode change request + SPACE = 0x20, // SPACEBAR + PRIOR = 0x21, // PAGE UP key + NEXT = 0x22, // PAGE DOWN key + END = 0x23, // END key + HOME = 0x24, // HOME key + LEFT = 0x25, // LEFT ARROW key + UP = 0x26, // UP ARROW key + RIGHT = 0x27, // RIGHT ARROW key + DOWN = 0x28, // DOWN ARROW key + SELECT = 0x29, // SELECT key + PRINT = 0x2A, // PRINT key + EXECUTE = 0x2B, // EXECUTE key + SNAPSHOT = 0x2C, // PRINT SCREEN key + INSERT = 0x2D, // INS key + DELETE = 0x2E, // DEL key + HELP = 0x2F, // HELP key + KEY_0 = 0x30, // 0 key + KEY_1 = 0x31, // 1 key + KEY_2 = 0x32, // 2 key + KEY_3 = 0x33, // 3 key + KEY_4 = 0x34, // 4 key + KEY_5 = 0x35, // 5 key + KEY_6 = 0x36, // 6 key + KEY_7 = 0x37, // 7 key + KEY_8 = 0x38, // 8 key + KEY_9 = 0x39, // 9 key + // 0x3A-0x40, // Undefined + KEY_A = 0x41, // A key + KEY_B = 0x42, // B key + KEY_C = 0x43, // C key + KEY_D = 0x44, // D key + KEY_E = 0x45, // E key + KEY_F = 0x46, // F key + KEY_G = 0x47, // G key + KEY_H = 0x48, // H key + KEY_I = 0x49, // I key + KEY_J = 0x4A, // J key + KEY_K = 0x4B, // K key + KEY_L = 0x4C, // L key + KEY_M = 0x4D, // M key + KEY_N = 0x4E, // N key + KEY_O = 0x4F, // O key + KEY_P = 0x50, // P key + KEY_Q = 0x51, // Q key + KEY_R = 0x52, // R key + KEY_S = 0x53, // S key + KEY_T = 0x54, // T key + KEY_U = 0x55, // U key + KEY_V = 0x56, // V key + KEY_W = 0x57, // W key + KEY_X = 0x58, // X key + KEY_Y = 0x59, // Y key + KEY_Z = 0x5A, // Z key + LWIN = 0x5B, // Left Windows key (Microsoft Natural keyboard) + RWIN = 0x5C, // Right Windows key (Natural keyboard) + APPS = 0x5D, // Applications key (Natural keyboard) + // 0x5E, // Reserved + SLEEP = 0x5F, // Computer Sleep key + NUMPAD0 = 0x60, // Numeric keypad 0 key + NUMPAD1 = 0x61, // Numeric keypad 1 key + NUMPAD2 = 0x62, // Numeric keypad 2 key + NUMPAD3 = 0x63, // Numeric keypad 3 key + NUMPAD4 = 0x64, // Numeric keypad 4 key + NUMPAD5 = 0x65, // Numeric keypad 5 key + NUMPAD6 = 0x66, // Numeric keypad 6 key + NUMPAD7 = 0x67, // Numeric keypad 7 key + NUMPAD8 = 0x68, // Numeric keypad 8 key + NUMPAD9 = 0x69, // Numeric keypad 9 key + MULTIPLY = 0x6A, // Multiply key + ADD = 0x6B, // Add key + SEPARATOR = 0x6C, // Separator key + SUBTRACT = 0x6D, // Subtract key + DECIMAL = 0x6E, // Decimal key + DIVIDE = 0x6F, // Divide key + F1 = 0x70, // F1 key + F2 = 0x71, // F2 key + F3 = 0x72, // F3 key + F4 = 0x73, // F4 key + F5 = 0x74, // F5 key + F6 = 0x75, // F6 key + F7 = 0x76, // F7 key + F8 = 0x77, // F8 key + F9 = 0x78, // F9 key + F10 = 0x79, // F10 key + F11 = 0x7A, // F11 key + F12 = 0x7B, // F12 key + F13 = 0x7C, // F13 key + F14 = 0x7D, // F14 key + F15 = 0x7E, // F15 key + F16 = 0x7F, // F16 key + F17 = 0x80, // F17 key + F18 = 0x81, // F18 key + F19 = 0x82, // F19 key + F20 = 0x83, // F20 key + F21 = 0x84, // F21 key + F22 = 0x85, // F22 key, (PPC only) Key used to lock device. + F23 = 0x86, // F23 key + F24 = 0x87, // F24 key + // 0x88-0X8F, // Unassigned + NUMLOCK = 0x90, // NUM LOCK key + SCROLL = 0x91, // SCROLL LOCK key + // 0x92-0x96, // OEM specific + // 0x97-0x9F, // Unassigned + LSHIFT = 0xA0, // Left SHIFT key + RSHIFT = 0xA1, // Right SHIFT key + LCONTROL = 0xA2, // Left CONTROL key + RCONTROL = 0xA3, // Right CONTROL key + LMENU = 0xA4, // Left MENU key + RMENU = 0xA5, // Right MENU key + BROWSER_BACK = 0xA6, // Windows 2000/XP: Browser Back key + BROWSER_FORWARD = 0xA7, // Windows 2000/XP: Browser Forward key + BROWSER_REFRESH = 0xA8, // Windows 2000/XP: Browser Refresh key + BROWSER_STOP = 0xA9, // Windows 2000/XP: Browser Stop key + BROWSER_SEARCH = 0xAA, // Windows 2000/XP: Browser Search key + BROWSER_FAVORITES = 0xAB, // Windows 2000/XP: Browser Favorites key + BROWSER_HOME = 0xAC, // Windows 2000/XP: Browser Start and Home key + VOLUME_MUTE = 0xAD, // Windows 2000/XP: Volume Mute key + VOLUME_DOWN = 0xAE, // Windows 2000/XP: Volume Down key + VOLUME_UP = 0xAF, // Windows 2000/XP: Volume Up key + MEDIA_NEXT_TRACK = 0xB0,// Windows 2000/XP: Next Track key + MEDIA_PREV_TRACK = 0xB1,// Windows 2000/XP: Previous Track key + MEDIA_STOP = 0xB2, // Windows 2000/XP: Stop Media key + MEDIA_PLAY_PAUSE = 0xB3,// Windows 2000/XP: Play/Pause Media key + LAUNCH_MAIL = 0xB4, // Windows 2000/XP: Start Mail key + LAUNCH_MEDIA_SELECT = 0xB5, // Windows 2000/XP: Select Media key + LAUNCH_APP1 = 0xB6, // Windows 2000/XP: Start Application 1 key + LAUNCH_APP2 = 0xB7, // Windows 2000/XP: Start Application 2 key + // 0xB8-0xB9, // Reserved + OEM_1 = 0xBA, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the ';:' key + OEM_PLUS = 0xBB, // Windows 2000/XP: For any country/region, the '+' key + OEM_COMMA = 0xBC, // Windows 2000/XP: For any country/region, the ',' key + OEM_MINUS = 0xBD, // Windows 2000/XP: For any country/region, the '-' key + OEM_PERIOD = 0xBE, // Windows 2000/XP: For any country/region, the '.' key + OEM_2 = 0xBF, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '/?' key + OEM_3 = 0xC0, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '`~' key + // 0xC1-0xD7, // Reserved + // 0xD8-0xDA, // Unassigned + OEM_4 = 0xDB, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '[{' key + OEM_5 = 0xDC, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the '\|' key + OEM_6 = 0xDD, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the ']}' key + OEM_7 = 0xDE, // Used for miscellaneous characters; it can vary by keyboard. + // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key + OEM_8 = 0xDF, // Used for miscellaneous characters; it can vary by keyboard. + // 0xE0, // Reserved + // 0xE1, // OEM specific + OEM_102 = 0xE2, // Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard + // 0xE3-E4, // OEM specific + PROCESSKEY = 0xE5, // Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key + // 0xE6, // OEM specific + PACKET = 0xE7, // Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP + // 0xE8, // Unassigned + // 0xE9-F5, // OEM specific + ATTN = 0xF6, // Attn key + CRSEL = 0xF7, // CrSel key + EXSEL = 0xF8, // ExSel key + EREOF = 0xF9, // Erase EOF key + PLAY = 0xFA, // Play key + ZOOM = 0xFB, // Zoom key + NONAME = 0xFC, // Reserved + PA1 = 0xFD, // PA1 key + OEM_CLEAR = 0xFE // Clear key + } + + /// + /// Internal callback processing function + /// + private delegate IntPtr KeyboardHookHandler(int nCode, IntPtr wParam, IntPtr lParam); + private KeyboardHookHandler hookHandler; + + /// + /// Function that will be called when defined events occur + /// + /// VKeys + public delegate void KeyboardHookCallback(VKeys key); + + #region Events + public event KeyboardHookCallback KeyDown; + public event KeyboardHookCallback KeyUp; + #endregion + + /// + /// Hook ID + /// + private IntPtr hookID = IntPtr.Zero; + + /// + /// Install low level keyboard hook + /// + public void Install() + { + int a = 0; + int b = 0; + a ^= b; + hookHandler = HookFunc; + hookID = SetHook(hookHandler); + } + + /// + /// Remove low level keyboard hook + /// + public void Uninstall() + { + UnhookWindowsHookEx(hookID); + } + + /// + /// Registers hook with Windows API + /// + /// Callback function + /// Hook ID + private IntPtr SetHook(KeyboardHookHandler proc) + { + using (ProcessModule module = Process.GetCurrentProcess().MainModule) + return SetWindowsHookEx(13, proc, GetModuleHandle(module.ModuleName), 0); + } + + /// + /// Default hook call, which analyses pressed keys + /// + private IntPtr HookFunc(int nCode, IntPtr wParam, IntPtr lParam) + { + if (nCode >= 0) + { + int iwParam = wParam.ToInt32(); + + if ((iwParam == WM_KEYDOWN || iwParam == WM_SYSKEYDOWN)) + if (KeyDown != null) + KeyDown((VKeys)Marshal.ReadInt32(lParam)); + if ((iwParam == WM_KEYUP || iwParam == WM_SYSKEYUP)) + if (KeyUp != null) + KeyUp((VKeys)Marshal.ReadInt32(lParam)); + } + + return CallNextHookEx(hookID, nCode, wParam, lParam); + } + + /// + /// Destructor. Unhook current hook + /// + ~KeyboardHook() + { + Uninstall(); + } + + /// + /// Low-Level function declarations + /// + #region WinAPI + private const int WM_KEYDOWN = 0x100; + private const int WM_SYSKEYDOWN = 0x104; + private const int WM_KEYUP = 0x101; + private const int WM_SYSKEYUP = 0x105; + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookHandler lpfn, IntPtr hMod, uint dwThreadId); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool UnhookWindowsHookEx(IntPtr hhk); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr GetModuleHandle(string lpModuleName); + #endregion + } +} \ No newline at end of file diff --git a/src/Program.cs b/src/Program.cs new file mode 100755 index 0000000..8232652 --- /dev/null +++ b/src/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SpeechBot +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs new file mode 100755 index 0000000..d4de56b --- /dev/null +++ b/src/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SpeechBot")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SpeechBot")] +[assembly: AssemblyCopyright("Copyright © 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ad4267e6-9d7a-4f24-bd72-6e8c8ba6b6e4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Properties/Resources.Designer.cs b/src/Properties/Resources.Designer.cs new file mode 100755 index 0000000..ac9096c --- /dev/null +++ b/src/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SpeechBot.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SpeechBot.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/src/Properties/Resources.resx b/src/Properties/Resources.resx new file mode 100755 index 0000000..ffecec8 --- /dev/null +++ b/src/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Properties/Settings.Designer.cs b/src/Properties/Settings.Designer.cs new file mode 100755 index 0000000..155a600 --- /dev/null +++ b/src/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SpeechBot.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/src/Properties/Settings.settings b/src/Properties/Settings.settings new file mode 100755 index 0000000..abf36c5 --- /dev/null +++ b/src/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/SpeechBot.csproj b/src/SpeechBot.csproj new file mode 100755 index 0000000..c0bacc5 --- /dev/null +++ b/src/SpeechBot.csproj @@ -0,0 +1,121 @@ + + + + + Debug + AnyCPU + {AD4267E6-9D7A-4F24-BD72-6E8C8BA6B6E4} + WinExe + SpeechBot + SpeechBot + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + packages\NAudio.1.10.0\lib\net35\NAudio.dll + + + + + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + Form + + + Form2.cs + + + Form + + + InputBox.cs + + + + + + Form1.cs + + + Form2.cs + + + InputBox.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + {6BF52A50-394A-11D3-B153-00C04F79FAA6} + 1 + 0 + 0 + tlbimp + False + True + + + + \ No newline at end of file diff --git a/src/SpeechBot.sln b/src/SpeechBot.sln new file mode 100755 index 0000000..ab05f60 --- /dev/null +++ b/src/SpeechBot.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29519.87 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpeechBot", "SpeechBot.csproj", "{AD4267E6-9D7A-4F24-BD72-6E8C8BA6B6E4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AD4267E6-9D7A-4F24-BD72-6E8C8BA6B6E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD4267E6-9D7A-4F24-BD72-6E8C8BA6B6E4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD4267E6-9D7A-4F24-BD72-6E8C8BA6B6E4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD4267E6-9D7A-4F24-BD72-6E8C8BA6B6E4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7438DE96-D1D6-430A-9114-9D998154B297} + EndGlobalSection +EndGlobal diff --git a/src/packages.config b/src/packages.config new file mode 100755 index 0000000..38cf596 --- /dev/null +++ b/src/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file