]> gitweb.ps.run Git - autorec/blobdiff - src/main.cpp
start obs manually
[autorec] / src / main.cpp
index 73661042121148a8461e966a4b740bb6d9b36c8c..5e6eba365aedde9753b432083333e85dbe143258 100644 (file)
@@ -8,6 +8,10 @@
 #define LAY_IMPLEMENTATION\r
 #include "layout.h"\r
 \r
+#include <fstream>\r
+#include <vector>\r
+#include <string>\r
+\r
 #include <Psapi.h>\r
 #include <stdbool.h>\r
 #include <stdio.h>\r
 #include <windows.h>\r
 #include <shlwapi.h>\r
 \r
+bool recording = false;\r
+HANDLE process = NULL;\r
+HWND hwnd;\r
+HINSTANCE hInstance;\r
+HICON icon_white, icon_green, icon_red;\r
+\r
+std::vector<std::string> gameExes;\r
+\r
+\r
+NOTIFYICONDATAA niData = { 0 };\r
+const UINT ICON_MSG = WM_APP+1;\r
+void\r
+ShowNotificationIcon()\r
+{\r
+  Shell_NotifyIconA(NIM_ADD, &niData);\r
+  Shell_NotifyIconA(NIM_SETVERSION, &niData);\r
+}\r
+\r
+void\r
+HideNotificationIcon()\r
+{\r
+  Shell_NotifyIconA(NIM_DELETE, &niData);\r
+}\r
+\r
+void changeIcon(HWND hwnd, HICON icon)\r
+{\r
+  niData.hIcon = icon;\r
+  if (! IsWindowVisible(hwnd))\r
+    Shell_NotifyIconA(NIM_MODIFY, &niData);\r
+  SendMessage(hwnd, WM_SETICON, 0, (LPARAM)icon);\r
+  SendMessage(hwnd, WM_SETICON, 1, (LPARAM)icon);\r
+}\r
+\r
+\r
+\r
 void\r
 startRecording()\r
 {\r
   ws::sendRequest("StartRecord");\r
+  changeIcon(hwnd, icon_green);\r
 }\r
 \r
 void\r
 stopRecording()\r
 {\r
   ws::sendRequest("StopRecord");\r
+  changeIcon(hwnd, icon_red);\r
 }\r
 \r
 bool\r
@@ -77,26 +118,143 @@ checkForegroundProcess(std::string exeName)
   HWND fgHwnd = GetForegroundWindow();\r
   HANDLE fgHandle = getHwndProcess(fgHwnd);\r
 \r
-  char filename[1024];\r
-  int len = GetModuleFileNameExA(fgHandle, NULL, filename, 1024);\r
+  char filename[MAX_PATH];\r
+  int len = GetModuleFileNameExA(fgHandle, NULL, filename, MAX_PATH);\r
+\r
+  if (strcmp(filename, exeName.c_str()) == 0)\r
+    return true;\r
+\r
   PathStripPathA(filename);\r
 \r
   return strcmp(filename, exeName.c_str()) == 0;\r
 }\r
 \r
