Game laggs after injecting my code - c++

I made .dll which I am injecting into game. It runs pixel detection after I press alt + s but the game laggs. Is there any possibility to fix it?
It detects red color, presses mouse3 and in-game it shoots but too slow and game is lagging.
I tried to remove Sleep() but it lag more. Any suggestions?
#include <windows.h>
#include <gdiplus.h>
const int SX = GetSystemMetrics(SM_CXSCREEN);
const int SY = GetSystemMetrics(SM_CYSCREEN);
const int SCREEN_X = (SX/2);
const int SCREEN_Y = (SY/2);
const COLORREF red=RGB(255, 0, 0);
const int Sound[]={SND_ALIAS_SYSTEMASTERISK,SND_ALIAS_SYSTEMEXCLAMATION};
const int State[]={MOUSEEVENTF_MIDDLEDOWN,MOUSEEVENTF_MIDDLEUP};
bool PixelCheck(HDC hdc)
{
time_t stop=GetTickCount()+50;
bool result=false;
while(GetTickCount()<stop) if(GetPixel(hdc,SCREEN_X,SCREEN_Y) == red) result=true;
Sleep(1);
return result;
}
DWORD WINAPI ThreadFunction(PVOID pvParam)
{
HDC hdc=GetDC(0);
bool shotbot=false,isdown=false;
INPUT ip;
ip.type=INPUT_MOUSE;
ip.mi.dx=0;
ip.mi.dy=0;
ip.mi.dwExtraInfo=0;
while(true)
{
if(GetAsyncKeyState(0xA4) && GetAsyncKeyState(0x53))
{
shotbot=!shotbot;
PlaySound((LPCSTR)Sound[shotbot],NULL,SND_ALIAS_ID);
}
Sleep(1);
if((shotbot&&PixelCheck(hdc))||isdown)
{
ip.mi.dwFlags=State[isdown];
SendInput(1,&ip,sizeof(INPUT));
isdown=!isdown;
}
}
ReleaseDC(0, hdc);
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
if(fdwReason==DLL_PROCESS_ATTACH) SetThreadPriority(CreateThread(0,0,ThreadFunction,0,0,NULL),THREAD_PRIORITY_NORMAL);
return TRUE;
}

You're doing nothing but call GetPixel() for 50 milliseconds. That's a 50 millisecond lag right there. What did you expect?
Removing the Sleep call just means you lag more often, and each time still for 50 milliseconds. That too is expected.

Some points:
1) Your while loop is tight and CPU intensive. If you have a CPU that supports it, put the __mm_pause intrinsic in there (::YieldProcessor()) or try ::SwitchToThread()
2) GetPixel is tremendously slow IIRC,, there may be a quicker way to read the pixel value from an HBITMAP

Related

How to stop C/C++ program from checking keyboard when not active / in focus

I'm getting use to the basics of game programming and design. I'm currently trying to practice with using the command line to render images for a platformer by looping the screen output. I just want to make a few simple projects, e.g clock, tetris, cellular automata(looking forward to Game of Life ¯\_(ツ)_/¯ ), etc before using any advanced libraries or going into something like Unity®.
I used the GetAsyncKeyState(VK_key) function I found from various online resources to control the player with the arrow keys. This works, in fact a little too well. It has the unintended effect of controlling the player even when the program is in the background/ not in focus/ inactive.
So how do I CONSTANTLY get keyboard button states/input ONLY while program is in focus?
I've looked for various solutions, one of which was the first answer
here.
It required me knowing the process id of the program, to which I tried variants of (I only used one at a time):
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdbool.h>
#ifdef _WIN32
#include <Windows.h>
#define SLEEP(x) Sleep(x) // takes milliseconds(ms)
#else
#include <unistd.h>
#define SLEEP(x) usleep(x * 1000) // takes microseconds(μs)
#endif
void printInColour(char str[], unsigned short colour) {
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hcon, colour);
printf("%s", str);
SetConsoleTextAttribute(hcon, 7); // Set back to default.
}
bool key_pressed(int key) {
return (GetAsyncKeyState(key) != 0);
}
bool IsForegroundProcess()
{
HWND hwnd = GetForegroundWindow();
if (hwnd == NULL) return false;
DWORD foregroundPid;
if (GetWindowThreadProcessId(hwnd, &foregroundPid) == 0) return false;
//return true;
//return (foregroundPid == GetProcessId( GetStdHandle(STD_OUTPUT_HANDLE)));
//return ( foregroundPid == getpid() );
//return (foregroundPid == GetCurrentProcessId());
//return (foregroundPid == GetProcessIdOfThread(GetStdHandle(STD_OUTPUT_HANDLE) ));
return (foregroundPid == GetThreadId( GetStdHandle(STD_OUTPUT_HANDLE)));
}
void main() {
// ...
while(isRunning) {
//...
if (IsForegroundProcess())
printInConsole(">> Currently Active\n", 10); // Debug in green
else
printInConsole(">> Return to focus\n", 12); // ...and red
if (key_pressed(VK_UP) != 0) {/*...*/} // jump, etc
SLEEP(1000);
}
}
I edited the code to remove the actual game. The fix I tried constantly fails saying it's out of focus. I'm open to any suggestions of how to get key pressed info(but only when program is in focus/active). Also, any tips for a newcomer into this daunting world of creating games will be vastly appreciated.
Use FindWindow() in combination with GetForegroundWindow() or GetFocus()
HWND hMyWindow = FindWindow(NULL, L"MyWindowName");
HWND hFocusWindow = GetForegroundWindow();
//May also use:
//HWND hFocusWindow = GetFocus();
if (hMyWindow == hFocusWindow)
{
//do stuff
}

