Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Suggestions wanted: online database

Status
Not open for further replies.

BobbaFet

Programmer
Feb 25, 2001
903
NL
Ok, here is what I want to do:

Here is what I want to do:
- Check the processlist for all processes running and get their memory block MD5 checksum. Simple enough and already made.
- Next I want to submit the checksum to an online database:
here is how I think I am going to do that: I'll use a idHTTP client to submit the value to a php database and get the return value in the stringstream. Then I read out the stringstream data and decide what to do from there.

Requirements:
- No installation of the BDE
- Needs to be very low in memory usage
- Needs to be very low in bandwidth usage
- Multiple users at the same time

This is intended as a form of known cheats detection. While the game is running I want to check wether or not known cheats are running on the clients PC.

Is this a good way to go about it or do you guys have better suggestions? This only concerns the checking of 1 value at a time and has to be usable by multiple users at the same time. Tell me please wether you think this is a good idea to go about it or not and if not, what do you think would work better.

Any and all suggestions are very welcome!!!

[bobafett] BobbaFet [bobafett]
Code:
if not Programming = 'Severe Migraine' then
                       ShowMessage('Eureka!');
 
I would suggest that you need to do the following:

Server-Side
- Create the relevant database (MySQL works particularly well with PHP, however any DBMS can be used) and tables on the server and populate these tables.
- Write a PHP script to be called by the client computers. The script would process the checksum sent via an HTTP POST, interface with your database so as to retrieve the return value, return HTML, XML, plain text, an encrypted string etc. as an output of the script.

Client-Side
- Point the TIdHTTP component at the URL of the PHP script and POST the checksum data via HTTP, receive the output of the PHP script and parse if necessary to get the data you require. See my post in the following thread for an example of using TIdHTTP to do this:
What you are trying to do lends itself to being implemented as a web service via XML-RPC. This is basically where the server makes procedure calls available for clients to call and receive responses from (using XML as a data transmission format). Please let me know if you would like more information about this. It can still be implemented using PHP on the server-side and Delphi on the client-side.

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
Ok tell me what you got man! This sounds very interesting!

[bobafett] BobbaFet [bobafett]
Code:
if not Programming = 'Severe Migraine' then
                       ShowMessage('Eureka!');
 
For the PHP/XML side of things, I followed a tutorial in a book entitled "No Nonsense XML Web Development with PHP" by Thomas Myer. The following is a link to an article on the publisher's website which gives a very comprehensive tutorial of this technique:

The tutorial will show you how to create a RPC server and an RPC client in PHP. All I did was create a means for sending RPC requests in Delphi via the WinInet API (I was originally using Indy but decided to use WinInet so that I didn't have to install extra bits and pieces to send requests via HTTPS).

This is the meat of the unit which actually sends the request to the server:
Code:
procedure TXmlRpcClient.DoPost(const PostData: String);
var
  NetHandle: HINTERNET;
  hConnect:  HINTERNET;
  hRequest:  HINTERNET;
  dwIndex, dwCodeLen, dwRead, dwNumber: Cardinal;
  dwCode: array[1..20] of char;
  res, str: pchar;
  dataBuffer: array[0..4095] of char;
  resStr: string;
begin
  NetHandle := InternetOpen('Daemon', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if Assigned(NetHandle) then
  begin
    try
      hConnect := InternetConnect(NetHandle, PChar(RPC_SERVER_NAME), fServerPort, nil, nil, INTERNET_SERVICE_HTTP, 0, 1);
      if Assigned(hConnect) then
      begin
        try
          hRequest := HttpOpenRequest(hConnect, PChar('POST'), PChar(RPC_SERVER_SCRIPT), nil, nil, nil, fHTTPOpenRequestFlags, 0);
          if Assigned(hRequest) then
          begin
            try
              if HttpSendRequest(hRequest, nil, 0, PChar(PostData), Length(PostData)) then
              begin
                dwIndex := 0;
                dwCodeLen := 10;
                HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, @dwCode, dwCodeLen, dwIndex);
                res := PChar(@dwCode);
                dwNumber := SizeOf(dataBuffer) - 1;
                // check if HTTP Status Code is 200 (OK)
                if (res = IntToStr(HTTP_STATUS_OK)) then
                begin
                  while (InternetReadfile(hRequest, @dataBuffer, dwNumber, dwRead)) do
                  begin
                    if dwRead = 0 then
                      Break;
                    dataBuffer[dwRead] := #0;
                    str := PChar(@dataBuffer);
                    resStr := resStr + str;
                  end;
                end
                else
                  resStr := 'Status: ' + res;
                fResponseString := resStr;
              end
              else
                // store error code - check wininet for error codes
                // ([URL unfurl="true"]http://support.microsoft.com/default.aspx?scid=193625),[/URL]
                fErrorCode := GetLastError;
            finally
              InternetCloseHandle(hRequest);
            end;
          end;
        finally
          InternetCloseHandle(hConnect);
        end;
      end;
    finally
      InternetCloseHandle(NetHandle);
    end;
  end;
end;

I have another bit of code that switches between HTTP and HTTPS depending on the value of a property called UseSSL:
Code:
procedure SetUseSSL(const Value: Boolean);
begin
  if Value then
  begin
    fHTTPOpenRequestFlags := INTERNET_FLAG_RELOAD Or INTERNET_FLAG_SECURE Or INTERNET_FLAG_DONT_CACHE;
    fServerPort := INTERNET_DEFAULT_HTTPS_PORT;
  end
  else
  begin
    fHTTPOpenRequestFlags := 0;
    fServerPort := INTERNET_DEFAULT_HTTP_PORT;
  end;
  fUseSSL := Value;
end;

All of the constants in the above code are defined in the WinInet unit, except for the following:
- RPC_SERVER_NAME (host address e.g. - RPC_SERVER_SCRIPT (path & name of script e.g. /web_services/rpc_server.php)

My server code exposes a getFileCount method which simply returns the number of rows in a database table. In the request sent from client to server, I pass the name of the getFileCount method with no additional parameters and the server returns the number of rows in that table.

Hope this helps!

Clive
Runner_1Revised.gif

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"To err is human, but to really foul things up you need a computer." (Paul Ehrlich)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To get the best answers from this forum see: faq102-5096
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top