-bool recording = false;\r
-HANDLE process = NULL;\r
+void ReadGameExes()\r
+{\r
+  std::ifstream ifs("games.txt");\r
+\r
+  gameExes.clear();\r
+\r
+  while (ifs) {\r
+    std::string str;\r
+    std::getline(ifs, str);\r
+    if (! str.empty())\r
+      gameExes.push_back(str);\r
+  }\r
 \r
-// int WINAPI\r
-// WinMain(HINSTANCE hInstance,\r
-//         HINSTANCE hPrevInstance,\r
-//         LPSTR lpCmdLine,\r
-//         int nCmdShow)\r
-int main(int argc, char **argv)\r
+  ifs.close();\r
+}\r
+\r
+void WriteGameExes()\r
 {\r
+  std::ofstream ofs("games.txt", std::ios::trunc);\r
 \r
-  //win::Window window("Title", "MyWindowClass", hInstance);\r
-  win::Window window("Title", "MyWindowClass", GetModuleHandle(0));\r
+  for (const auto &exe : gameExes)\r
+  {\r
+    ofs.write(exe.c_str(), exe.size());\r
+    ofs.write("\n", 1);\r
+  }\r
+\r
+  ofs.close();\r
+}\r
+\r
+PROCESS_INFORMATION StartOBS()\r
+{\r
+  // delete .sentinel folder to stop obs from displaying\r
+  // error message on startup\r
+  system("del %appdata%\\obs-studio\\.sentinel /Q");\r
+\r
+  PROCESS_INFORMATION pi;\r
+  STARTUPINFOA sui;\r
+  GetStartupInfoA(&sui);\r
+  CreateProcessA(nullptr, "C:\\Program Files\\obs-studio\\bin\\64bit\\obs64.exe",\r
+    nullptr, nullptr, false, NORMAL_PRIORITY_CLASS, nullptr, "C:\\Program Files\\obs-studio\\bin\\64bit", &sui, &pi);\r
+  return pi;\r
+}\r
+\r
+void StopOBS(PROCESS_INFORMATION &pi)\r
+{\r
+  EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {\r
+    PROCESS_INFORMATION *pi = (PROCESS_INFORMATION*)lParam;\r
+\r
+    DWORD pid, tid;\r
+    tid = GetWindowThreadProcessId(hwnd, &pid);\r
+    if (tid == pi->dwThreadId && pid == pi->dwProcessId) {\r
+\r
+      char title[1024]; GetWindowTextA(hwnd, title, 1024);\r
+\r
+      if (strncmp(title, "OBS", 3) == 0) {\r
+        PostMessage(hwnd, WM_CLOSE, 0, 0);\r
+        return FALSE; \r
+      }\r
+    }\r
+    return TRUE;\r
+  }, (LPARAM)&pi);\r
+}\r
+\r
+/*\r
+TODO:\r
+  - Disconnect while recording\r
+*/\r
+\r
+\r
+\r
+int WINAPI\r
+WinMain(HINSTANCE hInstance,\r
+        HINSTANCE hPrevInstance,\r
+        LPSTR lpCmdLine,\r
+        int nCmdShow)\r
+//int main(int argc, char **argv)\r
+{\r
+  hInstance = GetModuleHandle(0);\r
+\r
+  icon_white = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON_WHITE));\r
+  icon_green = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON_GREEN));\r
+  icon_red = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_ICON_RED));\r
+\r
+  win::Window window("Title", "MyWindowClass", hInstance);\r
+  hwnd = window.hwnd;\r
+\r
+  niData.cbSize = sizeof(niData);\r
+  niData.uID = 12345;\r
+  niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;\r
+  niData.hIcon = icon_white;\r
+  niData.hWnd = window.hwnd;\r
+  niData.uCallbackMessage = ICON_MSG;\r
+  niData.uVersion = NOTIFYICON_VERSION_4;\r
+\r
+  PROCESS_INFORMATION pi_obs = StartOBS();\r
+\r
+  window.handlers[WM_SIZE].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
+    if (wParam == SIZE_MINIMIZED) {\r
+      ShowNotificationIcon();\r
+      ShowWindow(hwnd, false);\r
+    }\r
+  });\r
+  window.handlers[WM_DESTROY].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
+    HideNotificationIcon();\r
+  });  \r
+  window.handlers[ICON_MSG].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
+    if (LOWORD(lParam) == NIN_SELECT) {\r
+      HideNotificationIcon();\r
+      ShowWindow(hwnd, true);\r
+      SetForegroundWindow(hwnd);\r
+      SetActiveWindow(hwnd);\r
+    }\r
+  });\r
+  window.handlers[WM_GETMINMAXINFO].push_back([](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
+    MINMAXINFO *mmInfo = (MINMAXINFO*)lParam;\r
+    mmInfo->ptMinTrackSize.x = 400;\r
+    mmInfo->ptMinTrackSize.y = 200;\r
+  });\r
+  window.handlers[WM_QUERYENDSESSION].push_back([&pi_obs](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
+    StopOBS(pi_obs);\r
+  });  window.handlers[WM_ENDSESSION].push_back([&pi_obs](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
+    StopOBS(pi_obs);\r
+  });\r
+  window.handlers[WM_CLOSE].push_back([&pi_obs](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {\r
+    StopOBS(pi_obs);\r
+  });\r
 \r
   lay_context *ctx = &window.ctx;\r
   lay_id root = window.lId;\r
@@ -111,18 +269,24 @@ int main(int argc, char **argv)
 \r
   win::Button btnConnect(&window, "Connect", row1, 100, 25, 0, 0);\r
   btnConnect.onClick([&]() {\r
-    ws::connect("ws://127.0.0.1:4444");\r
+    if (! ws::isConnected)\r
+      ws::connect("ws://127.0.0.1:4455");\r
   });\r
 \r
   win::ListBox lstActiveProcesses(&window, row2, 0, 0, 0, LAY_FILL);\r
   \r
   lay_id col1 = win::createLayId(&window.ctx, row2, 80, 0, LAY_COLUMN, LAY_VCENTER);\r
+  lstActiveProcesses.addStyle(WS_VSCROLL);\r
+\r
   lay_set_margins_ltrb(ctx, col1, 5, 0, 5, 0);\r
 \r
   win::ListBox lstMonitoredProcesses(&window, row2, 0, 0, 0, LAY_FILL);\r
-  lstActiveProcesses.addStyle(WS_VSCROLL);\r
   lstMonitoredProcesses.addStyle(WS_VSCROLL);\r
 \r
+  ReadGameExes();\r
+  for (const auto &exe : gameExes)\r
+    lstMonitoredProcesses.addString(exe);\r
+\r
   win::Button btnUpdateWindows(&window, "Update", col1, 85, 25, 0, 0);\r
   win::Button btnStartMonitoringName(&window, "Exe name >>", col1, 85, 25, 0, 0);\r
   win::Button btnStartMonitoringPath(&window, "Full path >>", col1, 85, 25, 0, 0);\r
@@ -150,12 +314,19 @@ int main(int argc, char **argv)
 \r
     std::string selStr = lstActiveProcesses.getText(sel);\r
     \r
-    char *filename = new char[selStr.size()];\r
+    char *filename = new char[selStr.size()+1];\r
     std::memcpy(filename, selStr.c_str(), selStr.size());\r
+    filename[selStr.size()] = '\0';\r
     PathStripPathA(filename);\r
 \r
-    if (lstMonitoredProcesses.findString(std::string(filename)) == LB_ERR)\r
-      lstMonitoredProcesses.addString(std::string(filename));\r
+    std::string filenameStr(filename);\r
+\r
+    if (lstMonitoredProcesses.findString(filenameStr) == LB_ERR)\r
+    {\r
+      lstMonitoredProcesses.addString(filenameStr);\r
+      gameExes.push_back(filenameStr);\r
+      WriteGameExes();\r
+    }\r
 \r
     delete[] filename;\r
   });\r
