int ga_crop_window(struct gaRect *rect, struct gaRect **prect) { char display[16], wndname[1024]; char *pdisplay, *pname; Display *d = NULL; int dw, dh, screen = 0; Window w = 0; // if(rect == NULL || prect == NULL) return -1; // if((pdisplay = ga_conf_readv("display", display, sizeof(display))) == NULL) { *prect = NULL; return 0; } if((pname = ga_conf_readv("find-window-name", wndname, sizeof(wndname))) == NULL) { *prect = NULL; return 0; } // if((d = XOpenDisplay(pdisplay)) == NULL) { ga_error("ga_crop_window: cannot open display %s\n", display); return -1; } screen = XDefaultScreen(d); dw = DisplayWidth(d, screen); dh = DisplayHeight(d, screen); if((w = FindWindowX(d, RootWindow(d, screen), pname)) == 0) { ga_error("FindWindowX failed for %s/%s\n", pdisplay, pname); XCloseDisplay(d); return -1; } if(GetClientRectX(d, screen, w, rect) < 0) { ga_error("GetClientRectX failed for %s/%s\n", pdisplay, pname); XCloseDisplay(d); return -1; } XRaiseWindow(d, w); XSetInputFocus(d, w, RevertToNone, CurrentTime); XCloseDisplay(d); // size check: multiples of 2? if((rect->right - rect->left + 1) % 2 != 0) rect->left--; if((rect->bottom - rect->top + 1) % 2 != 0) rect->top--; // window is all visible? if(rect->left < 0 || rect->top < 0 || rect->right >= dw || rect->bottom >= dh) { ga_error("Invalid window: (%d,%d)-(%d,%d) w=%d h=%d (screen dimension = %dx%d).\n", rect->left, rect->top, rect->right, rect->bottom, rect->right - rect->left + 1, rect->bottom - rect->top + 1, dw, dh); return -1; } // *prect = rect; return 1; }
int do_hook(char *hook_type, int hook_type_sz) { char *ptr, app_exe[1024], hook_method[1024]; int resolution[2]; // if(CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK) { ga_error("*** CoInitializeEx failed.\n"); } // if(ga_hook_init() < 0) return -1; // handle ga-hook specific configurations if((ptr = ga_conf_readv("game-exe", app_exe, sizeof(app_exe))) == NULL) { ga_error("*** no game executable specified.\n"); return -1; } if((ptr = ga_conf_readv("hook-type", hook_type, hook_type_sz)) == NULL) { ga_error("*** no hook type specified.\n"); return -1; } if((ptr = ga_conf_readv("hook-method", hook_method, sizeof(hook_method))) != NULL) { ga_error("*** hook method specified: %s\n", hook_method); } // ga_error("[start-hook] exe=%s; type=%s\n", app_exe, hook_type); // if(hook_input() < 0) return -1; // --- if(strcasecmp(hook_type, "sdl") == 0) { return hook_sdl12(hook_type, hook_method); } // d9? if(strcasecmp(hook_type, "d9") == 0) { return hook_d9(hook_type, hook_method); } // dxgi? if(strcasecmp(hook_type, "dxgi") == 0) { //if(strstr(hook_method, "GetDXGIFactoryAddress") != NULL) return hook_dxgi(hook_type, hook_method); } // d10? if(strcasecmp(hook_type, "d10") == 0) { return hook_d10(hook_type, hook_method); } // d10.1? if(strcasecmp(hook_type, "d10.1") == 0) { return hook_d10_1(hook_type, hook_method); } // d11? if(strcasecmp(hook_type, "d11") == 0) { return hook_d11(hook_type, hook_method); } // ga_error("Unsupported hook type (%s)\n", hook_type); return -1; }
//从config结构里找出key="logfile"对应的value,并打开 void ga_openlog() { char fn[1024]; FILE *fp; // if(ga_conf_readv("logfile", fn, sizeof(fn)) == NULL) return; if((fp = fopen(fn, "at")) != NULL) { fclose(fp); ga_logfile = strdup(fn); } // return; }
static int hook_sdl12(const char *hook_type, const char *hook_method) { HMODULE hMod; char audio_type[64] = ""; const char *sdlpath = getenv("LIBSDL_SO"); const char *def_sdlpath = "SDL.dll"; if(sdlpath == NULL) sdlpath = def_sdlpath; // if((hMod = GetModuleHandle(sdlpath)) == NULL) { if((hMod = LoadLibrary(sdlpath)) == NULL) { ga_error("Load %s failed.\n", sdlpath); return -1; } } if(ga_conf_readv("hook-audio", audio_type, sizeof(audio_type)) == NULL) audio_type[0] = '\0'; // //load_hook_function(hMod, t_SDL_Init, old_SDL_Init, "SDL_Init"); load_hook_function(hMod, t_SDL_Init, old_SDL_Init, "SDL_Init"); load_hook_function(hMod, t_SDL_SetVideoMode, old_SDL_SetVideoMode, "SDL_SetVideoMode"); load_hook_function(hMod, t_SDL_UpperBlit, old_SDL_UpperBlit, "SDL_UpperBlit"); // XXX: BlitSurface == UpperBlit load_hook_function(hMod, t_SDL_BlitSurface, old_SDL_BlitSurface, "SDL_UpperBlit"); load_hook_function(hMod, t_SDL_Flip, old_SDL_Flip, "SDL_Flip"); load_hook_function(hMod, t_SDL_UpdateRect, old_SDL_UpdateRect, "SDL_UpdateRect"); load_hook_function(hMod, t_SDL_UpdateRects, old_SDL_UpdateRects, "SDL_UpdateRects"); load_hook_function(hMod, t_SDL_GL_SwapBuffers, old_SDL_GL_SwapBuffers, "SDL_GL_SwapBuffers"); load_hook_function(hMod, t_SDL_PollEvent, old_SDL_PollEvent, "SDL_PollEvent"); load_hook_function(hMod, t_SDL_WaitEvent, old_SDL_WaitEvent, "SDL_WaitEvent"); load_hook_function(hMod, t_SDL_PeepEvents, old_SDL_PeepEvents, "SDL_PeepEvents"); load_hook_function(hMod, t_SDL_SetEventFilter, old_SDL_SetEventFilter, "SDL_SetEventFilter"); if(strcmp("sdlaudio", audio_type) == 0) { ///////////////////////////////////////// load_hook_function(hMod, t_SDL_OpenAudio, old_SDL_OpenAudio, "SDL_OpenAudio"); load_hook_function(hMod, t_SDL_PauseAudio, old_SDL_PauseAudio, "SDL_PauseAudio"); load_hook_function(hMod, t_SDL_CloseAudio, old_SDL_CloseAudio, "SDL_CloseAudio"); ga_error("hook: sdlaudio enabled.\n"); ///////////////////////////////////////// } // for internal use load_hook_function(hMod, t_SDL_CreateRGBSurface, old_SDL_CreateRGBSurface, "SDL_CreateRGBSurface"); load_hook_function(hMod, t_SDL_FreeSurface, old_SDL_FreeSurface, "SDL_FreeSurface"); load_hook_function(hMod, t_SDL_PushEvent, old_SDL_PushEvent, "SDL_PushEvent"); // #define SDL_DO_HOOK(name) \ DetourTransactionBegin(); \ DetourUpdateThread(GetCurrentThread()); \ DetourAttach(&(PVOID&)old_##name, hook_##name); \ DetourTransactionCommit(); //SDL_DO_HOOK(SDL_Init); SDL_DO_HOOK(SDL_SetVideoMode); SDL_DO_HOOK(SDL_UpperBlit); SDL_DO_HOOK(SDL_Flip); SDL_DO_HOOK(SDL_UpdateRect); SDL_DO_HOOK(SDL_UpdateRects); SDL_DO_HOOK(SDL_WaitEvent); SDL_DO_HOOK(SDL_PeepEvents); SDL_DO_HOOK(SDL_SetEventFilter); if(strcmp("sdlaudio", audio_type) == 0) { ///////////////////////////////////////// SDL_DO_HOOK(SDL_OpenAudio); SDL_DO_HOOK(SDL_PauseAudio); SDL_DO_HOOK(SDL_CloseAudio); ///////////////////////////////////////// } #if 1 SDL_DO_HOOK(SDL_GL_SwapBuffers); SDL_DO_HOOK(SDL_PollEvent); #else DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)old_SDL_GL_SwapBuffers, hook_SDL_GL_SwapBuffers); DetourTransactionCommit(); // DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)old_SDL_PollEvent, hook_SDL_PollEvent); DetourTransactionCommit(); #endif #undef SDL_DO_HOOK ga_error("hook_sdl12: done\n"); // return 0; }
int ga_crop_window(struct gaRect *rect, struct gaRect **prect) { char wndname[1024], wndclass[1024]; char *pname; char *pclass; int dw, dh, find_wnd_arg = 0; HWND hWnd; RECT client; POINT lt, rb; // if(rect == NULL || prect == NULL) return -1; // pname = ga_conf_readv("find-window-name", wndname, sizeof(wndname)); pclass = ga_conf_readv("find-window-class", wndclass, sizeof(wndclass)); // if(pname != NULL && *pname != '\0') find_wnd_arg++; if(pclass != NULL && *pclass != '\0') find_wnd_arg++; if(find_wnd_arg <= 0) { *prect = NULL; return 0; } // if((hWnd = FindWindow(pclass, pname)) == NULL) { ga_error("FindWindow failed for '%s/%s'\n", pclass ? pclass : "", pname ? pname : ""); return -1; } // GetWindowText(hWnd, wndname, sizeof(wndname)); dw = GetSystemMetrics(SM_CXSCREEN); dh = GetSystemMetrics(SM_CYSCREEN); // ga_error("Found window (0x%08x) :%s%s%s%s\n", hWnd, pclass ? " class=" : "", pclass ? pclass : "", pname ? " name=" : "", pname ? pname : ""); //设置子窗口置顶 if(SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW) == 0) { ga_error("SetWindowPos failed.\n"); return -1; } if(GetClientRect(hWnd, &client) == 0) { ga_error("GetClientRect failed.\n"); return -1; } if(SetForegroundWindow(hWnd) == 0) { ga_error("SetForegroundWindow failed.\n"); } // lt.x = client.left; lt.y = client.top; rb.x = client.right-1; rb.y = client.bottom-1; // if(ClientToScreen(hWnd, <) == 0 || ClientToScreen(hWnd, &rb) == 0) { ga_error("Map from client coordinate to screen coordinate failed.\n"); return -1; } // rect->left = lt.x; rect->top = lt.y; rect->right = rb.x; rect->bottom = rb.y; // size check: multiples of 2? if((rect->right - rect->left + 1) % 2 != 0) rect->left--; if((rect->bottom - rect->top + 1) % 2 != 0) rect->top--; // if(rect->left < 0 || rect->top < 0 || rect->right >= dw || rect->bottom >= dh) { ga_error("Invalid window: (%d,%d)-(%d,%d) w=%d h=%d (screen dimension = %dx%d).\n", rect->left, rect->top, rect->right, rect->bottom, rect->right - rect->left + 1, rect->bottom - rect->top + 1); return -1; } // *prect = rect; return 1; }