D3D9 Hooking (EndScene + DrawIndexedPrimitive)

As none of you already know, I am quite fed up with DirectX at the moment. I have tried and tried, and no matter what I do, I cannot seem to get any hooks to work. I have scoured the web and studied hooks; I have combined bits of code together to scrap together my own hook; I have flat out plagiarized hooks to find out how they worked; I have even written a few from scratch. However, I cannot seem to get one to work. I'm trying to make a simple D3D mod-menu for CrossFire. What I have tried:
Hooking via VTable [had issues with getting a device pointer]
Hooking via pattern + mask scanning, etc and detours [unsure how to get a pattern, and cannot find one that works reliably for win10]
Creating a dummy device to get the addresses, etc, etc [caused an immediate shut-down of the game (detected)]
No matter what I do, the menu either flat out refuses to appear once programmed into the detoured EndScene, I get shut-down, I crash, or nothing happens.
Are there any good starter materials with sample code that I can learn from, as well as get this off the ground?
I already have the hack menu programmed, the variables set, the features programmed, the DllMain, the dependencies, you name it. All I need is to get a proper hook working - the only one I got to work had a weird bug where text drawing in EndScene & wall-hack in DrawIndexedPrimitive didn't work.
This is a large amount of code for a SO answer but here we go.
Get correct window
Create a dummy device
Get address of endscene from vtable
Do a standard x86 trampoline hook
Inside hook do whatever initialize stuff you need to
Get a copy of the correct device pointer
Draw stuff
call original function with correct device pointer
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
bool Hook(char* src, char* dst, int len)
{
if (len < 5) return false;
DWORD curProtection;
VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &curProtection);
memset(src, 0x90, len);
uintptr_t relativeAddress = (uintptr_t)(dst - src - 5);
*src = (char)0xE9;
*(uintptr_t*)(src + 1) = (uintptr_t)relativeAddress;
DWORD temp;
VirtualProtect(src, len, curProtection, &temp);
return true;
}
char* TrampHook(char* src, char* dst, unsigned int len)
{
if (len < 5) return 0;
// Create the gateway (len + 5 for the overwritten bytes + the jmp)
char* gateway = (char*)VirtualAlloc(0, len + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
// Put the bytes that will be overwritten in the gateway
memcpy(gateway, src, len);
// Get the gateway to destination addy
uintptr_t gateJmpAddy = (uintptr_t)(src - gateway - 5);
// Add the jmp opcode to the end of the gateway
*(gateway + len) = (char)0xE9;
// Add the address to the jmp
*(uintptr_t*)(gateway + len + 1) = gateJmpAddy;
// Place the hook at the destination
if (Hook(src, dst, len))
{
return gateway;
}
else return nullptr;
}
typedef HRESULT(APIENTRY* tEndScene)(LPDIRECT3DDEVICE9 pDevice);
static HWND window;
BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam)
{
DWORD wndProcId;
GetWindowThreadProcessId(handle, &wndProcId);
if (GetCurrentProcessId() != wndProcId)
return TRUE; // skip to next window
window = handle;
return FALSE; // window found abort search
}
HWND GetProcessWindow()
{
window = NULL;
EnumWindows(EnumWindowsCallback, NULL);
return window;
}
bool GetD3D9Device(void** pTable, size_t Size)
{
if (!pTable)
return false;
IDirect3D9* pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (!pD3D)
return false;
IDirect3DDevice9* pDummyDevice = NULL;
// options to create dummy device
D3DPRESENT_PARAMETERS d3dpp = {};
d3dpp.Windowed = false;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = GetProcessWindow();
HRESULT dummyDeviceCreated = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDummyDevice);
if (dummyDeviceCreated != S_OK)
{
// may fail in windowed fullscreen mode, trying again with windowed mode
d3dpp.Windowed = !d3dpp.Windowed;
dummyDeviceCreated = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3dpp.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDummyDevice);
if (dummyDeviceCreated != S_OK)
{
pD3D->Release();
return false;
}
}
memcpy(pTable, *reinterpret_cast<void***>(pDummyDevice), Size);
pDummyDevice->Release();
pD3D->Release();
return true;
}
void DrawFilledRect(int x, int y, int w, int h, D3DCOLOR color, IDirect3DDevice9* dev)
{
D3DRECT BarRect = { x, y, x + w, y + h };
dev->Clear(1, &BarRect, D3DCLEAR_TARGET | D3DCLEAR_TARGET, color, 0, 0);
}
bool bInit = false;
tEndScene oEndScene = nullptr;
LPDIRECT3DDEVICE9 pD3DDevice = nullptr;
void* d3d9Device[119];
HRESULT APIENTRY hkEndScene(LPDIRECT3DDEVICE9 pDevice)
{
if (bInit == false)
{
pD3DDevice = pDevice;
bInit = true;
}
//draw stuff here like so:
DrawFilledRect(200, 200, 200, 200, D3DCOLOR_ARGB(255, 255, 0, 0), pDevice);
return oEndScene(pDevice);
}
DWORD WINAPI Init(HMODULE hModule)
{
if (GetD3D9Device(d3d9Device, sizeof(d3d9Device)))
{
oEndScene = (tEndScene)TrampHook((char*)d3d9Device[42], (char*)hkEndScene, 7);
}
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)Init, hModule, 0, nullptr));
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Credits to me, Broihon, Solaire & 0xDEC0DE for this barebones d3d9 endscene hook

