Skip to content

Commit

Permalink
Using PostMessage
Browse files Browse the repository at this point in the history
Using PE Explorer, I found out that ETS2 does NOT use any DirectX dll's
in it's import tables. It instead uses Win32 API for input (e.g.
PostMessageW, SendMessageW, and keybd_event).  See
bethesirius#4 (comment)

Now that we know that ETS2 accepts postmessage, I am removing the
SendInput stuff and replacing it with PostMessage. Unfortunately it's
not working in-game, but Spy++ verifies that those inputs are being sent
to the game window. The simulated keys are identical to the real keys
with two exceptions: cRepeat is 0 when simulated, 1 when real, and
LPARAM is 0 when simulated, given another value when real.

FPS is unfortunately pretty bad, can't deal with this yet until input is
working. For now I'm leaving "go straight" to have no messages sent,
since it would keep spamming the keydown for A and D, causing lag.
  • Loading branch information
zappybiby committed Jan 31, 2017
1 parent 5010833 commit e1bc37e
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 109 deletions.
Binary file modified ets2_auto_driving.sdf
Binary file not shown.
3 changes: 3 additions & 0 deletions ets2_auto_driving.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal
Binary file modified ets2_auto_driving.v12.suo
Binary file not shown.
2 changes: 2 additions & 0 deletions ets2_auto_driving/ets2_auto_driving.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<Profile>true</Profile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
Expand All @@ -142,6 +143,7 @@
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>C:\opencv\opencv\build\include;C:\opencv\opencv\build\include\opencv2;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_calib3d310.lib;opencv_core310.lib;opencv_features2d310.lib;opencv_flann310.lib;opencv_highgui310.lib;opencv_imgcodecs310.lib;opencv_imgproc310.lib;opencv_ml310.lib;opencv_objdetect310.lib;opencv_photo310.lib;opencv_shape310.lib;opencv_stitching310.lib;opencv_superres310.lib;opencv_ts310.lib;opencv_video310.lib;opencv_videoio310.lib;opencv_videostab310.lib;opencv_viz310.lib;%(AdditionalDependencies)</AdditionalDependencies>
<Profile>true</Profile>
</Link>
<CudaCompile>
<Include>C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include;%(Include)</Include>
Expand Down
121 changes: 17 additions & 104 deletions ets2_auto_driving/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ int main() {
auto begin = chrono::high_resolution_clock::now();
// ETS2
HWND hWnd = FindWindow("prism3d", NULL); // This finds the game window and sets the source for hWnd
// NOTEPAD
// HWND hWnd = FindWindow("Photo_Light", NULL);
Mat image, outputImg; // Creates two Mats, image and outputImg. outputImg is used for showing what the program sees to user in a new window.
Mat image, outputImg;
hwnd2mat(hWnd).copyTo(image);
// Mat to GpuMat
// cuda::GpuMat imageGPU;
// imageGPU.upload(image);

medianBlur(image, image, 3);
// medianBlur(image, image, 3);
// bilateralFilter(imageGPU, imageGPU, 15, 80, 80);

int width = 0, height = 0;
Expand Down Expand Up @@ -71,11 +69,7 @@ int main() {
IPM ipm(Size(width, height), Size(width, height), origPoints, dstPoints);

// Process
// clock_t begin = clock();
ipm.applyHomography(image, outputImg);
// clock_t end = clock();
// double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
// printf("%.2f (ms)\r", 1000 * elapsed_secs);
// ipm.drawPoints(origPoints, image);

// imageGPU.download(image);
Expand Down Expand Up @@ -104,14 +98,6 @@ int main() {
imshow("Test", contours);
waitKey(1);
// cv::cvtColor(contours, contours, COLOR_GRAY2RGB);
/*
auto end = chrono::high_resolution_clock::now();
auto dur = end - begin;
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
ms++;
sum += ms;
cout << 1000 / ms << "fps avr:" << 1000 / (sum / (++i)) << endl;
*/

unsigned char row_center = gray.at<uchar>(10, 160);

Expand Down Expand Up @@ -155,104 +141,31 @@ int main() {
{
cout << "go left ";

// SendMessage(hWnd, WM_KEYUP, 0x44, 0); // SendMessage not working for DirectX window, using SendInput instead
// Sleep(100);
// SendMessage(hWnd, WM_KEYDOWN, 0x74, 0);
// Sleep(100);
// SendMessage(hWnd, WM_KEYUP, 0x74, 0);

HKL kbl = GetKeyboardLayout(0);

// Create a generic keyboard event structure
INPUT ip; // Using SendInput to send input commands
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0; // We're doing scan codes instead (not using virtual keys)
ip.ki.dwExtraInfo = 0;

// Releases 'D'
ip.ki.wScan = 0x44;
ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(ip));
Sleep(100);

// Presses 'A'
ip.ki.wScan = 0x41;
ip.ki.dwFlags = KEYEVENTF_UNICODE;
SendInput(1, &ip, sizeof(ip));
Sleep(100);

// Releases 'A'
ip.ki.wScan = 0x41;
ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(ip));
Sleep(100);
// }
PostMessage(hWnd, WM_KEYUP, 0x44, 0);
Sleep(500);
PostMessage(hWnd, WM_KEYDOWN, 0x41, 0);
Sleep(500);
PostMessage(hWnd, WM_KEYUP, 0x41, 0);
}
else if (left + right > -50 && left + right < 50){
cout << "go straight ";
for (int x = 0, y = 0; x < 700 && y < 700; x += 10, y += 10)
{
//SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
//Sleep(100);

// SendMessage(hWnd, WM_KEYUP, 0x44, 0);
// Sleep(10);
// SendMessage(hWnd, WM_KEYUP, 0x41, 0);

INPUT ip; // Using SendInput to send input commands
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0; // We're doing scan codes instead
ip.ki.dwExtraInfo = 0;

// Releases 'D'
ip.ki.wScan = 0x44;
ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(ip));
Sleep(100);

// Releases 'A'
ip.ki.wScan = 0x41;
ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(ip));
Sleep(100);
// PostMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
// Sleep(500);
// PostMessage(hWnd, WM_KEYDOWN, 0x44, 0);
// Sleep(500);
// PostMessage(hWnd, WM_KEYDOWN, 0x41, 0);
}
}
else{
cout << "go right ";
{
// SendMessage(hWnd, WM_KEYUP, 0x41, 0);
// Sleep(100);
// SendMessage(hWnd, WM_KEYDOWN, 0x74, 0);
// Sleep(100);
// SendMessage(hWnd, WM_KEYUP, 0x74, 0);

INPUT ip;
Sleep(100);
ip.type = INPUT_KEYBOARD;
ip.ki.time = 0;
ip.ki.wVk = 0; // We're doing scan codes instead
ip.ki.dwExtraInfo = 0;

// Releases 'A'
ip.ki.wScan = 0x41;
ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(ip));
Sleep(100);

// Presses 'D'
ip.ki.wScan = 0x44;
ip.ki.dwFlags = KEYEVENTF_UNICODE;
SendInput(1, &ip, sizeof(ip));
Sleep(100);

// Releases 'D'
ip.ki.wScan = 0x44;
ip.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(ip));
Sleep(100);

PostMessage(hWnd, WM_KEYUP, 0x41, 0);
Sleep(500);
PostMessage(hWnd, WM_KEYDOWN, 0x44, 0);
Sleep(500);
PostMessage(hWnd, WM_KEYUP, 0x44, 0);
// keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0);
}
}
Expand Down
Binary file modified ets2_auto_driving/vc120.pdb
Binary file not shown.

0 comments on commit e1bc37e

Please sign in to comment.