mirror of
https://github.com/HolographicHat/Yae.git
synced 2025-12-06 22:52:49 +08:00
native addon
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ app*.exe
|
||||
export*.json
|
||||
secret.js
|
||||
package-lock.json
|
||||
native.node
|
||||
|
||||
2
native.d.ts
vendored
Normal file
2
native.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export function selectGameExecutable(): string
|
||||
export function checkGameIsRunning(processName: string): boolean
|
||||
5
native/.gitignore
vendored
Normal file
5
native/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
CMakeLists.txt
|
||||
.idea
|
||||
cmake-build-debug
|
||||
node_modules
|
||||
build
|
||||
22
native/binding.gyp
Normal file
22
native/binding.gyp
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "native",
|
||||
"sources": [
|
||||
"main.cc",
|
||||
"utils.cc",
|
||||
"utils.h",
|
||||
"define.h"
|
||||
],
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"AdditionalOptions": [
|
||||
"-std:c++latest",
|
||||
"-DUNICODE",
|
||||
"-sdl"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
26
native/define.h
Normal file
26
native/define.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <node_api.h>
|
||||
|
||||
using std::string, std::wstring, std::cout, std::endl;
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned long long ull;
|
||||
|
||||
typedef napi_env Env;
|
||||
typedef napi_value Value;
|
||||
typedef napi_status Status;
|
||||
typedef napi_callback Callback;
|
||||
typedef napi_callback_info CallbackInfo;
|
||||
|
||||
#define GetBoolean napi_get_boolean
|
||||
#define ThrowError napi_throw_error
|
||||
#define GetUTF8String napi_get_value_string_utf8
|
||||
#define CreateFunction napi_create_function
|
||||
#define GetCallbackInfo napi_get_cb_info
|
||||
#define CreateUTF8String napi_create_string_utf8
|
||||
#define SetNamedProperty napi_set_named_property
|
||||
58
native/main.cc
Normal file
58
native/main.cc
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <string>
|
||||
#include "utils.h"
|
||||
#include "define.h"
|
||||
|
||||
namespace native {
|
||||
|
||||
Value checkGameIsRunning(Env env, CallbackInfo info) {
|
||||
ull argc = 0;
|
||||
Value args[1];
|
||||
if (GetCallbackInfo(env, info, &argc, args, nullptr, nullptr) != napi_ok) {
|
||||
return nullptr;
|
||||
}
|
||||
char nameBuffer[256];
|
||||
GetUTF8String(env, args[0], (char *) &nameBuffer, sizeof(nameBuffer), nullptr);
|
||||
wstring pn = StringToWString(nameBuffer);
|
||||
bool isRunning = false;
|
||||
PROCESSENTRY32 entry;
|
||||
entry.dwSize = sizeof(entry);
|
||||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
|
||||
if (Process32First(snapshot, &entry) == TRUE) {
|
||||
while (Process32Next(snapshot, &entry) == TRUE) {
|
||||
if (wstring(entry.szExeFile) == pn) {
|
||||
isRunning = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
Value ret;
|
||||
GetBoolean(env, isRunning, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Value selectGameExecutable(Env env, CallbackInfo args) {
|
||||
Value path;
|
||||
LSTATUS retcode = OpenFile(env, path);
|
||||
if (retcode != ERROR_SUCCESS) {
|
||||
SetLastError(retcode);
|
||||
return nullptr;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
Value init(Env env, Value exports) {
|
||||
EnablePrivilege(L"SeDebugPrivilege");
|
||||
if (RegisterFunction(env, exports, checkGameIsRunning, "checkGameIsRunning") != napi_ok) {
|
||||
ThrowError(env, nullptr, "Failed to register checkGameIsRunning");
|
||||
return nullptr;
|
||||
}
|
||||
if (RegisterFunction(env, exports, selectGameExecutable, "selectGameExecutable") != napi_ok) {
|
||||
ThrowError(env, nullptr, "Failed to register selectGameExecutable");
|
||||
return nullptr;
|
||||
}
|
||||
return exports;
|
||||
}
|
||||
|
||||
NAPI_MODULE(NODE_GYP_MODULE_NAME, init)
|
||||
|
||||
}
|
||||
12
native/package.json
Normal file
12
native/package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "genshin-export-native",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"build": "node-gyp rebuild && copy .\\build\\Release\\native.node ..\\genshin-export\\"
|
||||
},
|
||||
"gypfile": true,
|
||||
"devDependencies": {
|
||||
"node-gyp": "^9.0.0"
|
||||
}
|
||||
}
|
||||
83
native/utils.cc
Normal file
83
native/utils.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "utils.h"
|
||||
#include "define.h"
|
||||
|
||||
wstring StringToWString(const string &src) {
|
||||
wstring result;
|
||||
int len = MultiByteToWideChar(CP_ACP, 0, src.c_str(), src.size(), nullptr, 0); // NOLINT(cppcoreguidelines-narrowing-conversions)
|
||||
auto *buffer = new WCHAR[len + 1];
|
||||
MultiByteToWideChar(CP_ACP, 0, src.c_str(), src.size(), buffer, len); // NOLINT(cppcoreguidelines-narrowing-conversions)
|
||||
buffer[len] = '\0';
|
||||
result.append(buffer);
|
||||
delete[] buffer;
|
||||
return result;
|
||||
}
|
||||
|
||||
string WStringToString(const wstring &src) {
|
||||
string result;
|
||||
int len = WideCharToMultiByte(CP_ACP, 0, src.c_str(), src.size(), nullptr, 0, nullptr, nullptr); // NOLINT(cppcoreguidelines-narrowing-conversions)
|
||||
char *buffer = new char[len + 1];
|
||||
WideCharToMultiByte(CP_ACP, 0, src.c_str(), src.size(), buffer, len, nullptr, nullptr); // NOLINT(cppcoreguidelines-narrowing-conversions)
|
||||
buffer[len] = '\0';
|
||||
result.append(buffer);
|
||||
delete[] buffer;
|
||||
return result;
|
||||
}
|
||||
|
||||
LSTATUS OpenFile(Env env, Value &result, HWND parent) {
|
||||
OPENFILENAME open;
|
||||
ZeroMemory(&open, sizeof(open));
|
||||
WCHAR file[32768];
|
||||
file[0]=L'\0';
|
||||
open.Flags = OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_PATHMUSTEXIST | OFN_EXPLORER;
|
||||
open.hwndOwner = parent;
|
||||
open.nMaxFile = 32768;
|
||||
open.lpstrFile = file;
|
||||
open.lpstrTitle = L"选择原神主程序";
|
||||
open.lpstrFilter = L"国服/国际服主程序 (YuanShen/GenshinImpact.exe)\0YuanShen.exe;GenshinImpact.exe\0";
|
||||
open.lStructSize = sizeof(open);
|
||||
if(GetOpenFileName(&open)) {
|
||||
string s = WStringToString(file);
|
||||
if (CreateUTF8String(env, s.c_str(), NAPI_AUTO_LENGTH, &result) == napi_ok) {
|
||||
return ERROR_SUCCESS;
|
||||
} else {
|
||||
return ERROR_ERRORS_ENCOUNTERED;
|
||||
}
|
||||
} else {
|
||||
return (LSTATUS)CommDlgExtendedError();
|
||||
}
|
||||
}
|
||||
|
||||
Status RegisterFunction(Env env, Value exports, Callback cb, const string &name) {
|
||||
Value fn;
|
||||
Status status = CreateFunction(env, nullptr, 0, cb, nullptr, &fn);
|
||||
if (status != napi_ok) return status;
|
||||
status = SetNamedProperty(env, exports, name.c_str(), fn);
|
||||
if (status != napi_ok) return status;
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
BOOL EnablePrivilege(const wstring &name) {
|
||||
HANDLE hToken;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
|
||||
cout << "OpenProcessToken error: %lu\n" << GetLastError() << endl;
|
||||
return FALSE;
|
||||
}
|
||||
TOKEN_PRIVILEGES tp;
|
||||
ZeroMemory(&tp, sizeof(tp));
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
if (!LookupPrivilegeValue(nullptr, name.c_str(), &tp.Privileges[0].Luid)) {
|
||||
cout << "LookupPrivilegeValue error: %lu\n" << GetLastError() << endl;
|
||||
return FALSE;
|
||||
}
|
||||
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), nullptr, nullptr)) {
|
||||
cout << "AdjustTokenPrivileges error: %lu\n" << GetLastError() << endl;
|
||||
return FALSE;
|
||||
}
|
||||
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
|
||||
cout <<"The token does not have the specified privilege." << endl;
|
||||
return FALSE;
|
||||
}
|
||||
CloseHandle(hToken);
|
||||
return TRUE;
|
||||
}
|
||||
14
native/utils.h
Normal file
14
native/utils.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "define.h"
|
||||
|
||||
string WStringToString(const wstring &src);
|
||||
wstring StringToWString(const string &src);
|
||||
LSTATUS OpenFile(Env env, Value &result, HWND parent = GetConsoleWindow());
|
||||
Status RegisterFunction(Env env, Value exports, Callback cb, const string &name);
|
||||
BOOL EnablePrivilege(const wstring &name);
|
||||
|
||||
#ifndef GENSHIN_EXPORT_NATIVE_UTILS_H
|
||||
#define GENSHIN_EXPORT_NATIVE_UTILS_H
|
||||
|
||||
#endif //GENSHIN_EXPORT_NATIVE_UTILS_H
|
||||
Reference in New Issue
Block a user