AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Query an Gameserver
Thema durchsuchen
Ansicht
Themen-Optionen

Query an Gameserver

Ein Thema von Flodding · begonnen am 18. Feb 2015 · letzter Beitrag vom 1. Nov 2015
Antwort Antwort
Seite 1 von 2  1 2      
Flodding

Registriert seit: 26. Dez 2007
Ort: Kiel
121 Beiträge
 
Turbo Delphi für Win32
 
#1

AW: Query an Gameserver

  Alt 24. Feb 2015, 19:20
Also LOB an Medium der mit so wenig Aufwand doch so viel erreicht hat in diesem Thema.

Vielen Dank dafür.

Der hängt sich immernoch auf wenn ich auf einen falschen Port verbinde.
Habe die Änderungen vorgenommen wie vorgeschlagen:
Delphi-Quellcode:
form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin
  form4.Udp1.Send....
end;
Ich weiss ich werde für die folgende Frage bestimmt gesteinigt. Aber warum kommt da eine negative Zahl bei der ID raus? kommt zumindest wenn ich wie folgt aufrufe:
IntToStr(response.ID) Liegt das wieder an der 8A84 die falschrum sind?
Flo
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#2

AW: Query an Gameserver

  Alt 24. Feb 2015, 19:28
Der hängt sich immernoch auf wenn ich auf einen falschen Port verbinde.
Habe die Änderungen vorgenommen wie vorgeschlagen:

Delphi-Quellcode:
form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin
  form4.Udp1.Send....
end;
Nicht das END hinter SendBuf() sondern ganz ans Ende.

Delphi-Quellcode:

begin
  request.RequestHeader := 'ÿÿÿÿ';
  request.PacketHeader := 'T';
  request.Payload := 'Source Engine Query'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring
  request.Payload[24] := #00;

  form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
   begin
    form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
    form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));

    i := 0;
    Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader));
    Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader));
    Move(buffer[i], response.Protocol, SizeOf(response.Protocol)); inc(i, SizeOf(response.Protocol));
    response.Name := GetString(buffer, i);
    response.Map := GetString(buffer, i);
    response.Folder := GetString(buffer, i);
    response.Game := GetString(buffer, i);
    Move(buffer[i], response.ID, SizeOf(response.ID)); inc(i, SizeOf(response.ID));
    Move(buffer[i], response.Players, SizeOf(response.Players)); inc(i, SizeOf(response.Players));
    Move(buffer[i], response.MaxPlayers, SizeOf(response.MaxPlayers)); inc(i, SizeOf(response.MaxPlayers));
    Move(buffer[i], response.Bots, SizeOf(response.Bots)); inc(i, SizeOf(response.Bots));
    Move(buffer[i], response.ServerType, SizeOf(response.ServerType)); inc(i, SizeOf(response.ServerType));
    Move(buffer[i], response.Environment, SizeOf(response.Environment)); inc(i, SizeOf(response.Environment));
    Move(buffer[i], response.Visibility, SizeOf(response.Visibility)); inc(i, SizeOf(response.Visibility));
    Move(buffer[i], response.VAC, SizeOf(response.VAC)); inc(i, SizeOf(response.VAC));
    response.Version := GetString(buffer, i);
    //form4.edit1.Text := response.Name;

  end; //hier hin

end;
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.

Geändert von BadenPower (24. Feb 2015 um 19:34 Uhr)
  Mit Zitat antworten Zitat
Flodding

Registriert seit: 26. Dez 2007
Ort: Kiel
121 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Query an Gameserver

  Alt 24. Feb 2015, 19:32
So habe ich es gemacht. Das kopierte Stückchen war wohl etwas unklar.
Delphi-Quellcode:
procedure Get_A2S_INFO;
var
  request: TInfoRequest;
  response: TInfoResponse;
  buffer: TBufferArray;
  i: Integer;
begin
  request.RequestHeader := -1;
  request.PacketHeader := 'T';
  request.Payload := 'Source Engine Query'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring
  request.Payload[19] := #0;

  form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin

  form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
  form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));

  i := 0;
  Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader));
  Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader));
  Move(buffer[i], response.Protocol, SizeOf(response.Protocol)); inc(i, SizeOf(response.Protocol));
  response.Name := GetString(buffer, i);
  response.Map := GetString(buffer, i);
  response.Folder := GetString(buffer, i);
  response.Game := GetString(buffer, i);
  Move(buffer[i], response.ID, SizeOf(response.ID)); inc(i, SizeOf(response.ID));
  Move(buffer[i], response.Players, SizeOf(response.Players)); inc(i, SizeOf(response.Players));
  Move(buffer[i], response.MaxPlayers, SizeOf(response.MaxPlayers)); inc(i, SizeOf(response.MaxPlayers));
  Move(buffer[i], response.Bots, SizeOf(response.Bots)); inc(i, SizeOf(response.Bots));
  Move(buffer[i], response.ServerType, SizeOf(response.ServerType)); inc(i, SizeOf(response.ServerType));
  Move(buffer[i], response.Environment, SizeOf(response.Environment)); inc(i, SizeOf(response.Environment));
  Move(buffer[i], response.Visibility, SizeOf(response.Visibility)); inc(i, SizeOf(response.Visibility));
  Move(buffer[i], response.VAC, SizeOf(response.VAC)); inc(i, SizeOf(response.VAC));
  response.Version := GetString(buffer, i);
  end;
