[c]Communiceren met de console van Enemy Territory

Pagina: 1
Acties:

  • StM
  • Registratie: Februari 2005
  • Laatst online: 12-02 19:01
Het probleem:

Ik wil communniceren met de console van ET.

Kan dit wel?

Jazeker, er zijn verschillende tooltjes die het doen.

Wat is die console eigenlijk?

Nou dit:

Afbeeldingslocatie: http://server.site-to-make.nl/dump/got/console.jpg

En wat wil je nu precies?

Ik wil met een extern 'tooltje' kunnen communiceren met die console. Dus ik wil wat er op staat kunnen uitlezen en er naar toe kunnen schrijven?

Heb je ook wat al wat gevonden?

Jazeker. De source van etfakt is open en kan je hier vinden: http://www.theunknownones...php?file=ETFakt03_src.rar

Ik heb in de source verschillende stukken code gevonden die in mijn ogen de koppeling zouden MOETEN doen, waarom moeten met hoofdletters staan later meer ;)

Dit zijn die stukken, geschreven in delphi:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
procedure ExecETCommand(Command : String);
var
  buffer : array[0..4096] of char;
  F : THandle;
  written : Cardinal;
begin
  StrPCopy(buffer,Command);
  if (not WaitNamedPipe(PChar('\\.\pipe\ETCommands'),25)) then
    exit;
  F:=CreateFile(PChar('\\.\pipe\ETCommands'),
                      GENERIC_WRITE,
                      0,
                      nil,
                      OPEN_EXISTING,
                      0,
                      0);
  if (f<>INVALID_HANDLE_VALUE) then
    WriteFile(F,buffer,length(Command),written,nil);
  CloseHandle(F);
end;


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

procedure TCommandCatcher.Execute;
var
  Ovl : TOverlapped;
  fConnected: Boolean;
  bytesRead : Cardinal;
  Buffer    : array [0..512] of char;
  strBuffer : String;
begin
  hPipe:=CreateNamedPipe(PAnsiChar('\\.\pipe\ETCommands'),
                          PIPE_ACCESS_INBOUND,
                          PIPE_TYPE_BYTE or PIPE_WAIT,
                          10,
                          0,
                          sizeof(buffer),
                          10000, // timeout in millseconds
                          Nil);
  Ovl.hEvent:=CreateEvent(nil, True, False, 'PipeConnected');
  repeat
    strbuffer:='';
    try
      fConnected := ConnectNamedPipe(hPipe, @Ovl) or (GetLastError = ERROR_PIPE_CONNECTED);
      if not fConnected then
        fConnected := WaitForSingleObject(Ovl.hEvent, 20) <> WAIT_TIMEOUT;
      if fConnected then
      begin
        ResetEvent(Ovl.hEvent);
        while ReadFile(hPipe,Buffer,sizeof(Buffer),bytesRead,nil) do
        begin
          strBuffer:=strBuffer+copy(Buffer,0,bytesRead);
          buffer:='';
        end;
        if (not AnsiSameStr(Trim(strBuffer),'')) then
        begin
          formMain.SendCommand(Trim(strBuffer));
          FlushFileBuffers(hPipe);
        end;
      end;
    finally
      FlushFileBuffers(hPipe);
      DisconnectNamedPipe(hPipe);
    end;
  until (Self.Suspended or Self.Terminated);
  CloseHandle(hPipe);
  CloseHandle(Ovl.hEvent);
end;


bovenstaande code komt 2x voor in de source van etfakt... :?

Dit vond ik ook nog:

Delphi: unitFormMain.pas
1
2
3
4
5
6
7
8
9
10
11
12
procedure TETFformMain.SendCommand(CMD: String);
begin
  if (AnsiSameText(Trim(CMD),EmptyStr)) then exit;
  if (ETRunning) then
  begin
    AddLog('Sending ETCommand: '+CMD);
    SendMessage(ETCMDHandle, WM_SETTEXT, Length(CMD), Integer(PChar(CMD)));
    SendMessage(ETCMDHandle, WM_CHAR, 13, 1)
  end
  else
    AddLog('Can not send ETCommand: '+CMD);
end;


Ik dacht dus dan maken wij een pipe client die met etcommands communiceert. De code hiervoor heb ik met behulp van GeniusDex MSDN gehaalt en uiteraard aangepast.

Hier mijn code:

C++: main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <windows.h> 
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <cstdlib>

#define BUFSIZE 512
 
