From 5d0979480ff50390b3883795ec2093e0d3d6193b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Mon, 22 Aug 2022 22:22:29 +0200 Subject: Open episodes without Prolog. --- c/ext.cpp | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 c/ext.cpp (limited to 'c/ext.cpp') diff --git a/c/ext.cpp b/c/ext.cpp new file mode 100644 index 0000000..f485dce --- /dev/null +++ b/c/ext.cpp @@ -0,0 +1,132 @@ +#include +#include +#include + +#include "data.h" + +extern CfgA& g_cfg; +extern FileView g_fvElv; +extern FileView g_fvDlv; + +void OpenOnline(int iEp) +{ + wchar_t url[sizeof(g_cfg.url)+4]; + Swprintf(url, L"%s%d", g_cfg.url, iEp); + INT_PTR r = reinterpret_cast( + ShellExecute(nullptr, L"open", url, nullptr, nullptr, SW_SHOWNORMAL)); + if (r <= 32) + throw Win32Error(); +} + +void OpenWiki(int iEp) +{ + const DlvDataA& d = g_fvDlv.At(iEp-1); + wchar_t url[sizeof(d.wiki)+35]; + Swprintf(url, L"https://www.detectiveconanworld.com%s", d.wiki); + INT_PTR r = reinterpret_cast( + ShellExecute(nullptr, L"open", url, nullptr, nullptr, SW_SHOWNORMAL)); + if (r <= 32) + throw Win32Error(); +} + +static inline bool MatchFileName(wchar_t (&file)[MAX_PATH], const wchar_t* const siEp) noexcept +{ + /* This is a hand-written parser that matches file names of + * the type "Detective Conan - 010.mkv". */ + + wchar_t* f = file; + + /* Match Detective Conan prefix. */ + if (*f != L'D' && *f != L'd') + return false; + f++; + + if (wcsncmp(f, L"etective", 8) != 0) + return false; + f += 8; + + if (*f != L' ' && *f != L'_' && *f != L'-') + return false; + f++; + + if (*f != L'C' && *f != L'c') + return false; + f++; + + if (wcsncmp(f, L"onan", 4) != 0) + return false; + f += 4; + + /* Match garbage before episode number. */ + while (*f == L' ' || *f == L'_' || *f == L'-' || *f == L'0') + f++; + + /* Match episode number. */ + size_t lenEp = wcslen(siEp); + if (wcsncmp(f, siEp, lenEp) != 0) + return false; + f += lenEp; + + if (isdigit(*f)) + return false; + + return true; +} + +static bool FindMatchingFile(wchar_t (&file)[MAX_PATH], const wchar_t* const root, + const wchar_t* const siEp, const int level = 0) +{ + /* Don't recurse too much. */ + if (level > 3) + return false; + + wchar_t pat[MAX_PATH]; + Swprintf(pat, L"%s\\*", root); + + WIN32_FIND_DATA fdata; + HANDLE hf = FindFirstFile(pat, &fdata); + if (hf == INVALID_HANDLE_VALUE) + throw Win32Error().what(); + + do { + if (fdata.cFileName[0] == L'.') + continue; + if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + /* Recurse into directory. */ + wchar_t root2[MAX_PATH]; + Swprintf(root2, L"%s\\%s", root, fdata.cFileName); + try { + if (FindMatchingFile(file, root2, siEp, level+1)) + return true; + } catch (...) { + FindClose(hf); + throw; + } + } + else /* Try to match file name. */ + if (MatchFileName(fdata.cFileName, siEp)) { + Swprintf(file, L"%s\\%s", root, fdata.cFileName); + return true; + } + } while (FindNextFile(hf, &fdata)); + + DWORD e = GetLastError(); + FindClose(hf); + if (e != ERROR_NO_MORE_FILES) + throw Win32Error(e); + + return false; +} + +bool OpenLocally(int iEp) +{ + wchar_t file[MAX_PATH]; + if (FindMatchingFile(file, g_cfg.root, g_fvElv.At(iEp-1).siEp)) { + INT_PTR r = reinterpret_cast( + ShellExecute(nullptr, L"open", file, nullptr, nullptr, SW_SHOWNORMAL)); + if (r <= 32) + throw Win32Error(); + return true; + } else + return false; +} -- cgit v1.2.3