DevC++4.9.9.2, I'm glad to see you're still working on this as it has been something that's bugged me for sometime now. I run a CS:S surf server and there is no built-in way to supress the million or so dataTable warnings that pop up every time a surfer exceeds the "speed-limit". There are some other features I wanted like automatic restarting on crashes (which I already coded in a seperate application).
I don't know anything about socket programming so I'm looking forward to your examples.
I got my code working using a C++ version of sendkeys I got here:
http://www.codeproject.com/KB/cpp/se...p_Article.aspx
C# has sendkeys built in though it's a little messy and might require a class for certain functions.
Since I couldn't get postMessage() to work with the srcds window I had to use getfocus() every time I sent keys to srcds which is sloppy but it works. I attempted to hide the srcds window by making it small, moving it offscreen and only making it visible on the taskbar for the brief period when keys are sent.
I know this is in C++ but it is really easy to convert to C# and won't require my sloppy type conversions. I have done very little bug testing and the only obvious issue is that when you type in a command it spits out twice (once from you typing it and the other from srcds getting it and sending it back).
I code this in VS2008. I'll post a full project zip just as soon as I read the license for the version of sendkeys I'm using.
#include "stdafx.h"
#include "SendKeys.h"
#include <stdio.h>
#include <string.h>
#include <Windows.h>
#include <tchar.h>
#include <time.h>
#using <System.dll>
using namespace System;
using namespace System::Diagnostics;
using namespace System::IO;
using namespace System::Threading;
ref class MyThread{
public:
static void GetInput(Object ^Name);
};
void MyThread::GetInput(Object ^Name){
HWND WindowHandle;
HWND RestoreMain;
String^ inputText;
String^ check;
LPCTSTR inputConv;
//http://www.codeproject.com/KB/cpp/sendkeys_cpp_Article.aspx
CSendKeys sk;
//Get Window handles
while((WindowHandle = FindWindow(_T("ConsoleWindowClass"), _T("SOURCE DEDICATED SERVER")))==NULL){};
while((RestoreMain = FindWindow(_T("ConsoleWindowClass"), _T("Surf Mod")))==NULL){};
//Always wait for commands from user
while(true)
{
inputText=Console::ReadLine();
if ( inputText && inputText->Length > 0 )
{
//This is a sloppy function which converts String^ to LPCTSTR one character at a time
//In C# this loop wouldn't be necessary
for(int i=0; i<inputText->Length;i++){
sk.AppActivate(WindowHandle);
check=inputText->Substring(i,1);
inputConv = (LPCTSTR)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(check).ToInt32();
sk.SendKeys(inputConv);
}
sk.SendKeys("{ENTER}");
//Once keys are sent hide the srcds window
while(SetForegroundWindow(RestoreMain)==0){}
ShowWindow(WindowHandle, SW_HIDE);
//Detect user exit and break read loop
if(inputText->IndexOf("exit")>=0){
break;
}
}
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleTitle(_T("Surf Mod") );
HWND WindowHandle;
//Prepare the srcds process
Process^ myProcess = gcnew Process;
ProcessStartInfo^ myProcessStartInfo = gcnew ProcessStartInfo("srcds.exe","-console -game cstrike");
myProcessStartInfo->UseShellExecute = false;
myProcessStartInfo->RedirectStandardOutput = true;
myProcessStartInfo->RedirectStandardError = false;
myProcess->StartInfo = myProcessStartInfo;
myProcess->Start();
//Hide the SRCDS Window
while((WindowHandle = FindWindow(NULL, _T("SOURCE DEDICATED SERVER")))==NULL){};
MoveWindow(WindowHandle,-200,-200,120,120,true);
ShowWindow(WindowHandle, SW_HIDE);
//Start thread to get commands to send to srcds
Thread ^thr1 = gcnew Thread(gcnew ParameterizedThreadStart(&MyThread::GetInput));
thr1->Start("SOURCE DEDICATED SERVER");
//Prepare Stream Reader
StreamReader^ myStreamReader = myProcess->StandardOutput;
String^ myString;
// Read the standard output of the spawned process.
while(!(myProcess->HasExited)){
if(myString = myStreamReader->ReadLine()){
if (myString->IndexOf("DataTable")<0)
Console::WriteLine( myString );
}
}
myProcess->Close();
thr1->Abort();
return 0;
}