{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence                                   }
{ Team Coherence is Copyright 2002 by Quality Software Components      }
{                                                                      }
{ For further information / comments, visit our WEB site at            }
{ http://www.TeamCoherence.com                                         }
{**********************************************************************}
{}
{ $Log:  110720: UDPServerMain.pas 
{
{   Rev 1.0    25/10/2004 23:31:26  ANeillans    Version: 9.0.17
{ Verified
}
{-----------------------------------------------------------------------------
 Demo Name: UDP Server
 Author:    <unknown - please contact me to take credit! - Allen O'Neill>
 Copyright: Indy Pit Crew
 Purpose:
 History:
-----------------------------------------------------------------------------
 Notes:

 Simple UDP server demo

Verified:
  Indy 9:
    D7: 25th Oct 2004 Andy Neillans

}

unit Server1;

interface

uses
  Windows, Messages, Graphics, Controls, Forms, Dialogs, IdWinsock2, stdctrls,
  SysUtils, Classes, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze,
  IdComponent, IdUDPBase, IdUDPClient, IdStack, IdUDPServer, IdSocketHandle,
  ExtCtrls,mk_utl;


type
  TUDPMainForm = class(TForm)
    SourceGroupBox: TGroupBox;
    HostNameLabel: TLabel;
    HostAddressLabel: TLabel;
    HostName: TLabel;
    HostAddress: TLabel;
    UDPServer: TIdUDPServer;
    UDPAntiFreeze: TIdAntiFreeze;
    PortLabel: TLabel;
    Port: TLabel;
    BufferSizeLabel: TLabel;
    BufferSize: TLabel;
    UDPMemo: TMemo;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Edit1: TEdit;
    Label5: TLabel;
    Timer1: TTimer;
    GroupBox1: TGroupBox;
    Button1: TButton;
    Button2: TButton;
    Edit2: TEdit;
    Edit3: TEdit;
    Button3: TButton;
    Button4: TButton;
    OpenDialog1: TOpenDialog;
    OpenDialog2: TOpenDialog;
    Edit4: TEdit;
    Button5: TButton;
    Button6: TButton;
    procedure FormCreate(Sender: TObject);
    procedure UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
    procedure Timer1Timer(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  UDPMainForm: TUDPMainForm;

implementation


const
  HOSTNAMELENGTH = 80;

  var ileluda:integer;
  kom:array[1..8] of string;
  user:array[1..8] of record ax,ay,aa,bx,by,ba:double; nam:string; empty,sw,st:boolean; ki:integer; end;
  t:tmemorystream;
  rczas,servertime:tdatetime;
  pversion:double;
  bus:string;
  map:string;
  tosend,running:boolean;

{$R *.DFM}




function zakoduj:string;
var a:string;
i:integer;

begin
t.Clear;
t.Position:=0;
a:='P';
t.WriteBuffer(a[1],length(a));

t.WriteBuffer(servertime,sizeof(servertime));
for i:=1 to 4 do begin
t.WriteBuffer(user[i].ax,sizeof(double));
t.WriteBuffer(user[i].ay,sizeof(double));
t.WriteBuffer(user[i].aa,sizeof(double));
t.WriteBuffer(user[i].bx,sizeof(double));
t.WriteBuffer(user[i].by,sizeof(double));
t.WriteBuffer(user[i].ba,sizeof(double));
t.WriteBuffer(user[i].sw,sizeof(boolean));
t.WriteBuffer(user[i].ki,sizeof(integer));
t.WriteBuffer(user[i].st,sizeof(boolean));
end;
end;

procedure wczytajmape;
var l:string;
f:textfile;
i:integer;
begin
if fileexists(extractfiledir(application.exename)+'\map\'+map) then begin
        assign(f,extractfiledir(application.exename)+'\map\'+map);
        reset(f);
        repeat
        readln(f,l);
                if (copy(l,1,2)='RB') then begin
                        delete(l,1,pos(' ',l));
                        rczas:=time-strtotime(l);
                        UDPMainForm.UDPMemo.Lines.add(l);
                        end;
                if (length(l)>2) and (l[1]='A') and (l[2]>'0') and (l[2]<'5') then begin
                         i:=ord(l[2])-ord('0');
                         delete(l,1,3);
                         user[i].ax:=-strtofloat(paramnr(l,0))+15;
                         user[i].ay:=strtofloat(paramnr(l,1))-15;
                         user[i].aa:=strtofloat(paramnr(l,2));
                end;
        until eof(f);
        closefile(f);
end;
end;

procedure TUDPMainForm.FormCreate(Sender: TObject);
var i:integer;
fi:textfile;
l:string;
begin
decimalseparator:='.';
  pversion:=2.02;
  HostName.Caption := UDPServer.LocalName;
  edit1.text := GStack.LocalAddress;
  Port.Caption := IntToStr(UDPServer.DefaultPort);
  BufferSize.Caption := IntToStr(UDPServer.BufferSize);
  UDPServer.Active := True;
  ileluda:=1;
  for i:=1 to 4 do  begin user[i].empty:=true; kom[i]:='-empty-'; user[i].nam:='-empty-'; end;
  udpmemo.Lines.add('ver '+floattostr(pversion));
  map:='XXXX1';
  bus:='AAAAs';
  running:=false;
  assignfile(fi,'serv.cfg');
  reset(fi);
  readln(fi,l); delete(l,1,3); edit3.Text:=l;
  readln(fi,l); delete(l,1,3); edit2.Text:=l;
  closefile(fi);
        udpmainform.label1.Caption:=kom[1];
        udpmainform.label2.Caption:=kom[2];
        udpmainform.label3.Caption:=kom[3];
        udpmainform.label4.Caption:=kom[4];

end;

procedure TUDPMainForm.UDPServerUDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
  DataStringStream: TStringStream;
  s: String;
  i,j:integer;
  f:double;
  es:integer;
  clver:double;
  b:boolean;
  int:integer;
begin
  s:='     ';
  i:=length(s);

  t:=tmemorystream.Create;
  t.SetSize(512);

  //DataStringStream := TStringStream.Create('');
  try
  //  DataStringStream.CopyFrom(AData, AData.Size);


    t.copyfrom(adata,adata.Size);
  //  udpmemo.lines.add('t.size '+inttostr(t.size));
  //  udpmemo.Lines.Add('adata.size '+inttostr(adata.Size));
//    s:='        ';
t.Position:=0;
SetLength(S, 1);
  //  udpmemo.Lines.add('###');
 // udpmemo.Lines.Add(inttostr(t.Position));
    t.readbuffer(pointer(s)^,1);
 // udpmemo.Lines.Add(inttostr(t.Position));
  //  udpmemo.Lines.add('!!!!!');
 //   udpmemo.lines.add(s[1]+'|'+s[2]+'|'+s[3]+'|'+s[4]);


  //  UDPMemo.Lines.Add('Received "' + DataStringStream.DataString + '" from ' + ABinding.PeerIP + ' on port ' + IntToStr(ABinding.PeerPort));
  //  s := 'Replied from ' + UDPServer.LocalName + ' to "' + DataStringStream.DataString + '"';
//    s:='A';

if (s[1]='L') and running then
    begin
        es:=0;
        for i:=1 to 4 do
                if user[i].empty then es:=i;

        if es>0 then begin
        setlength(user[es].nam,20);
        t.ReadBuffer(pointer(user[es].nam)^,20);
        t.readbuffer(clver,sizeof(clver));
        udpmemo.Lines.add('|'+user[es].nam+'| ver'+floattostr(clver));
        if (clver=pversion) then begin
                s:='N';
                t.Clear;
                t.position:=0;
                inc(ileluda);
                t.WriteBuffer(s[1],1);
                t.writebuffer(es,sizeof(es));
                t.WriteBuffer(pversion,sizeof(pversion));
                i:=length(map);
                t.WriteBuffer(i,sizeof(i));
                t.WriteBuffer(pointer(map)^,length(map));
                i:=length(bus);
                t.WriteBuffer(i,sizeof(i));
                t.WriteBuffer(pointer(bus)^,length(bus));
                user[es].empty:=false;
                kom[es]:=user[es].nam;
        end else begin
                s:='V';
                t.clear;
                t.position:=0;
                t.writebuffer(s[1],1);
        end;

        end else begin
        s:='F';
        t.Clear;
        t.position:=0;
        t.WriteBuffer(s[1],1);
        end;
    end;

if (s[1]='Q') then
    begin
        t.readbuffer(j,sizeof(integer));
        user[j].empty:=true;
        user[j].nam:='-empty-';
        kom[j]:='-empty-';

    end;

/////////////// dekodujemy pozycje
    if (s[1]='P') then
    begin
       // udpmemo.Lines.add('recv');
       // i:=sizeof(integer);
        t.readbuffer(j,sizeof(integer));
       // i:=sizeof(real);
       // udpmemo.Lines.add(inttostr(j));
        t.Readbuffer(f,sizeof(double));user[j].ax:=f; //udpmemo.Lines.add(floattostr(f));

        t.Readbuffer(f,sizeof(double));user[j].ay:=f; //udpmemo.Lines.add(floattostr(f));
        t.Readbuffer(f,sizeof(double));user[j].aa:=f; //udpmemo.Lines.add(floattostr(f));
        t.ReadBuffer(f,sizeof(double));user[j].bx:=f; //udpmemo.Lines.add(floattostr(f));
        t.ReadBuffer(f,sizeof(double));user[j].by:=f;
        t.ReadBuffer(f,sizeof(double));user[j].ba:=f;
        t.readbuffer(b,sizeof(boolean));user[j].sw:=b;
        t.readbuffer(int,sizeof(integer));user[j].ki:=int;
        t.readbuffer(b,sizeof(boolean));user[j].st:=b;


            //    i:=sizeof(integer);
             //   t.ReadBuffer(j,sizeof(integer));udpmemo.Lines.add(inttostr(j));
        kom[j]:=format('%s %f %f %f',[user[j].nam,user[j].ax,user[j].ay,user[j].aa]);
//        zdekoduj(datastringstream.DataString);

        zakoduj;

    end;
        udpmainform.label1.Caption:=kom[1];
        udpmainform.label2.Caption:=kom[2];
        udpmainform.label3.Caption:=kom[3];
        udpmainform.label4.Caption:=kom[4];
    if (s[1]='O') then begin
    t.clear;
    t.position:=0;
    s:='T';
    t.writebuffer(pointer(s)^,length(s));
    s:='INF :'+user[1].nam+' | '+user[2].nam+' | '+user[3].nam+' | '+user[4].nam;
    i:=length(s);
    t.WriteBuffer(i,sizeof(i));
    t.WriteBuffer(pointer(s)^,length(s));
    end;

    if tosend then begin
    t.clear;
    t.Position:=0;
    s:='T';
    t.WriteBuffer(pointer(s)^,length(s));
    s:='MSG :'+edit4.Text;
    i:=length(s);
    t.WriteBuffer(i,sizeof(i));
    t.WriteBuffer(pointer(s)^,length(s));
    edit4.text:='';
    tosend:=false;
    end;

    if not running then begin
    t.Clear;
    s:='I';
    t.WriteBuffer(pointer(s)^,length(s));
    end;
    //ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
    abinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, t.memory^, t.size);

  finally
    t.Free;
  end;
end;


procedure TUDPMainForm.Timer1Timer(Sender: TObject);
begin
servertime:=time-rczas;
label5.Caption:=timetostr(servertime);
end;

procedure TUDPMainForm.Button3Click(Sender: TObject);
begin
if (opendialog1.Execute) then edit2.Text:=extractfilename(opendialog1.FileName);

end;

procedure TUDPMainForm.Button4Click(Sender: TObject);
var s:string;
begin
if (opendialog2.Execute) then begin
s:=opendialog2.FileName;
edit3.Text:=extractfilename(s);
s:=extractfilepath(s);
delete(s,length(s),1);
edit3.Text:=extractfilename(s)+'\'+edit3.Text;
s:=extractfilepath(s);
delete(s,length(s),1);
edit3.Text:=extractfilename(s)+'\'+edit3.Text;
end;
end;

procedure TUDPMainForm.Button1Click(Sender: TObject);
begin
button2.Enabled:=true;
button1.Enabled:=false;
running:=true;
map:=edit2.Text;
bus:=edit3.Text;
wczytajmape;
end;

procedure TUDPMainForm.Button2Click(Sender: TObject);
var i:integer;
begin
for i:=1 to 4 do  begin user[i].empty:=true; kom[i]:='-empty-'; user[i].nam:='-empty-'; end;
        udpmainform.label1.Caption:=kom[1];
        udpmainform.label2.Caption:=kom[2];
        udpmainform.label3.Caption:=kom[3];
        udpmainform.label4.Caption:=kom[4];
button1.Enabled:=true;
button2.Enabled:=false;
running:=false;
end;

procedure TUDPMainForm.Button5Click(Sender: TObject);
begin
if length(edit4.text)>0 then tosend:=true;
end;

procedure TUDPMainForm.Button6Click(Sender: TObject);
var fi:textfile;
begin
assignfile(fi,extractfiledir(application.exename)+'\serv.cfg');
rewrite(fi);
writeln(fi,'TE ',edit3.text);
writeln(fi,'MA ',edit2.text);
closefile(fi);
end;

end.