end;
Flo
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#4

AW: Query an Gameserver

  Alt 24. Feb 2015, 20:58
Ich weiss ich werde für die folgende Frage bestimmt gesteinigt. Aber warum kommt da eine negative Zahl bei der ID raus? kommt zumindest wenn ich wie folgt aufrufe:
IntToStr(response.ID) Liegt das wieder an der 8A84 die falschrum sind?
Nein, dass liegt daran, dass der Typ von ID im Record TInfoResponse falsch deklariert ist.

Statt "SmallInt" muss der Typ von Id "Word" sein.

Dann ist nicht nur die Zahl positiv, sondern der Wert stimmt auch und ist dann 33930.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Flodding

Registriert seit: 26. Dez 2007
Ort: Kiel
121 Beiträge
 
Turbo Delphi für Win32
 
#5

AW: Query an Gameserver

  Alt 24. Feb 2015, 21:10
Vielen Dank , das hat auch super geklappt.

Hab jetzt mal rumgespielt und versucht die A2S_PLAYER Daten zu bekommen. Das Funktionierte vorher ja auch schon soweit, dass die aktuelle Spielerzahl ausgegeben wurde.
an dem selben Punkt bin ich jetzt mit der neuen Funktion die ich etwas umgebaut habe.
Delphi-Quellcode:
TPlayerResponse = record
  ResponseHeader: Integer;
  PacketHeader: Byte;
  Challenge: Integer;
  PlayerCount: Byte;
  PlayerIndex: Byte;
  PlayerName: String;
  PlayerScore: Integer;
  PlayerDuration: Integer;
end;
Delphi-Quellcode:
procedure Get_PLAYER_INFO;
var
  request: TInfoRequest;
  response: TPlayerResponse;
  buffer: TBufferArray;
  i: Integer;
  y: integer;
begin
  request.RequestHeader := -1;
  request.PacketHeader := 'U';
  request.Payload := 'FFFFFFFF'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring

  form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin

  form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
  form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));

  i := 0;

  Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader));
  Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader));
  Move(buffer[i], response.Challenge, SizeOf(response.Challenge)); inc(i, SizeOf(response.Challenge));

  i := 0;

  request.Payload[0] := chr(buffer[5]);
  request.Payload[1] := chr(buffer[6]);
  request.Payload[2] := chr(buffer[7]);
  request.Payload[3] := chr(buffer[8]);
  form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
  form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));
  Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader));
  Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader));

  Move(buffer[i], response.PlayerCount, SizeOf(response.PlayerCount)); inc(i, SizeOf(response.PlayerCount));

  for y := 0 to response.PlayerCount do
    begin
    Move(buffer[i], response.PlayerIndex, SizeOf(response.PlayerIndex)); inc(i, SizeOf(response.PlayerIndex));
    Move(buffer[i], response.PlayerName, SizeOf(response.PlayerName)); inc(i, SizeOf(response.PlayerName));
    Move(buffer[i], response.PlayerScore, SizeOf(response.PlayerScore)); inc(i, SizeOf(response.PlayerScore));
    Move(buffer[i], response.PlayerDuration, SizeOf(response.PlayerDuration)); inc(i, SizeOf(response.PlayerDuration));
    end;

  form4.lblServerHeader.Caption := chr(response.PacketHeader); // D = Antwort -> Playerinfos kommen

  end;
end;
Ich bekomme sogar das D zurückgeliefert. Hatte echt Schwierigkeiten das Challenge in den Payload zu bekommen, aber am Ende hat es dann doch geklappt und die Spielerzahl wird wieder ausgegeben.
Jetzt wollt ich natürlich weil ich einfach musste noch die Spielerdaten haben.
Das schien mir auf den ersten Blick auch ganz einfach. Nimmste einfach ne Schleife und lässt ihn durch laufen und jedes Mal die Daten weiter Lesen.
Hab mir ne Listbox vorne mit aufs Form gelegt und dann wollte ich die Listbox mit den SpielerNAMEN füllen.
form4.ListBox1.Items.Add(response.PlayerName) Jedes Mal wenn ich auslesen möchte kommt ein Fehler.

EDIT: Das mit dem TimeOut funktioniert immernoch nicht richtig in der anderen Funktion.
Flo
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#6

