diff --git a/resources/commands/apps/command.toml b/resources/commands/apps/command.toml new file mode 100644 index 0000000..5ce0817 --- /dev/null +++ b/resources/commands/apps/command.toml @@ -0,0 +1,230 @@ +[[commands]] +id = "open_browser" +type = "lua" +script = "open_browser.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "открой браузер", + "запусти браузер", + "открой хром", + "запусти хром", + "включи браузер", + "браузер открой", + "нужен браузер", +] +en = [ + "open browser", + "launch browser", + "open chrome", + "launch chrome", + "start browser", + "i need browser", +] +ua = [ + "відкрий браузер", + "запусти браузер", + "відкрий хром", + "запусти хром", + "увімкни браузер", +] + + +[[commands]] +id = "open_notepad" +type = "lua" +script = "open_notepad.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "открой блокнот", + "запусти блокнот", + "открой нотепад", +] +en = [ + "open notepad", + "launch notepad", +] +ua = [ + "відкрий блокнот", + "запусти блокнот", +] + + +[[commands]] +id = "open_calculator" +type = "lua" +script = "open_calculator.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "открой калькулятор", + "запусти калькулятор", + "нужен калькулятор", +] +en = [ + "open calculator", + "launch calculator", + "calculator please", +] +ua = [ + "відкрий калькулятор", + "запусти калькулятор", +] + + +[[commands]] +id = "open_explorer" +type = "lua" +script = "open_explorer.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "открой проводник", + "открой папку", + "запусти проводник", + "открой файлы", +] +en = [ + "open explorer", + "open file explorer", + "open files", + "open folder", +] +ua = [ + "відкрий провідник", + "відкрий папку", +] + + +[[commands]] +id = "open_terminal" +type = "lua" +script = "open_terminal.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "открой терминал", + "запусти терминал", + "открой консоль", + "запусти консоль", + "открой повершелл", +] +en = [ + "open terminal", + "open powershell", + "open console", + "launch terminal", +] +ua = [ + "відкрий термінал", + "відкрий консоль", +] + + +[[commands]] +id = "open_settings" +type = "lua" +script = "open_settings.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "открой настройки", + "открой параметры", + "запусти настройки", + "открой настройки виндоус", +] +en = [ + "open settings", + "launch settings", + "windows settings", +] +ua = [ + "відкрий налаштування", + "відкрий параметри", +] + + +[[commands]] +id = "open_task_manager" +type = "lua" +script = "open_task_manager.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "открой диспетчер задач", + "запусти диспетчер задач", + "диспетчер задач", +] +en = [ + "open task manager", + "launch task manager", + "task manager", +] +ua = [ + "відкрий диспетчер задач", + "диспетчер задач", +] + + +[[commands]] +id = "lock_screen" +type = "lua" +script = "lock_screen.lua" +sandbox = "full" +timeout = 3000 + +[commands.phrases] +ru = [ + "заблокируй компьютер", + "заблокируй экран", + "блокировка экрана", + "залочь", +] +en = [ + "lock screen", + "lock the computer", + "lock pc", +] +ua = [ + "заблокуй комп'ютер", + "заблокуй екран", +] + + +[[commands]] +id = "screenshot" +type = "lua" +script = "screenshot.lua" +sandbox = "full" +timeout = 5000 + +[commands.phrases] +ru = [ + "сделай скриншот", + "скриншот", + "сними экран", +] +en = [ + "take screenshot", + "screenshot", + "capture screen", +] +ua = [ + "зроби скріншот", + "знімок екрана", +] diff --git a/resources/commands/apps/lock_screen.lua b/resources/commands/apps/lock_screen.lua new file mode 100644 index 0000000..956384f --- /dev/null +++ b/resources/commands/apps/lock_screen.lua @@ -0,0 +1,8 @@ +local res = jarvis.system.exec("rundll32.exe user32.dll,LockWorkStation") +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "lock screen failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/open_browser.lua b/resources/commands/apps/open_browser.lua new file mode 100644 index 0000000..c1061ac --- /dev/null +++ b/resources/commands/apps/open_browser.lua @@ -0,0 +1,9 @@ +local cmd = "start \"\" \"https://www.google.com\"" +local res = jarvis.system.exec(cmd) +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "open browser failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/open_calculator.lua b/resources/commands/apps/open_calculator.lua new file mode 100644 index 0000000..0afe795 --- /dev/null +++ b/resources/commands/apps/open_calculator.lua @@ -0,0 +1,8 @@ +local res = jarvis.system.exec("start \"\" calc.exe") +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "open calculator failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/open_explorer.lua b/resources/commands/apps/open_explorer.lua new file mode 100644 index 0000000..5c6a2e4 --- /dev/null +++ b/resources/commands/apps/open_explorer.lua @@ -0,0 +1,8 @@ +local res = jarvis.system.exec("start \"\" explorer.exe") +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "open explorer failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/open_notepad.lua b/resources/commands/apps/open_notepad.lua new file mode 100644 index 0000000..023c4f1 --- /dev/null +++ b/resources/commands/apps/open_notepad.lua @@ -0,0 +1,8 @@ +local res = jarvis.system.exec("start \"\" notepad.exe") +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "open notepad failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/open_settings.lua b/resources/commands/apps/open_settings.lua new file mode 100644 index 0000000..786ad13 --- /dev/null +++ b/resources/commands/apps/open_settings.lua @@ -0,0 +1,8 @@ +local res = jarvis.system.exec("start \"\" ms-settings:") +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "open settings failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/open_task_manager.lua b/resources/commands/apps/open_task_manager.lua new file mode 100644 index 0000000..b7d0f18 --- /dev/null +++ b/resources/commands/apps/open_task_manager.lua @@ -0,0 +1,8 @@ +local res = jarvis.system.exec("start \"\" taskmgr.exe") +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "open task manager failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/open_terminal.lua b/resources/commands/apps/open_terminal.lua new file mode 100644 index 0000000..cf91242 --- /dev/null +++ b/resources/commands/apps/open_terminal.lua @@ -0,0 +1,13 @@ +local res = jarvis.system.exec("start \"\" wt.exe") +if not res.success then + jarvis.log("warn", "wt.exe not found, falling back to powershell") + res = jarvis.system.exec("start \"\" powershell.exe") +end + +if res.success then + jarvis.audio.play_ok() +else + jarvis.log("error", "open terminal failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end +return { chain = false } diff --git a/resources/commands/apps/screenshot.lua b/resources/commands/apps/screenshot.lua new file mode 100644 index 0000000..4d24243 --- /dev/null +++ b/resources/commands/apps/screenshot.lua @@ -0,0 +1,24 @@ +local ts = jarvis.context.time.year .. jarvis.context.time.month .. jarvis.context.time.day + .. "_" .. jarvis.context.time.hour .. jarvis.context.time.minute .. jarvis.context.time.second + +local userprofile = jarvis.system.env("USERPROFILE") or "C:\\Users\\Public" +local target = userprofile .. "\\Pictures\\jarvis_screenshot_" .. ts .. ".png" + +local ps = string.format( + [[Add-Type -AssemblyName System.Windows.Forms,System.Drawing; $b=[System.Windows.Forms.Screen]::PrimaryScreen.Bounds; $bmp=New-Object Drawing.Bitmap $b.Width,$b.Height; $g=[Drawing.Graphics]::FromImage($bmp); $g.CopyFromScreen($b.Location,[Drawing.Point]::Empty,$b.Size); $bmp.Save('%s'); $g.Dispose(); $bmp.Dispose()]], + target:gsub("\\", "\\\\") +) + +local cmd = string.format('powershell -NoProfile -ExecutionPolicy Bypass -Command "%s"', ps:gsub('"', '\\"')) +local res = jarvis.system.exec(cmd) + +if res.success then + jarvis.log("info", "screenshot saved to " .. target) + jarvis.system.notify("Скриншот", target) + jarvis.audio.play_ok() +else + jarvis.log("error", "screenshot failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() +end + +return { chain = false } diff --git a/resources/commands/file_search/command.toml b/resources/commands/file_search/command.toml new file mode 100644 index 0000000..f931b14 --- /dev/null +++ b/resources/commands/file_search/command.toml @@ -0,0 +1,26 @@ +[[commands]] +id = "file_search" +type = "lua" +script = "search.lua" +sandbox = "full" +timeout = 15000 + +[commands.phrases] +ru = [ + "найди файл", + "поиск файла", + "ищи файл", + "где файл", + "найди документ", +] +en = [ + "find file", + "search file", + "where is file", + "locate file", +] +ua = [ + "знайди файл", + "пошук файлу", + "де файл", +] diff --git a/resources/commands/file_search/search.lua b/resources/commands/file_search/search.lua new file mode 100644 index 0000000..40d9365 --- /dev/null +++ b/resources/commands/file_search/search.lua @@ -0,0 +1,78 @@ +local lang = jarvis.context.language +local phrase = (jarvis.context.phrase or ""):lower() + +local triggers = { + "найди документ", "найди файл", "поиск файла", "ищи файл", "где файл", + "find file", "search file", "where is file", "locate file", + "знайди файл", "пошук файлу", "де файл", +} + +local query = phrase +for _, t in ipairs(triggers) do + local start, finish = string.find(query, t, 1, true) + if start == 1 then + query = query:sub(finish + 1) + break + end +end +query = query:gsub("^%s+", ""):gsub("%s+$", "") + +if query == "" then + jarvis.log("warn", "file_search: empty query (phrase=" .. phrase .. ")") + jarvis.system.notify( + lang == "ru" and "Поиск файлов" or "File search", + lang == "ru" and "Что искать?" or "What to search for?" + ) + jarvis.audio.play_error() + return { chain = false } +end + +local userprofile = jarvis.system.env("USERPROFILE") or "C:\\Users\\Public" +local roots = { + userprofile .. "\\Desktop", + userprofile .. "\\Documents", + userprofile .. "\\Downloads", +} + +local escaped = query:gsub("'", "''") +local roots_arg = "'" .. table.concat(roots, "','") .. "'" +local ps = string.format( + [[$ErrorActionPreference='SilentlyContinue'; $r=@(%s); $q='*%s*'; $hits=Get-ChildItem -Path $r -Filter $q -Recurse -Depth 3 -File | Select-Object -First 5; foreach($h in $hits){ Write-Output $h.FullName }]], + roots_arg, escaped +) + +local cmd = string.format('powershell -NoProfile -ExecutionPolicy Bypass -Command "%s"', ps:gsub('"', '\\"')) +jarvis.log("info", "file_search query='" .. query .. "'") + +local res = jarvis.system.exec(cmd) + +if not res.success then + jarvis.log("error", "file_search exec failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() + return { chain = false } +end + +local stdout = res.stdout or "" +local lines = {} +for line in stdout:gmatch("[^\r\n]+") do + if line ~= "" then table.insert(lines, line) end +end + +if #lines == 0 then + jarvis.system.notify( + lang == "ru" and "Поиск файлов" or "File search", + (lang == "ru" and "Не найдено: " or "Not found: ") .. query + ) + jarvis.audio.play_not_found() +else + local first = lines[1] + local count = #lines + local title = lang == "ru" and "Найдено файлов: " or "Files found: " + jarvis.system.notify(title .. count, first) + + jarvis.log("info", "file_search opening: " .. first) + jarvis.system.exec(string.format('explorer.exe /select,"%s"', first)) + jarvis.audio.play_ok() +end + +return { chain = false } diff --git a/resources/commands/output_device/_audio_devices.ps1 b/resources/commands/output_device/_audio_devices.ps1 new file mode 100644 index 0000000..2cf76e9 --- /dev/null +++ b/resources/commands/output_device/_audio_devices.ps1 @@ -0,0 +1,195 @@ +param( + [Parameter(Mandatory=$true)] + [ValidateSet("list","set","next","current")] + [string]$Action, + + [int]$Index = -1 +) + +$ErrorActionPreference = 'Stop' + +Add-Type -TypeDefinition @' +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace JarvisAudio +{ + [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMMDeviceEnumerator + { + [PreserveSig] int EnumAudioEndpoints(int dataFlow, int stateMask, out IMMDeviceCollection devices); + [PreserveSig] int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice device); + [PreserveSig] int GetDevice([MarshalAs(UnmanagedType.LPWStr)] string id, out IMMDevice device); + } + + [Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMMDeviceCollection + { + [PreserveSig] int GetCount(out int count); + [PreserveSig] int Item(int idx, out IMMDevice device); + } + + [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IMMDevice + { + [PreserveSig] int Activate(ref Guid iid, int clsCtx, IntPtr activationParams, [MarshalAs(UnmanagedType.IUnknown)] out object iface); + [PreserveSig] int OpenPropertyStore(int access, out IPropertyStore store); + [PreserveSig] int GetId([MarshalAs(UnmanagedType.LPWStr)] out string id); + [PreserveSig] int GetState(out int state); + } + + [Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IPropertyStore + { + [PreserveSig] int GetCount(out int count); + [PreserveSig] int GetAt(int idx, out PROPERTYKEY key); + [PreserveSig] int GetValue(ref PROPERTYKEY key, out PROPVARIANT value); + } + + [StructLayout(LayoutKind.Sequential)] + public struct PROPERTYKEY + { + public Guid formatId; + public int propertyId; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PROPVARIANT + { + public ushort vt; + public ushort r1; + public ushort r2; + public ushort r3; + public IntPtr p; + public IntPtr p2; + } + + [ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] + public class MMDeviceEnumerator {} + + [Guid("F8679F50-850A-41CF-9C72-430F290290C8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IPolicyConfig + { + [PreserveSig] int GetMixFormat(); + [PreserveSig] int GetDeviceFormat(); + [PreserveSig] int ResetDeviceFormat(); + [PreserveSig] int SetDeviceFormat(); + [PreserveSig] int GetProcessingPeriod(); + [PreserveSig] int SetProcessingPeriod(); + [PreserveSig] int GetShareMode(); + [PreserveSig] int SetShareMode(); + [PreserveSig] int GetPropertyValue(); + [PreserveSig] int SetPropertyValue(); + [PreserveSig] int SetDefaultEndpoint([MarshalAs(UnmanagedType.LPWStr)] string deviceId, uint role); + [PreserveSig] int SetEndpointVisibility(); + } + + [ComImport, Guid("870AF99C-171D-4F9E-AF0D-E63DF40C2BC9")] + public class PolicyConfigClient {} + + public class Device + { + public string Id { get; set; } + public string Name { get; set; } + } + + public static class Manager + { + const int eRender = 0; + const int DEVICE_STATE_ACTIVE = 1; + + static PROPERTYKEY PKEY_Device_FriendlyName = new PROPERTYKEY { + formatId = new Guid("a45c254e-df1c-4efd-8020-67d146a850e0"), + propertyId = 14 + }; + + public static List ListRender() + { + var enumr = (IMMDeviceEnumerator)new MMDeviceEnumerator(); + IMMDeviceCollection coll; + int hr = enumr.EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, out coll); + if (hr != 0) throw new Exception("EnumAudioEndpoints failed: 0x" + hr.ToString("X")); + + int count; + coll.GetCount(out count); + + var result = new List(); + for (int i = 0; i < count; i++) + { + IMMDevice dev; + coll.Item(i, out dev); + string id; + dev.GetId(out id); + + IPropertyStore store; + dev.OpenPropertyStore(0, out store); + + PROPVARIANT v; + store.GetValue(ref PKEY_Device_FriendlyName, out v); + string name = v.p != IntPtr.Zero ? Marshal.PtrToStringUni(v.p) : "(unknown)"; + + result.Add(new Device { Id = id, Name = name }); + } + return result; + } + + public static string GetDefaultRenderId() + { + var enumr = (IMMDeviceEnumerator)new MMDeviceEnumerator(); + IMMDevice dev; + int hr = enumr.GetDefaultAudioEndpoint(eRender, 0, out dev); // eConsole = 0 + if (hr != 0) return null; + string id; + dev.GetId(out id); + return id; + } + + public static void SetDefault(string deviceId) + { + var cfg = (IPolicyConfig)new PolicyConfigClient(); + cfg.SetDefaultEndpoint(deviceId, 0); // eConsole + cfg.SetDefaultEndpoint(deviceId, 1); // eMultimedia + cfg.SetDefaultEndpoint(deviceId, 2); // eCommunications + } + } +} +'@ -Language CSharp + +$devs = [JarvisAudio.Manager]::ListRender() + +switch ($Action) { + "list" { + for ($i = 0; $i -lt $devs.Count; $i++) { + Write-Output ("{0}`t{1}" -f $i, $devs[$i].Name) + } + } + "current" { + $cur = [JarvisAudio.Manager]::GetDefaultRenderId() + for ($i = 0; $i -lt $devs.Count; $i++) { + if ($devs[$i].Id -eq $cur) { + Write-Output ("{0}`t{1}" -f $i, $devs[$i].Name) + return + } + } + Write-Output "-1`t(unknown)" + } + "set" { + if ($Index -lt 0 -or $Index -ge $devs.Count) { + Write-Error "Index out of range: $Index (have $($devs.Count) devices)" + exit 2 + } + [JarvisAudio.Manager]::SetDefault($devs[$Index].Id) + Write-Output ("OK`t{0}" -f $devs[$Index].Name) + } + "next" { + $cur = [JarvisAudio.Manager]::GetDefaultRenderId() + $curIdx = -1 + for ($i = 0; $i -lt $devs.Count; $i++) { + if ($devs[$i].Id -eq $cur) { $curIdx = $i; break } + } + $nextIdx = ($curIdx + 1) % $devs.Count + [JarvisAudio.Manager]::SetDefault($devs[$nextIdx].Id) + Write-Output ("OK`t{0}" -f $devs[$nextIdx].Name) + } +} diff --git a/resources/commands/output_device/command.toml b/resources/commands/output_device/command.toml new file mode 100644 index 0000000..422687b --- /dev/null +++ b/resources/commands/output_device/command.toml @@ -0,0 +1,55 @@ +[[commands]] +id = "list_output_devices" +type = "lua" +script = "list_devices.lua" +sandbox = "full" +timeout = 8000 + +[commands.phrases] +ru = [ + "какие устройства вывода", + "покажи устройства", + "список устройств", + "какие наушники", + "какие колонки", +] +en = [ + "list output devices", + "show audio devices", + "list speakers", + "what audio devices", +] +ua = [ + "які пристрої виводу", + "покажи пристрої", + "список пристроїв", +] + + +[[commands]] +id = "next_output_device" +type = "lua" +script = "next_device.lua" +sandbox = "full" +timeout = 8000 + +[commands.phrases] +ru = [ + "переключи устройство", + "переключи звук", + "следующее устройство", + "смени вывод", + "переключи на наушники", + "переключи на колонки", +] +en = [ + "switch audio device", + "next audio device", + "switch output", + "switch speakers", +] +ua = [ + "перемкни пристрій", + "перемкни звук", + "наступний пристрій", +] diff --git a/resources/commands/output_device/list_devices.lua b/resources/commands/output_device/list_devices.lua new file mode 100644 index 0000000..aefc6b2 --- /dev/null +++ b/resources/commands/output_device/list_devices.lua @@ -0,0 +1,31 @@ +local lang = jarvis.context.language +local helper = jarvis.context.command_path .. "\\_audio_devices.ps1" +local cmd = string.format( + 'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action list', + helper +) + +local res = jarvis.system.exec(cmd) +if not res.success then + jarvis.log("error", "list devices failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() + return { chain = false } +end + +local lines = {} +for line in (res.stdout or ""):gmatch("[^\r\n]+") do + if line ~= "" then table.insert(lines, line) end +end + +local title = lang == "ru" and "Устройства вывода" or "Output devices" +local body +if #lines == 0 then + body = lang == "ru" and "Активных устройств не найдено" or "No active devices" +else + body = table.concat(lines, "\n") +end + +jarvis.system.notify(title, body) +jarvis.log("info", "audio devices: " .. body) +jarvis.audio.play_ok() +return { chain = false } diff --git a/resources/commands/output_device/next_device.lua b/resources/commands/output_device/next_device.lua new file mode 100644 index 0000000..852462a --- /dev/null +++ b/resources/commands/output_device/next_device.lua @@ -0,0 +1,22 @@ +local lang = jarvis.context.language +local helper = jarvis.context.command_path .. "\\_audio_devices.ps1" +local cmd = string.format( + 'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action next', + helper +) + +local res = jarvis.system.exec(cmd) +if not res.success then + jarvis.log("error", "next device failed: " .. tostring(res.stderr)) + jarvis.audio.play_error() + return { chain = false } +end + +local out = (res.stdout or ""):gsub("[\r\n]+$", "") +local name = out:match("^OK\t(.+)$") or out + +local title = lang == "ru" and "Аудио переключено" or "Audio switched" +jarvis.system.notify(title, name) +jarvis.log("info", "audio switched to: " .. name) +jarvis.audio.play_ok() +return { chain = false } diff --git a/resources/commands/volume/_volume_helper.ps1 b/resources/commands/volume/_volume_helper.ps1 new file mode 100644 index 0000000..3cc0161 --- /dev/null +++ b/resources/commands/volume/_volume_helper.ps1 @@ -0,0 +1,31 @@ +param( + [Parameter(Mandatory=$true)] + [ValidateSet("up","down","mute","max")] + [string]$Action, + + [int]$Times = 1 +) + +Add-Type -Name VolumeKey -Namespace Win32 -MemberDefinition @' +[DllImport("user32.dll")] +public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, System.UIntPtr dwExtraInfo); +'@ + +$KEY_UP = 0xAF +$KEY_DOWN = 0xAE +$KEY_MUTE = 0xAD + +$vk = switch ($Action) { + "up" { $KEY_UP } + "down" { $KEY_DOWN } + "mute" { $KEY_MUTE } + "max" { $KEY_UP } +} + +$count = if ($Action -eq "max") { 50 } else { $Times } + +for ($i = 0; $i -lt $count; $i++) { + [Win32.VolumeKey]::keybd_event($vk, 0, 0, [UIntPtr]::Zero) + [Win32.VolumeKey]::keybd_event($vk, 0, 2, [UIntPtr]::Zero) + Start-Sleep -Milliseconds 25 +} diff --git a/resources/commands/volume/command.toml b/resources/commands/volume/command.toml new file mode 100644 index 0000000..288af96 --- /dev/null +++ b/resources/commands/volume/command.toml @@ -0,0 +1,106 @@ +[[commands]] +id = "volume_up" +type = "lua" +script = "volume_up.lua" +sandbox = "full" +timeout = 3000 + +[commands.phrases] +ru = [ + "громче", + "сделай громче", + "прибавь звук", + "увеличь громкость", + "погромче", +] +en = [ + "louder", + "volume up", + "increase volume", + "turn it up", +] +ua = [ + "голосніше", + "зроби голосніше", + "збільш гучність", +] + + +[[commands]] +id = "volume_down" +type = "lua" +script = "volume_down.lua" +sandbox = "full" +timeout = 3000 + +[commands.phrases] +ru = [ + "тише", + "сделай тише", + "убавь звук", + "уменьши громкость", + "потише", +] +en = [ + "quieter", + "volume down", + "decrease volume", + "turn it down", +] +ua = [ + "тихіше", + "зроби тихіше", + "зменш гучність", +] + + +[[commands]] +id = "volume_mute" +type = "lua" +script = "volume_mute.lua" +sandbox = "full" +timeout = 3000 + +[commands.phrases] +ru = [ + "выключи звук", + "заткнись", + "тишина", + "приглуши звук", + "отключи звук", +] +en = [ + "mute", + "silence", + "shut up", + "be quiet", +] +ua = [ + "вимкни звук", + "тиша", + "стихни", +] + + +[[commands]] +id = "volume_max" +type = "lua" +script = "volume_max.lua" +sandbox = "full" +timeout = 3000 + +[commands.phrases] +ru = [ + "максимальная громкость", + "звук на максимум", + "на полную", +] +en = [ + "max volume", + "full volume", + "maximum", +] +ua = [ + "максимальна гучність", + "звук на максимум", +] diff --git a/resources/commands/volume/volume_down.lua b/resources/commands/volume/volume_down.lua new file mode 100644 index 0000000..db0f7f7 --- /dev/null +++ b/resources/commands/volume/volume_down.lua @@ -0,0 +1,16 @@ +local helper = jarvis.context.command_path .. "\\_volume_helper.ps1" +local cmd = string.format( + 'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action down -Times 5', + helper +) + +local res = jarvis.system.exec(cmd) +if res.success then + jarvis.log("info", "volume down") + jarvis.audio.play_ok() +else + jarvis.log("error", "volume down failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr)) + jarvis.audio.play_error() +end + +return { chain = false } diff --git a/resources/commands/volume/volume_max.lua b/resources/commands/volume/volume_max.lua new file mode 100644 index 0000000..7935502 --- /dev/null +++ b/resources/commands/volume/volume_max.lua @@ -0,0 +1,16 @@ +local helper = jarvis.context.command_path .. "\\_volume_helper.ps1" +local cmd = string.format( + 'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action max', + helper +) + +local res = jarvis.system.exec(cmd) +if res.success then + jarvis.log("info", "volume max") + jarvis.audio.play_ok() +else + jarvis.log("error", "volume max failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr)) + jarvis.audio.play_error() +end + +return { chain = false } diff --git a/resources/commands/volume/volume_mute.lua b/resources/commands/volume/volume_mute.lua new file mode 100644 index 0000000..bb29bdb --- /dev/null +++ b/resources/commands/volume/volume_mute.lua @@ -0,0 +1,16 @@ +local helper = jarvis.context.command_path .. "\\_volume_helper.ps1" +local cmd = string.format( + 'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action mute', + helper +) + +local res = jarvis.system.exec(cmd) +if res.success then + jarvis.log("info", "mute toggled") + jarvis.audio.play_ok() +else + jarvis.log("error", "mute failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr)) + jarvis.audio.play_error() +end + +return { chain = false } diff --git a/resources/commands/volume/volume_up.lua b/resources/commands/volume/volume_up.lua new file mode 100644 index 0000000..0561954 --- /dev/null +++ b/resources/commands/volume/volume_up.lua @@ -0,0 +1,16 @@ +local helper = jarvis.context.command_path .. "\\_volume_helper.ps1" +local cmd = string.format( + 'powershell -NoProfile -ExecutionPolicy Bypass -File "%s" -Action up -Times 5', + helper +) + +local res = jarvis.system.exec(cmd) +if res.success then + jarvis.log("info", "volume up") + jarvis.audio.play_ok() +else + jarvis.log("error", "volume up failed: code=" .. tostring(res.code) .. " stderr=" .. tostring(res.stderr)) + jarvis.audio.play_error() +end + +return { chain = false }