C++ - Change vertical pitch of your mouse

The Idea
I was wondering if it's possible to change the pitch of your mouse over the entire screen. To give an example: If you draw a perfect circle with your physical mouse on your table, your screen would draw an oval (with: width > height).
This could be useful if you e.g. used to have a customizable mouse that supported individual m_pitch settings but recently broke down and you can't afford a new one. You could use this program to virtualize those individual settings.
So I went to work and concocted this small program:
#include <windows.h>
#include <iostream>
#include <math.h>
using namespace std;
HHOOK hMouseHook;
bool prev_initialized = false;
bool real_input = true;
MOUSEHOOKSTRUCT prevMouseStruct;
double ratio = 0.5; //cursor should pitch 0.5x as fast as it normally would
double rest = 0;
LRESULT CALLBACK mouseProc (int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
if (pMouseStruct != NULL){
if(wParam == WM_MOUSEMOVE)
{
printf("Mouse position X = %d Mouse Position Y = %d\n", pMouseStruct->pt.x,pMouseStruct->pt.y);
if(prev_initialized && real_input){
int y_diff = prevMouseStruct.pt.y - pMouseStruct->pt.y;
if(y_diff != 0){
double ratiod_diff = ((double)y_diff) * ratio;
int rounded_diff = (int)round(ratiod_diff);
int newY = prevMouseStruct.pt.y - rounded_diff;
rest += ratiod_diff - rounded_diff;
if(rest > 1){
--rest;
++newY;
}else if(rest < -1){
++rest;
--newY;
}
real_input = false;
pMouseStruct->pt.y = newY;
SetCursorPos(pMouseStruct->pt.x, pMouseStruct->pt.y);
printf("New- Mouse position X = %d Mouse Position Y = %d\n", pMouseStruct->pt.x,newY);
}
}else if(!real_input){
real_input = true;
} else{
prevMouseStruct = *pMouseStruct;
prev_initialized = true;
}
}
}
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
int main()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, hInstance, NULL);
MSG message;
while (GetMessage(&message,NULL,0,0)) {
TranslateMessage( &message );
DispatchMessage( &message );
}
UnhookWindowsHookEx(hMouseHook);
return 0;
}
How?
This program registers all mousemovement-events on the screen and remembers 2 coordinates:
The previous mouse location; e.g.: POINT(100, 100)
The current mouse location; e.g.: POINT(120,150) -> the mouse moved 20px to the right and 50px down
Then, I calculate where I want the cursor to be with the ratio (and some other fancy precision stuff). E.g.: the cursor moves 50px down and the ratio is 0.5 -> the mouse only goes 25px down.
Lastly, I call SetMousePos() with the new y-value to move the cursor to my desired location. (Note: I also try to make sure that this function does not call mouseProc() again by using the boolean real_input as a flag).
The problem
I am running into the following problem: the cursor is not staying at its new y-position. After calling the setMousePos()-function, the mouse shifts to its new position for a split second and then instantly reverts back to its former position. This leaves a makeshift 'afterimage' of the mouse. In this GIF, I move the cursor from the top to the bottom. You can see that it leaves it's after-image that grows larger in distance when you move further away from your starting-position (the starting-position is the position of your mouse when the console opens).
Any feedback would be MUCH appreciated!