AW: Query an Gameserver

  Alt 24. Feb 2015, 21:14
@BadenPower
Dann ist der auf der Valve Seite falsch deklariert. Dort ist ID als "short" gelistet, und ganz oben steht in den Typkonventionen: short = 16 bit signed integer
Ein 16 Bit ohne Vorzeichen kommt dort nichtmals vor.

@Flodding
Ich hoffe, dass abgesehen vom nacken funktionieren jetzt auch deutlich wurde, wo du deine Gedankenverknotungen hattest, und wie man prinzipiell mit solchen Dingen umgeht. Was das Ganze hier etwas gemein gemacht hat war, dass die Strings von variabler Länge sind. Wären sie mit festen Längen definiert, könnte man das ganze Geraffel mit dem Move() weg lassen, und das RecieveBuffer() direkt eine TInfoResponse Variable füllen lassen, da die Antwort dann "binär" 1:1 zu der Recordstruktur passen würde (bzw. umgekehrt). Dann wäre das nen Einzeiler.

Edit: Okay, du braucht mehr Grundlagen!!! 0xFFFFFFFF ist nicht 'FFFFFFFF'! Das erste ist eine 32 Bit Zahl in Hex-Darstellung, deins ist ein String. Dein String wäre in Hex 0x4646464646464646, also zu lang und völlig falsch. Du solltest dich bevor du mit Protokollen überhaupt anfängst dringend mit Datentypen und -darstellung befassen.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (24. Feb 2015 um 21:23 Uhr)
  Mit Zitat antworten Zitat
Flodding

Registriert seit: 26. Dez 2007
Ort: Kiel
121 Beiträge
 
Turbo Delphi für Win32
 
#7

AW: Query an Gameserver

  Alt 24. Feb 2015, 21:44
Hab den Fehler gefunden.
Move(buffer[i], response.PlayerName, SizeOf(response.PlayerName)); inc(i, SizeOf(response.PlayerName)); kann ja nicht gehen... wofür hab ich denn EXTRA ne GETSTRING Funktion geschenkt bekommen?
response.PlayerName := GetString(buffer, i); Muss es natürlich heissen.

Die Abfrage mit den Spielernamen funktioniert nun auch:
Delphi-Quellcode:
procedure Get_PLAYER_INFO;
var
  request: TInfoRequest;
  response: TPlayerResponse;
  buffer: TBufferArray;
  i: Integer;
  y: integer;
begin
  request.RequestHeader := -1;
  request.PacketHeader := 'U';
  request.Payload := 'FFFFFFFF'; // Von mir aus auch mit einer Konstante oder einem Ressourcestring

  form4.udp1.RemoteHost:= form4.edit1.Text;
  form4.udp1.RemotePort:= form4.edit2.Text;
  form4.udp1.Open;

  if (form4.udp1.Connected) then
  begin

  form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
  form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));

  i := 0;

  Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader));
  Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader));
  Move(buffer[i], response.Challenge, SizeOf(response.Challenge)); inc(i, SizeOf(response.Challenge));

  i := 0;

  request.Payload[0] := chr(buffer[5]);
  request.Payload[1] := chr(buffer[6]);
  request.Payload[2] := chr(buffer[7]);
  request.Payload[3] := chr(buffer[8]);
  form4.Udp1.SendBuf(request, SizeOf(TInfoRequest));
  form4.Udp1.ReceiveBuf(buffer, SizeOf(buffer));

  Move(buffer[i], response.ResponseHeader, SizeOf(response.ResponseHeader)); inc(i, SizeOf(response.ResponseHeader));
  Move(buffer[i], response.PacketHeader, SizeOf(response.PacketHeader)); inc(i, SizeOf(response.PacketHeader));
  Move(buffer[i], response.PlayerCount, SizeOf(response.PlayerCount)); inc(i, SizeOf(response.PlayerCount));

  for y := 0 to response.PlayerCount - 1 do
    begin
    Move(buffer[i], response.PlayerIndex, SizeOf(response.PlayerIndex)); inc(i, SizeOf(response.PlayerIndex));
    response.PlayerName := GetString(buffer, i);
    Move(buffer[i], response.PlayerScore, SizeOf(response.PlayerScore)); inc(i, SizeOf(response.PlayerScore));
    Move(buffer[i], response.PlayerDuration, SizeOf(response.PlayerDuration)); inc(i, SizeOf(response.PlayerDuration));
    form4.ListBox1.Items.Add(response.PlayerName);
    end;

  form4.lblServerHeader.Caption := chr(response.PacketHeader); // D = Antwort -> Playerinfos kommen

  end;
