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