Multiple monitors and handles

Trying to run a for loop through physical monitors but the handles are really confusing me, I have pseudo code that runs along the lines of:
int tempCounter=0
for(counter = number of monitors;counter > 0;counter--){
RECT tempRECT;
HDC tempHDC;
Get resolution of DC handle (counter) -> tempRECT;
arrayList[tempCounter] = tempRECT;
Get virtual work area of DC handle (counter) -> tempRECT;
arrayList[tempCounter++] = tempRECT;
tempCounter++;
}
GetSystemMetrics(80) for the count of monitors, is this reliable enough to use, or any exceptions it might fail?
I know there is not much there, but looking on the MSDN just kept me going around in circles, that and I am not very competent at programming.
It can be as simple as this:
#include <Windows.h>
#include <stdio.h>
BOOL CALLBACK MonitorEnumProc(
HMONITOR hMonitor,
HDC hdcMonitor,
LPRECT lprcMonitor,
LPARAM dwData
)
{
printf("%dx%d\n", lprcMonitor->right, lprcMonitor->bottom);
}
int main(int argc, char*argv[]) {
EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);
}

C++ Pixels In Console Window

In C++ using Code::Blocks v10.05, how do I draw a single pixel on the console screen? Is this easy at all, or would it be easier to just draw a rectangle? How do I color it?
I'm sorry, but I just can't get any code from SOF, HF, or even cplusplus.com to work. This is for a Super Mario World figure on the screen. The game I think is 16-bit, and is for the SNES system. C::B says I need SDK for C::B. It says "afxwin.h" doesn't exist. Download maybe?
This is what I'm trying to make:
It depends on your OS. I suppose you are programming in a Windows platform, therefore you can use SetPixel but you have to use "windows.h" to get a console handle, so here an example for drawing the cos() function:
#include<windows.h>
#include<iostream>
#include <cmath>
using namespace std;
#define PI 3.14
int main()
{
//Get a console handle
HWND myconsole = GetConsoleWindow();
//Get a handle to device context
HDC mydc = GetDC(myconsole);
int pixel =0;
//Choose any color
COLORREF COLOR= RGB(255,255,255);
//Draw pixels
for(double i = 0; i < PI * 4; i += 0.05)
{
SetPixel(mydc,pixel,(int)(50+25*cos(i)),COLOR);
pixel+=1;
}
ReleaseDC(myconsole, mydc);
cin.ignore();
return 0;
}
You can also use some others libraries like: conio.h allegro.h sdl, etc.
If you're willing to have the image look blocky, you could take advantage of the block characters from the console code page.
█ = '\xDB' = U+2588 FULL BLOCK
▄ = '\xDC' = U+2584 LOWER HALF BLOCK
▀ = '\xDF' = U+2580 UPPER HALF BLOCK
and space
By using the half-blocks in combination with colored text, you can turn an 80×25 console window into an 80×50 16-color display. (This was the approach used by the QBasic version of Nibbles.)
Then, you just need to convert your image to the 16-color palette and a reasonably small size.
windows.h provides a function SetPixel() to print a pixel at specified location of a window. The general form of the function is
SetPixel(HDC hdc, int x, int y, COLORREF& color);
where, x and y are coordinates of pixel to be display and color is the color of pixel.
Important: to print the pixel in your machine with Code::blocks IDE, add a link library libgdi32.a (it is usually inside MinGW\lib ) in linker setting.
Console is a text device, so in general you don't write to individual pixels. You can create a special font and select it as a font for console, but it will be monochromatic. There are libraries which simplify writing console UI (e.g. Curses), but I believe that you also have more gamelike functionality in mind besides just showing a sprite.
if you want to write a game, I suggest taking a look at some of the graphics/game frameworks/libs, e.g. SDL
I have drawn the straight line using windows.h in code::blocks. I can't explain it in details, but I can provide you a code and procedure to compile it in code::blocks.
go to setting menu and select compiler and debugger.
Click on linker tab and add a link library libgdi32.a which is at C:\Program Files\CodeBlocks\MinGW\lib directory.
Now compile this program
#include <windows.h>
#include <cmath>
#define ROUND(a) ((int) (a + 0.5))
/* set window handle */
static HWND sHwnd;
static COLORREF redColor=RGB(255,0,0);
static COLORREF blueColor=RGB(0,0,255);
static COLORREF greenColor=RGB(0,255,0);
void SetWindowHandle(HWND hwnd){
sHwnd=hwnd;
}
/* SetPixel */
void setPixel(int x,int y,COLORREF& color=redColor){
if(sHwnd==NULL){
MessageBox(NULL,"sHwnd was not initialized !","Error",MB_OK|MB_ICONERROR);
exit(0);
}
HDC hdc=GetDC(sHwnd);
SetPixel(hdc,x,y,color);
ReleaseDC(sHwnd,hdc);
return;
// NEVERREACH //
}
void drawLineDDA(int xa, int ya, int xb, int yb){
int dx = xb - xa, dy = yb - ya, steps, k;
float xIncrement, yIncrement, x = xa, y = ya;
if(abs(dx) > abs(dy)) steps = abs(dx);
else steps = abs(dy);
xIncrement = dx / (float) steps;
yIncrement = dy / (float) steps;
setPixel(ROUND(x), ROUND(y));
for(int k = 0; k < steps; k++){
x += xIncrement;
y += yIncrement;
setPixel(x, y);
}
}
/* Window Procedure WndProc */
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
switch(message){
case WM_PAINT:
SetWindowHandle(hwnd);
drawLineDDA(10, 20, 250, 300);
break;
case WM_CLOSE: // FAIL THROUGH to call DefWindowProc
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break; // FAIL to call DefWindowProc //
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iCmdShow){
static TCHAR szAppName[] = TEXT("Straight Line");
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW|CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
// Register the window //
if(!RegisterClass(&wndclass)){
MessageBox(NULL,"Registering the class failled","Error",MB_OK|MB_ICONERROR);
exit(0);
}
// CreateWindow //
HWND hwnd=CreateWindow(szAppName,"DDA - Programming Techniques",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if(!hwnd){
MessageBox(NULL,"Window Creation Failed!","Error",MB_OK);
exit(0);
}
// ShowWindow and UpdateWindow //
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
// Message Loop //
MSG msg;
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
/* return no error to the operating system */
return 0;
}
In this program I have used DDA line drawing algorithm. Pixel drawing tasks is done by setPixel(ROUND(x), ROUND(y)) function.
This is windows programing which you can learn details here
To use in CodeBlocks I found this (you have to add a linker option -lgdi32):
//Code Blocks: Project Build Options Linker settings Othoer linker options: add -lgdi32
I forgot: You have to put this before including windows.h:
#define _WIN32_WINNT 0x0500
The whole cosine code again. Ready to compile:
//Code Blocks: Project Build Options Linker settings Othoer linker options: add -lgdi32
#define _WIN32_WINNT 0x0500
#include "windows.h"
#include <iostream>
#include <cmath>
using namespace std;
#define PI 3.14
int main(){
HWND myconsole = GetConsoleWindow();
HDC mydc = GetDC(myconsole);
int pixel =0;
COLORREF COLOR= RGB(255,255,255);
//Draw pixels
for(double i = 0; i < PI * 4; i += 0.05)
{
SetPixel(mydc,pixel,(int)(50+25*cos(i)),COLOR);
pixel+=1;
}
ReleaseDC(myconsole, mydc);
cin.ignore();
return 0;
}