int _tmain(int argc, TCHAR *argv[]) 
{ 
   HANDLE hPipe; 
   LPTSTR lpvMessage=TEXT("Default message from client"); 
   TCHAR chBuf[BUFSIZE]; 
   BOOL fSuccess; 
   DWORD cbRead, cbWritten, dwMode; 
   LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\ETCommands"); 

   if( argc > 1 )
      lpvMessage = argv[1];
 
// Try to open a named pipe; wait for it, if necessary. 
 
   while (1) 
   { 
      hPipe = CreateFile( 
         lpszPipename,   // pipe name 
         GENERIC_READ |  // read and write access 
         GENERIC_WRITE, 
         0,              // no sharing 
         NULL,           // default security attributes
         OPEN_EXISTING,  // opens existing pipe 
         0,              // default attributes 
         NULL);          // no template file 
 
   // Break if the pipe handle is valid. 
 
      if (hPipe != INVALID_HANDLE_VALUE) 
         break; 
 
      // Exit if an error other than ERROR_PIPE_BUSY occurs. 
      
      if (GetLastError() == ERROR_FILE_NOT_FOUND) 
      {
       printf("Pipe not exists\n"); 
       Sleep(500);
      }
      else
      {
 
          if (GetLastError() != ERROR_PIPE_BUSY) 
          {
             printf("Could not open pipe %d", GetLastError()); 
             system("pause");
             return 0;
          }
     
          // All pipe instances are busy, so wait for 20 seconds. 
 
          if (!WaitNamedPipe(lpszPipename, 20000)) 
          { 
             printf("Could not open pipe"); 
             system("pause");
             return 0;
          } 
      }
   } 
 
// The pipe connected; change to message-read mode. 
 
   dwMode = PIPE_READMODE_MESSAGE; 
   fSuccess = SetNamedPipeHandleState( 
      hPipe,    // pipe handle 
      &dwMode,  // new pipe mode 
      NULL,     // don't set maximum bytes 
      NULL);    // don't set maximum time 
   if (!fSuccess) 
   {
      printf("SetNamedPipeHandleState failed"); 
      system("pause");
      return 0;
   }
 
// Send a message to the pipe server. 
 
   fSuccess = WriteFile( 
      hPipe,                  // pipe handle 
      lpvMessage,             // message 
      (lstrlen(lpvMessage)+1)*sizeof(TCHAR), // message length 
      &cbWritten,             // bytes written 
      NULL);                  // not overlapped 
   if (!fSuccess) 
   {
      printf("WriteFile failed"); 
      system("pause");
      return 0;
   }
 
   do 
   { 
   // Read from the pipe. 
 
      fSuccess = ReadFile( 
         hPipe,    // pipe handle 
         chBuf,    // buffer to receive reply 
         BUFSIZE*sizeof(TCHAR),  // size of buffer 
         &cbRead,  // number of bytes read 
         NULL);    // not overlapped 
 
      if (! fSuccess && GetLastError() != ERROR_MORE_DATA) 
         break; 
 
      _tprintf( TEXT("%s\n"), chBuf ); 
   } while (!fSuccess);  // repeat loop if ERROR_MORE_DATA 

   getch();
 
   CloseHandle(hPipe); 
   
   system("pause"); 
   return 0; 
}


Hier staat de msdn informatie en de source: http://msdn.microsoft.com...ase/named_pipe_client.asp

Zodra ik et en dit progje start gebeurt er NIKS :'(

Vandaar ook dat ik hierboven zou moeten neerzette.

Het lijkt er dus op dat die pipe enkel is om tussen de verschillende delen van etfakt te communiceren. Hoe moet ik dan verbinden met ET?

Ik heb hiervoor al gegoogled, gespit in de etfakt code en het uiteindelijk maar hier gepost. Ik weet het eerlijk gezegt niet meer.

Mijn doel: het bovenstaande probleemde probleem oplossen in c of java. En ik hoop dat jullie daar bij kunnen helpen. Heb je meer info nodig? roept u maar :) Ik wil dit puur doen al leerprocess en niet om te cheaten zoals sommige doen. Ook is het handig als je gehele console in bestanden weggeschreven word zodat je later kan terug lezen wat er precies gezegt is. (handig bij het adminnen). De daadwerkelijke impentatie van functies doet er nog niet heel erg toe. Dat lukt me wel. Het gaat me hier puur om de communicatie.


offtopic:
Zijn er geen speciale code tags?

[ Voor 2% gewijzigd door StM op 15-10-2006 12:27 . Reden: filename van code aangepast ]


  • mr_obb
  • Registratie: Juni 2001
  • Laatst online: 20-01 17:28

mr_obb

Lakse Perfectionist


  • StM
  • Registratie: Februari 2005
  • Laatst online: 12-02 19:01
tnx, aangepast + nog klein stukje code toegevoegt

BTW: et is gebaseerd op de quake3 engine

[ Voor 30% gewijzigd door StM op 15-10-2006 12:29 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

C++:
1
SendMessage(ETCMDHandle, WM_SETTEXT, Length(CMD), Integer(PChar(CMD)));    SendMessage(ETCMDHandle, WM_CHAR, 13, 1) 


dit is de code waar imo effectief het commando gezonden wordt.

ASSUME makes an ASS out of U and ME