end;
Ja mir fehlen viele Grundlagen was dieses Thema angeht. Ich hatte ehrlich gesagt auch nicht damit gerechnet vor solch Problemen (aus meiner Sicht jetzt) zu stehen als ich meinen kleinen CommunityLauncher angefangen habe zu basteln. Grundsätzlich wollte ich auch NUR die aktuelle Anzahl der Spieler anzeigen lassen, aber es taten sich mit einmal alle Möglichkeiten auf und dadurch ist es erst so eskaliert (wenn dies dann das richtige Wort ist)

Bis jetzt habe ich immer nur kleinere Tools gebastelt die mit dann im Alltag Kleinigkeiten abnehmen oder Dateieinhalte ändern und sowas. Da brauchte ich solch Teufelszeug noch nie und dementsprechend gering sind meine Erfahrungen damit. Wobei ich sagen muss, dass ich in der Vergangenheit wohl auch eher umständlich Programmiert habe als effizient.
Ich habe es auch schon vorher erwähnt. Ich bin kein Professioneller Programmierer und werds leider auch niemals werden. Aber genau dafür gibt es solche Foren, wo Menschen die Wissen haben, es auch teilen können mit denen die es nicht haben oder noch nicht genug.

Trotzdem möchte ich mich hier nochmal bei jedem bedanken der an diesem Thema seinen Beitrag geleistet hat und hoffe, dass zukünftige Forumbesucher mit der selben Problematik es hierdurch leichter haben.

Am Ende bleibt ein Problem übrig...

Zitat:
Wenn der Server nicht erreichbar ist oder der falsche Port angegeben wird, hängt sich das Programm auf.
Wer dafür noch eine Lösung parat hat möge diese doch bitte mit uns teilen
Flo
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#8

AW: Query an Gameserver

  Alt 25. Feb 2015, 10:19
Am Ende bleibt ein Problem übrig...

Zitat:
Wenn der Server nicht erreichbar ist oder der falsche Port angegeben wird, hängt sich das Programm auf.
Wer dafür noch eine Lösung parat hat möge diese doch bitte mit uns teilen
Ach da war ja noch etwas.

Delphi-Quellcode:
procedure TForm4.Get_A2S_INFO;
var
  Request: TInfoRequest;
  Response: TInfoResponse;
  Buffer: TBufferArray;
  I: Integer;
  CheckTime: TDateTime;
begin
  Request.RequestHeader := 'ÿÿÿÿ';
  Request.PacketHeader := 'T';
  Request.Payload := 'Source Engine Query';
  Request.Payload[19] := #0;

  Udp1.RemoteHost:= Edit1.Text;
  Udp1.RemotePort:= Edit2.Text;

  Udp1.Open;
  if (Udp1.Connected) then
   begin
    Udp1.SendBuf(Request, SizeOf(TInfoRequest));
    CheckTime := Now();
    Udp1.WaitForData(5000);
    if (SecondsBetween(Now(),CheckTime) <= 1) then
     begin
      Udp1.ReceiveBuf(Buffer, SizeOf(Buffer));

      I := 0;
      Move(Buffer[I], Response.ResponseHeader, SizeOf(Response.ResponseHeader));
      Inc(I, SizeOf(Response.ResponseHeader));

      //...

     end;

   end;

end;
Normalerweise sollte die Funktion WaitForData() true zurückgeben wenn der Server bereit ist. Da bei mir mit D2007 aber immer false geliefert wird, mache das wie oben gepostet.

Kann das einmal jemand prüfen, ob bei höheren Delphi-Versionen True zurückgegeben wird?

Wenn ja dann könnte man das Workaround in höheren Versionen weglassen.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#9

AW: Query an Gameserver

  Alt 24. Feb 2015, 21:56
@BadenPower
Dann ist der auf der Valve Seite falsch deklariert. Dort ist ID als "short" gelistet, und ganz oben steht in den Typkonventionen: short = 16 bit signed integer
Ein 16 Bit ohne Vorzeichen kommt dort nichtmals vor.
Das habe ich auch gesehen und mich eigentlich gewundert.

Aber ich habe auch die Ausgabe von dem folgenden Link angeschaut:

http://last-templers.de/a2epoch/query/query.php

Dort wird die ID auch positiv als 33930 dargestellt.
Und eine negative ID macht in meinen Augen doch auch keinen Sinn. Daher bin ich eigentlich der Meinung, dass es ein "Word" sein müsste.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Query an Gameserver

  Alt 24. Feb 2015, 22:20
Nein, was es ist ist eindeutig von Valve festgelegt: 16 bit signed integer

Was du daraus interpretierst ist und bleibt deine Sache. Du kannst ja auch die ID als HEX-Wert ausgeben, oder daraus ein Bild erzeugen, oder oder oder.
Es ist einfach eine eindeutige ID und das wichtigste ist, dass beim Austausch mit dem Rest der Welt, die korrekte Bytefolge zu dieser ID wieder zurückgegeben wird.

In der Schnittstelle würde ich das immer so belassen, wie es vorgegeben ist ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz