mirror of
https://github.com/cheat-engine/cheat-engine
synced 2026-08-15 02:26:08 -04:00
547 lines
11 KiB
ObjectPascal
Executable file
547 lines
11 KiB
ObjectPascal
Executable file
unit networkConfig;
|
|
|
|
{$mode DELPHI}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$ifdef darwin}
|
|
macport,
|
|
{$endif}
|
|
{$ifdef windows}
|
|
jwawindows, windows,
|
|
{$endif}
|
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics,
|
|
Dialogs, StdCtrls, ExtCtrls, ComCtrls, Menus, resolve, Sockets, ctypes,
|
|
registry, betterControls, Types;
|
|
|
|
type
|
|
|
|
{ TfrmNetworkConfig }
|
|
|
|
|
|
|
|
TfrmNetworkConfig = class(TForm)
|
|
btnConnect: TButton;
|
|
Button2: TButton;
|
|
edtFriendlyName: TEdit;
|
|
edtHost: TEdit;
|
|
edtPort: TEdit;
|
|
GroupBox1: TGroupBox;
|
|
ctsImageList: TImageList;
|
|
Label1: TLabel;
|
|
Label2: TLabel;
|
|
lblOptionalName: TLabel;
|
|
lvIPList: TListView;
|
|
miRefresh: TMenuItem;
|
|
miDelete: TMenuItem;
|
|
Panel1: TPanel;
|
|
Panel2: TPanel;
|
|
PopupMenu1: TPopupMenu;
|
|
procedure btnConnectClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure FormShow(Sender: TObject);
|
|
procedure lvIPListDblClick(Sender: TObject);
|
|
procedure lvIPListSelectItem(Sender: TObject; Item: TListItem;
|
|
Selected: Boolean);
|
|
procedure miDeleteClick(Sender: TObject);
|
|
procedure miRefreshClick(Sender: TObject);
|
|
procedure PopupMenu1Popup(Sender: TObject);
|
|
private
|
|
{ private declarations }
|
|
|
|
public
|
|
{ public declarations }
|
|
procedure requestlist;
|
|
end;
|
|
|
|
var
|
|
frmNetworkConfig: TfrmNetworkConfig;
|
|
|
|
var
|
|
host: THostAddr;
|
|
port: integer;
|
|
|
|
networkcompression: integer;
|
|
|
|
procedure CEConnect(hostname: string; p: integer);
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses networkInterfaceApi, mainunit2;
|
|
|
|
resourcestring
|
|
rsHost = 'host:';
|
|
rsCouldNotBeResolved = ' could not be resolved';
|
|
rsFailureCreatingSocket = 'Failure creating socket';
|
|
rsFailedConnectingToTheServer = 'Failed connecting to the server';
|
|
|
|
type
|
|
THistoryEntry=class
|
|
public
|
|
ip: string;
|
|
port: string;
|
|
name: string;
|
|
end;
|
|
|
|
TDiscovery=class(tthread)
|
|
private
|
|
s: cint;
|
|
|
|
server: record
|
|
ip: string;
|
|
port: word;
|
|
end;
|
|
procedure addip;
|
|
public
|
|
procedure execute; override;
|
|
procedure Terminate;
|
|
|
|
constructor create(suspended: boolean);
|
|
destructor destroy; override;
|
|
|
|
end;
|
|
|
|
var Discovery: TDiscovery;
|
|
|
|
constructor TDiscovery.create(suspended: boolean);
|
|
begin
|
|
s:=fpsocket(PF_INET, SOCK_DGRAM, 0);
|
|
inherited create(suspended);
|
|
end;
|
|
|
|
destructor TDiscovery.destroy;
|
|
begin
|
|
if s<>cint(INVALID_SOCKET) then
|
|
closeSocket(s);
|
|
end;
|
|
|
|
procedure TDiscovery.terminate;
|
|
var olds: cint;
|
|
begin
|
|
if s<>cint(INVALID_SOCKET) then
|
|
begin
|
|
olds:=s;
|
|
s:=cint(INVALID_SOCKET);
|
|
CloseSocket(olds);
|
|
end;
|
|
|
|
inherited terminate;
|
|
end;
|
|
|
|
procedure TDiscovery.addip;
|
|
var li: tlistitem;
|
|
begin
|
|
if frmNetworkConfig<>nil then
|
|
begin
|
|
li:=frmNetworkConfig.lvIPList.Items.Insert(0); //add to the top
|
|
li.Caption:=server.ip;
|
|
li.SubItems.Add(inttostr(server.port));
|
|
end;
|
|
end;
|
|
|
|
procedure TDiscovery.execute;
|
|
var
|
|
v: BOOL;
|
|
sin: sockaddr_in;
|
|
Y: word;
|
|
|
|
sout: sockaddr_in;
|
|
i: integer;
|
|
|
|
//l: socklen_t;
|
|
|
|
srecv: sockaddr_in;
|
|
recvsize: integer;
|
|
|
|
packet: packed record
|
|
checksum: dword;
|
|
port: word;
|
|
end;
|
|
|
|
begin
|
|
//send a broadcast asking which devices (port 3296)
|
|
|
|
|
|
if s>=0 then
|
|
begin
|
|
v:=true;
|
|
if fpsetsockopt(s, SOL_SOCKET, SO_BROADCAST, @v, sizeof(v)) >=0 then
|
|
begin
|
|
zeromemory(@sin, sizeof(sin));
|
|
|
|
sin.sin_family:=PF_INET;
|
|
sin.sin_addr.s_addr:=htonl(INADDR_ANY);
|
|
sin.sin_port:=htons(3296);
|
|
i:=fpbind(s, @sin, sizeof(sin));
|
|
|
|
if (i>=0) then
|
|
begin
|
|
zeromemory(@sout, sizeof(sout));
|
|
sout.sin_family:=PF_INET;
|
|
sout.sin_addr.s_addr:=htonl(INADDR_BROADCAST);
|
|
sout.sin_port:=htons(3296);
|
|
|
|
packet.checksum:=random(100);
|
|
|
|
i:=fpsendto(s, @packet, sizeof(packet),0, @sout, sizeof(sout));
|
|
|
|
|
|
y:=packet.checksum*$ce;
|
|
|
|
if (i>0) then
|
|
repeat
|
|
recvsize:=sizeof(srecv);
|
|
ZeroMemory(@srecv, recvsize);
|
|
i:=fprecvfrom(s, @packet, sizeof(packet), 0, @srecv, @recvsize);
|
|
if (i>0) and (not terminated) then
|
|
begin
|
|
// showmessage('packet.checksum='+inttohex(packet.checksum,8)+' - y='+inttohex(y,8));
|
|
if packet.checksum=y then
|
|
begin
|
|
// showmessage('address='+inttohex(srecv.sin_addr.s_addr,8)+' port='+inttostr(packet.port));
|
|
//add to list
|
|
server.ip:=NetAddrToStr(srecv.sin_addr);
|
|
server.port:=packet.port;
|
|
if not terminated then
|
|
synchronize(addip);
|
|
end;
|
|
end
|
|
|
|
|
|
until (i<=0) or (terminated);
|
|
|
|
|
|
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if s<>cint(INVALID_SOCKET) then
|
|
begin
|
|
closesocket(s);
|
|
s:=cint(invalid_socket);
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure CEconnect(hostname: string; p: integer);
|
|
var hr: THostResolver;
|
|
begin
|
|
hr:=THostResolver.Create(nil);
|
|
try
|
|
|
|
host:=StrToNetAddr(hostname);
|
|
|
|
if host.s_bytes[4]=0 then
|
|
begin
|
|
if hr.NameLookup(hostname) then
|
|
host:=hr.NetHostAddress
|
|
else
|
|
raise exception.create(rsHost+hostname+rsCouldNotBeResolved);
|
|
|
|
end;
|
|
|
|
|
|
finally
|
|
hr.free;
|
|
end;
|
|
|
|
port:=ShortHostToNet(p);
|
|
|
|
if getConnection=nil then
|
|
begin
|
|
if host.s_addr<>0 then //it's 0 when it terminated earlier
|
|
begin
|
|
host.s_addr:=0;
|
|
if MainThreadID=GetCurrentThreadId then
|
|
MessageDlg(rsFailedConnectingToTheServer, mtError, [mbOK],0);
|
|
end;
|
|
|
|
exit;
|
|
end;
|
|
|
|
|
|
InitializeNetworkInterface;
|
|
end;
|
|
|
|
{ TfrmNetworkConfig }
|
|
|
|
procedure TfrmNetworkConfig.requestlist;
|
|
var
|
|
i: integer;
|
|
begin
|
|
|
|
if discovery<>nil then
|
|
begin
|
|
discovery.Terminate;
|
|
discovery.WaitFor;
|
|
freeandnil(discovery);
|
|
end;
|
|
|
|
//delete discovered entries
|
|
for i:=lvIPList.items.count-1 downto 0 do
|
|
begin
|
|
if lvIPList.items[i].Data=nil then
|
|
lvIPList.items[i].Delete;
|
|
|
|
end;
|
|
|
|
discovery:=TDiscovery.Create(false);
|
|
end;
|
|
|
|
|
|
procedure TfrmNetworkConfig.FormShow(Sender: TObject);
|
|
begin
|
|
requestlist;
|
|
|
|
edtHost.Width:=canvas.GetTextWidth('1234.1234.1234.1234');
|
|
edtPort.Width:=canvas.GetTextWidth(' 99999 ');
|
|
end;
|
|
|
|
|
|
|
|
procedure TfrmNetworkConfig.btnConnectClick(Sender: TObject);
|
|
var
|
|
reg: Tregistry;
|
|
i: integer;
|
|
name, ip: string;
|
|
he: THistoryEntry;
|
|
li: TListitem;
|
|
begin
|
|
CEconnect(trim(edtHost.text), strtoint(trim(edtPort.text)));
|
|
|
|
//check if this is in the list
|
|
he:=nil;
|
|
li:=nil;
|
|
ip:=edtHost.text;
|
|
name:=edtFriendlyName.text;
|
|
for i:=0 to lvIPList.items.count-1 do
|
|
begin
|
|
he:=lvIPList.items[i].data;
|
|
|
|
if (name<>'') and (he<>nil) then
|
|
begin
|
|
if he.name=name then
|
|
begin
|
|
li:=lvIPList.items[i];
|
|
break;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if lvIPList.items[i].caption=ip then
|
|
begin
|
|
li:=lvIPList.items[i];
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if li=nil then
|
|
begin
|
|
li:=lvIPList.items.insert(0);
|
|
li.data:=THistoryEntry.create;
|
|
li.SubItems.add('');
|
|
end;
|
|
|
|
if li.data=nil then //update a found entry to history entry
|
|
li.data:=THistoryEntry.create;
|
|
|
|
he:=THistoryEntry(li.data);
|
|
|
|
|
|
if he<>nil then
|
|
begin
|
|
he.ip:=edtHost.text;
|
|
he.port:=edtport.text;
|
|
he.name:=edtFriendlyName.text;
|
|
|
|
if he.name<>'' then
|
|
li.Caption:=he.name+' ('+he.ip+')'
|
|
else
|
|
li.caption:=he.ip;
|
|
|
|
li.subitems[0]:=he.port;
|
|
end;
|
|
|
|
//still here so the connection is made
|
|
reg:=tregistry.create;
|
|
try
|
|
if reg.OpenKey('\Software\'+strCheatEngine+'\',false) then
|
|
begin
|
|
reg.WriteString('Last Connect IP', edtHost.text);
|
|
reg.WriteString('Last Connect Port', edtport.text);
|
|
reg.WriteString('Last Connect Name', edtFriendlyName.text);
|
|
end;
|
|
finally
|
|
reg.free;
|
|
end;
|
|
|
|
modalresult:=mrok;
|
|
end;
|
|
|
|
procedure TfrmNetworkConfig.FormCreate(Sender: TObject);
|
|
var
|
|
reg: tregistry;
|
|
sl: TStringlist;
|
|
li: tlistitem;
|
|
i: integer;
|
|
ip: string;
|
|
port: string;
|
|
name: string;
|
|
he: THistoryEntry;
|
|
begin
|
|
|
|
reg:=tregistry.create;
|
|
try
|
|
if reg.OpenKey('\Software\'+strCheatEngine+'\',false) then
|
|
begin
|
|
if reg.ValueExists('Last Connect IP') then
|
|
edtHost.text:=reg.ReadString('Last Connect IP');
|
|
|
|
if reg.ValueExists('Last Connect Port') then
|
|
edtport.text:=reg.ReadString('Last Connect Port');
|
|
|
|
sl:=tstringlist.create;
|
|
reg.ReadStringList('History',sl);
|
|
|
|
|
|
for i:=0 to sl.count-1 do
|
|
begin
|
|
case i mod 3 of
|
|
0: ip:=sl[i];
|
|
1: port:=sl[i];
|
|
2:
|
|
begin
|
|
name:=sl[i];
|
|
he:=THistoryEntry.create;
|
|
he.ip:=ip;
|
|
he.port:=port;
|
|
he.name:=name;
|
|
|
|
li:=lvIPList.Items.add;
|
|
if name<>'' then
|
|
li.caption:=name+' ('+ip+')'
|
|
else
|
|
li.caption:=ip;
|
|
|
|
li.SubItems.add(port);
|
|
li.Data:=he;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
sl.free;
|
|
end;
|
|
finally
|
|
reg.free;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmNetworkConfig.FormDestroy(Sender: TObject);
|
|
var
|
|
i: integer;
|
|
reg: Tregistry;
|
|
he: THistoryEntry;
|
|
sl: tstringlist;
|
|
count: integer;
|
|
begin
|
|
|
|
reg:=tregistry.create;
|
|
try
|
|
if reg.OpenKey('\Software\'+strCheatEngine+'\',true) then
|
|
begin
|
|
sl:=tstringlist.create;
|
|
count:=0;
|
|
for i:=0 to lvIPList.items.count-1 do
|
|
begin
|
|
if lvIPList.items[i].Data<>nil then
|
|
begin
|
|
he:=lvIPList.items[i].Data;
|
|
inc(count);
|
|
if count<=10 then //limit to 10 entries
|
|
begin
|
|
sl.add(he.ip);
|
|
sl.add(he.port);
|
|
sl.add(he.name);
|
|
end;
|
|
|
|
he.free;
|
|
lvIPList.items[i].Data:=nil;
|
|
end;
|
|
end;
|
|
|
|
reg.WriteStringList('History',sl);
|
|
sl.free;
|
|
end;
|
|
finally
|
|
reg.free;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmNetworkConfig.lvIPListDblClick(Sender: TObject);
|
|
begin
|
|
if lvIPList.selected<>nil then
|
|
begin
|
|
if lvIPList.selected.Data<>nil then
|
|
begin
|
|
edthost.text:=THistoryEntry(lvIPList.selected.Data).ip;
|
|
edtFriendlyName.text:=THistoryEntry(lvIPList.selected.Data).name;
|
|
end
|
|
else
|
|
edthost.text:=lvIPList.selected.caption;
|
|
edtport.text:=lvIPList.selected.subitems[0];
|
|
btnConnect.click;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmNetworkConfig.lvIPListSelectItem(Sender: TObject;
|
|
Item: TListItem; Selected: Boolean);
|
|
begin
|
|
if selected then
|
|
begin
|
|
if item.data<>nil then
|
|
begin
|
|
edtHost.text:=THistoryEntry(item.data).ip;
|
|
edtFriendlyName.text:=THistoryEntry(item.data).name;
|
|
|
|
end
|
|
else
|
|
edthost.text:=item.caption;
|
|
|
|
|
|
|
|
edtport.text:=item.subitems[0];
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmNetworkConfig.miDeleteClick(Sender: TObject);
|
|
begin
|
|
if (lvIPList.selected<>nil) and (lvIPList.selected.data<>nil) then
|
|
begin
|
|
THistoryEntry(lvIPList.selected.data).free;
|
|
lvIPList.selected.data:=nil;
|
|
lvIPList.selected.Delete;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmNetworkConfig.miRefreshClick(Sender: TObject);
|
|
begin
|
|
requestlist;
|
|
end;
|
|
|
|
procedure TfrmNetworkConfig.PopupMenu1Popup(Sender: TObject);
|
|
begin
|
|
midelete.enabled:=(lvIPList.Selected<>nil) and (lvIPList.Selected.Data<>nil);
|
|
end;
|
|
|
|
|
|
|
|
|
|
end.
|
|
|