Home > OS >  Indy 9 to Indy 10 conversion
Indy 9 to Indy 10 conversion

Time:12-13

I have found an old .dpr file on the internet, the file is basically a Delphi 7 project from 2008 about server-emulation of an old game.

I tried to compile the file using RAD Studio, but it seemed that the file was using Indy 9 units/libs, where the availabe Indy that comes with RAD Studio is Indy 10.

The codes I want to convert are the ones with errors.

procedure aServer.Map_ServerExecute(AThread: TIdContext);
var
  i, n: integer;
  sz: integer;
  incom_buf: array[0..8192] of byte;
  str: string;
begin
  for i := 0 to max_connects do
    if Assigned(map_connections[i]) then
      if map_connections[i] = AThread then break;
  n := i;
  if i >= max_connects then exit;
  for i := 0 to 8191 do
    incom_buf[i] := 0;
  sz := AThread.Connection.ReadFromStack(); // E2003 Undeclared identifier: 'ReadFromStack'
  AThread.Connection.ReadBuffer(incom_buf,sz); // E2003 Undeclared identifier: 'ReadBuffer'
  decrypt_pkt(incom_buf, sz);
  if do_debug_output <> 0 then
  begin
    str := ByteArrayToHexString(incom_buf, sz-1);
    Writeln('in>' str);
  end;
  sv_callback(n, 1, sz, @incom_buf[0]);
end;
procedure write_to_n(n: integer; is_map: integer; sz: integer; p:pointer); stdcall;
var
  TheThread: TIdContext; 
  i: integer;
  out_buf: array [0..2048] of byte;
  p_out_buf: PByteArray;
  str: string;
begin
  if n < 0 then exit;
  if n > max_connects then exit; 
  if sz <= 0 then exit;
  TheThread := nil;
  if is_map = 0 then
    TheThread := chr_connections[n]
  else 
    TheThread := map_connections[n];
  if not Assigned(TheThread) then exit;
  for i := 0 to 2048 do
    out_buf[i] := 0;
  p_out_buf := p;
  for i := 0 to sz do
    out_buf[i] := p_out_buf[i];
  if do_debug_output <> 0 then
  begin
    str := ByteArrayToHexString(out_buf, sz-1);
    Writeln('out>' str);
  end;
  decrypt_pkt(out_buf, sz);
  TheThread.Connection.WriteBuffer(out_buf,sz-1); // E2003 Undeclared identifier: 'WriteBuffer' 
end;

I tried a few conversions from the internet, but other errors kept arising.

CodePudding user response:

In Indy 10, most of the reading/writing methods were moved from TIdTCPConnection to TIdIOHandler, and also redesigned. For instance, Indy 10 supports .NET, so raw pointers to memory buffers are no longer accepted (that may change in a future version), so you have to use either the TIdBytes (dynamic array of bytes) type, or a TId(ReadOnly)MemoryBufferStream instead.

So, in the code you have shown, try the following changes...

Using TIdBytes:

procedure aServer.Map_ServerExecute(AThread: TIdContext);
var
  i, n: integer;
  sz: integer;
  incom_buf: TIdBytes;
  str: string;
begin
  for i := 0 to max_connects do
    if Assigned(map_connections[i]) then
      if map_connections[i] = AThread then break;
  n := i;
  if i >= max_connects then exit;
  AThread.Connection.IOHandler.CheckForDataOnSource;
  sz := AThread.Connection.IOHandler.InputBuffer.Size;
  if sz = 0 then exit;
  AThread.Connection.IOHandler.ReadBytes(incom_buf, sz);
  decrypt_pkt(PByte(incom_buf), sz);
  if do_debug_output <> 0 then
  begin
    str := ByteArrayToHexString(PByte(incom_buf), sz-1); // why -1?
    Writeln('in>' str);
  end;
  sv_callback(n, 1, sz, PByte(incom_buf));
end;
procedure write_to_n(n: integer; is_map: integer; sz: integer; p: Pointer); stdcall;
var
  TheThread: TIdContext; 
  i: integer;
  out_buf: TIdBytes;
  str: string;
begin
  if n < 0 then exit;
  if n > max_connects then exit; 
  if sz <= 0 then exit;
  TheThread := nil;
  if is_map = 0 then
    TheThread := chr_connections[n]
  else 
    TheThread := map_connections[n];
  if not Assigned(TheThread) then exit;
  out_buf := RawToBytes(p^, sz);
  if do_debug_output <> 0 then
  begin
    str := ByteArrayToHexString(PByte(out_buf), sz-1); // why -1?
    Writeln('out>' str);
  end;
  decrypt_pkt(PByte(out_buf), sz);
  TheThread.Connection.IOHandler.Write(out_buf, sz-1); // why -1?
end;

Alternatively, using TId(ReadOnly)MemoryBufferStream:

procedure aServer.Map_ServerExecute(AThread: TIdContext);
var
  i, n: integer;
  sz: integer;
  incom_buf: array[0..8192] of byte;
  incom_strm: TIdMemoryBufferStream;
  str: string;
begin
  for i := 0 to max_connects do
    if Assigned(map_connections[i]) then
      if map_connections[i] = AThread then break;
  n := i;
  if i >= max_connects then exit;
  ZeroMemory(incom_buf, SizeOf(incom_buf));
  AThread.Connection.IOHandler.CheckForDataOnSource;
  sz := AThread.Connection.IOHandler.InputBuffer.Size;
  if sz = 0 then exit;
  incom_strm := TIdMemoryBufferStream.Create(incom_buf, SizeOf(incom_buf));
  try
    AThread.Connection.IOHandler.ReadStream(incom_strm, sz);
  finally
    incom_strm.Free;
  end;
  decrypt_pkt(incom_buf, sz);
  if do_debug_output <> 0 then
  begin
    str := ByteArrayToHexString(incom_buf, sz-1); // why -1?
    Writeln('in>' str);
  end;
  sv_callback(n, 1, sz, @incom_buf[0]);
end;
procedure write_to_n(n: integer; is_map: integer; sz: integer; p: Pointer); stdcall;
var
  TheThread: TIdContext; 
  i: integer;
  out_buf: array [0..2048] of byte;
  p_out_buf: PByteArray;
  out_strm: TIdReadOnlyMemoryBufferStream;
  str: string;
begin
  if n < 0 then exit;
  if n > max_connects then exit; 
  if sz <= 0 then exit;
  TheThread := nil;
  if is_map = 0 then
    TheThread := chr_connections[n]
  else 
    TheThread := map_connections[n];
  if not Assigned(TheThread) then exit;
  ZeroMemory(out_buf, SizeOf(out_buf));
  CopyMemory(out_buf, p, sz);
  if do_debug_output <> 0 then
  begin
    str := ByteArrayToHexString(out_buf, sz-1); // why -1?
    Writeln('out>' str);
  end;
  decrypt_pkt(out_buf, sz);
  // NOTE: passing ASize=0 to IOHandler.Write(TStream) will send the entire stream instead of sending nothing...
  if sz = 1 then exit;
  out_strm := TIdReadOnlyMemoryBufferStream.Create(out_buf, SizeOf(out_buf));
  try
    TheThread.Connection.IOHandler.Write(out_strm, sz-1); // why -1?
  finally
    out_strm.Free;
  end;
end;
  • Related