@@ -164,24 +335,47 @@ int main(int argc, char **argv)
     if (sel < 0) return;\r
     std::string selStr = lstActiveProcesses.getText(sel);\r
     if (lstMonitoredProcesses.findString(selStr) == LB_ERR)\r
-    lstMonitoredProcesses.addString(selStr);\r
+    {\r
+      lstMonitoredProcesses.addString(selStr);\r
+      gameExes.push_back(selStr);\r
+      WriteGameExes();  \r
+    }\r
   });\r
   btnStopMonitoring.onClick([&]() {\r
     int sel = lstMonitoredProcesses.getSelectedIndex();\r
     if (sel < 0) return;\r
     lstMonitoredProcesses.remove(sel);\r
+    gameExes.erase(gameExes.begin() + sel);\r
+    WriteGameExes();\r
   });\r
 \r
   window.show();\r
-\r
+  window.setDefaultFont();\r
+\r
+  ws::onConnect = [&]() {\r
+    changeIcon(window.hwnd, icon_red);\r
+    btnConnect.setActive(false);\r
+  };\r
+  ws::onClose = [&]() {\r
+    changeIcon(window.hwnd, icon_white);\r
+    btnConnect.setActive(true);\r
+  };\r
+  ws::onError = ws::onClose;\r
   ws::init();\r
 \r
-  SetTimer(window.hwnd, 10123, 100, [](HWND, UINT, UINT_PTR, DWORD) {\r
+  window.setTimer(1000, [&btnConnect]() {\r
+    if (! ws::isConnected)\r
+      ws::connect("ws://127.0.0.1:4455");\r
+  });\r
+\r
+  window.setTimer(100, []() {\r
     if (!recording) {\r
-      if (checkForegroundProcess("League of Legends.exe")) {\r
-        recording = true;\r
-        process = getHwndProcess(GetForegroundWindow());\r
-        startRecording();\r
+      for (auto exe : gameExes) {\r
+        if (checkForegroundProcess(exe)) {\r
+          recording = true;\r
+          process = getHwndProcess(GetForegroundWindow());\r
+          startRecording();\r
+        } \r
       }\r
     } else {\r
       if (!checkProcessRunning(process)) {\r
@@ -195,4 +389,6 @@ int main(int argc, char **argv)
   while (window.update()) {\r
     ws::update();\r
   }\r
+\r
+  return 0;\r
 }\r