From b40dbb8df7f64e9e7ea2797f92a54a37a4ab15b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20K=C3=BChne?= <jakob.kuehne@stud.hs-hannover.de> Date: Thu, 27 Oct 2022 11:07:08 +0200 Subject: [PATCH] Update Schnittstellendefinition_1.md --- Schnittstellendefinition_1.md | 342 ++++++++++++++++++++++++---------- 1 file changed, 244 insertions(+), 98 deletions(-) diff --git a/Schnittstellendefinition_1.md b/Schnittstellendefinition_1.md index 5b9b277..5a7e853 100644 --- a/Schnittstellendefinition_1.md +++ b/Schnittstellendefinition_1.md @@ -1,176 +1,322 @@ +<style> +.opt { + color: #ed767e; + font-style: italic; +} +</style> + # Schnittstellendefinition +## Versionsübersicht +1. ### [**API-Definition Version 1**](#v1) ## Allgemeines -**Verwendete Netzwerktechnologie:** +### Verwendete Netzwerktechnologie: - java.net.Socket - java.net.ServerSocket -**Art des Datentransfers:** +### Art des Datentransfers: - Plaintext -**Andere Festlegungen:** -- Semester wird direkt übetragen => Ob Spieler auf diesem spielen kann, wird nicht im Netzwerk behandelt +### Standardport +* 42069 + +### Andere Festlegungen: +- Für den Host ist es uninteressant, ob der Client berechtigt ist auf einem Semester zu spielen. Es existiert demnach keine zentrale "Registry", welche den Fortschritt aller Nutzer trackt. Diese Aufgabe übernimmt jeder Host/Client für sich selbst intern. - Schiffe mit der Größe `8-Credits <= 0` werden aufgeteilt in einzelne Schiffe der Größe `8-Credits/2` +> - <span style="color:orange">***ACHTUNG*** Eine Größe von `1` ist für eine sinnvolle implementierung einer KI ungeeignet. Es ist sinnvoller die Formel `max(8-Credits, 2)` zu verwenden.</span> -**Semester - Schiffe** - -1. 2, 2, 2, 2, 4, 6 -2. 2, 2, 2, 2, 2, -3. 2, 2, 2, 2, 4, 6 -4. 2, 2, 2, 2, 4, 6 -5. 2, 2, 2, 3, 3, 6 -6. 2, 1, 1, 1, 6 +### **Schiffsgrößen nach Semester** -## API-Definition Version 1 -### Trennzeichen -";" => Befehle auslesen durch String.split(";"); +| Semester | Schiffe & Größen | +| -------- | -------- | +| 1 | {2, 2, 2, 2, 4, 6} | +| 2 | {2, 2, 2, 2, 2} | +| 3 | {2, 2, 2, 2, 4, 6} | +| 4 | {2, 2, 2, 2, 4, 6} | +| 5 | {2, 2, 2, 3, 3, 6} | +| 6 | {2, 1, 1, 1, 6} | ----- -### 1. HELLO + +# [**API-Definition Version 1**](#v1)<a id="v1"></a> +### Übersicht +1. [Allgemeine Beschreibung der Kommunikation](#v1/general) + 1. [Struktur einer Nachricht](#v1/general/msg_structure) + 2. [Ablauf der Verbindung](#v1/general/connection_timeline) +2. [Schnittstellenendpunkte](#v1/api) + * [HELLO](#v1/api/hello) + * [HELLO_ACK](#v1/api/hello_ack) + * [START](#v1/api/start) + * [START_ack](#v1/api/start_ack) + * [READY_PING](#v1/api/ready_ping) + * [READY_CHK](#ready_chk) + * [BEGIN](#v1/api/begin) + * [BEGIN_ACK](#v1/api/begin_ack) + * [FIRE](#v1/api/fire) + * [FIRE_ACK](#v1/api/fire_ack) + * [END](#v1/api/end) + * [END_ACK](#v1/api/end_ack) + * [BYE](#v1/api/bye) + * [ERR](#v1/api/err) + + +## [Allgemeine Beschreibung der Kommunikation](#v1/general)<a id="v1/general"></a> +### [Struktur einer Nachricht](#v1/general/msg_structure)<a id="v1/general/msg_structure"></a> +Nachrichten sind aufgebaut nach dem Schema: +``` +COMMAND;<ARGUMENT>[;[<OPTIONAL_ARG1>][;OPTIONAL_ARG2]] +``` +Jeder Teil der Nachricht ist mit einem `;` getrennt. +Die Daten können in Java mithilfe von `String.split(";");` ausgelesen werden. + +<span class="opt">COMMAND:</span> +Am Anfang steht immer der auszührende Befehl (*COMMAND*). Dieser gibt an, was ein Netzwerkteilnehmer tun soll. + +<span class="opt"><ARGUMENT>:</span> +Auf den *COMMAND* folgen jegliche Argumente, die zwingend erforderlich sind. +``` +COMMAND;ARGUMENT1;ARGUMENT2;... +``` + +<span class="opt">[OPTIONAL_ARG]</span>: +Auf das letzte *ARGUMENT* folgen alle optionalen Argumente. +Sollte bspw. nur *OPTIONAL_ARG2* übergeben werden kann die Nachricht wie folgt übermittelt werden: +``` +COMMAND;ARGUMENT;;OPTIONAL_ARG2 +``` + +### [Ablauf der Verbindung](#v1/general/connection_timeline)<a id="v1/general/connection_timeline"></a> + + + + +## [Schnittstellenendpunkte](#v1/api)<a id="v1/api"></a> +### [HELLO](#v1/api/hello)<a id="v1/api/hello"></a> **Synopsis:** ``` -HELLO;<USERNAME>[;VERSION] +HELLO;<VERSION>;<MAX_SEMESTER>;<USERNAME> ``` -**Description:** -Wird durch den Client bei der Verbindung an den Host gesendet. Typischerweise die erste Nachricht. -**Options:** -* *USERNAME*: Name des hostenden Spielers + +**Beschreibung:** +Die erste Nachricht der Verbindung und wird nach Herstellung der SocketVerbindung von dem Host an den Client gesendet. + +**Argumente:** +* <span class="opt">VERSION:</span> Versionsnummer des Programms + * int: API_VERSION +* <span class="opt">MAX_SEMESTER:</span> Höchstes spielbares Semester des Client + * int: Ganzzahl $\in$ [1,6] +* <span class="opt">USERNAME:</span> Spielername des *Client* * String (UTF-8) * Maximale Länge: 255 Zeichen -* *VERSION* (optional): Versionsnummer des Programms + +**Antwort:** +* [HELLO_ACK](#v1/api/hello_ack): Bestätigung der Verbindung durch den *Client* + + +---- +### [HELLO_ACK](#v1/api/hello_ack)<a id="v1/api/start"></a> + +**Synopsis:** +``` +HELLO_ACK;<VERSION>;<USERNAME>;<SEMESTER> +``` +**Beschreibung:** +Signalisiert de Start einer Session durch den *Host* an den *Client*. + +*Diese Nachricht wird als Antwort auf eine [HELLO](#v1/api/hello)-Nachricht gesendet.* + +**Argumente:** +* <span class="opt">VERSION:</span> Versionsnummer des Programms * int: API_VERSION +* <span class="opt">SEMESTER:</span> Das Semester auf dem die Session gespielt werden wird + * **int**: Ganzzahl $\in$ [1,6] + * berechnet mit `min(hostSemester, clientSemester)` +* <span class="opt">USERNAME:</span> Spielername des *Host* + * **String**: + * Encoding Format: UTF-8 + * Maximale Länge 255 Zeichen ---- -### 2. VERSION_SEND (Optional) +### [START](#v1/api/start)<a id="v1/api/start"></a> **Synopsis:** ``` -VERSION_SEND;<VERSION> +START ``` -**Seit Version:** 1 -**Description:** -Einmalig vor Spielbeginn senden um dem Peer mitzuteilen welche Version des Protokolls man benutzt. Optional. -Wird nie ein ``VERSION_SEND`` empfangen, wird per Definition Version 1 benutzt. -**Options:** +**Beschreibung:** +Infomiert den Client durch den Host dass das die Partie gestartet wird. +**Antwort:** +* [START_ACK](#v1/api/start_ack): Bestätigung des Partiebeginns durch den *Client* + ---- -### 3. VERSION_ACK +### [START_ACK](#v1/api/start_ack)<a id="v1/api/start_ack"></a> **Synopsis:** ``` -VERSION_ACK;<VERSION> +START_ACK ``` -**Description:** -Einmalig vor Spielbeginn senden nachdem man das ``VERSION_SEND`` des Peers empfangen hat um sicher zu gehen dass die Version des Partners die Gleiche ist. -**Options:** -* *VERSION*: Versionsnummer des Programms - * int: API_VERSION +**Beschreibung:** +Bestätigt dem Host durch den Client, dass das die Partie gestartet wird. + +*Diese Nachricht wird als Antwort auf eine [START](#v1/api/start)-Nachricht gesendet.* + +---- +### [READY_PING](#v1/api/ready_ping)<a id="v1/api/ready_ping"></a> +**Synopsis:** +``` +READY_PING;<SHIPS_PLACED> +``` +**Beschreibung:** +Stellt eine Anfrage an den Client während der Vorbereitungsphase, wie viele Schiffe dieser Bereits plaziert hat. +Sind alle Schiffe plaziert, wird stattdessen eine [READY_CHK](#v1/api/ready_chk)-Antwort vom Client gesendet. +**Argumente:** +* <span class="opt">SHIPS_PLACED:</span> Anzahl der noch nicht platzierten Schiffe + * **int**: Ganzzahl $\in$ (0, Anzahl der Schiffe] + +**Antwort:** +* [READY_PING](#v1/api/ready_ping): Nicht alle Schiffe wurden plaziert oder der Client ist nicht bereit fortzufahren +* [READY_CHK](#v1/api/ready_chk): Alle Schiffe wurden plaziert und der Client ist bereit fortzufahren + ---- -### 4. SEMESTER_SEND +### [READY_CHK](#v1/api/ready_chk)<a id="v1/api/ready_chk"></a> **Synopsis:** ``` -SEMESTER_SEND;<SEMESTER> +READY_CHK ``` -**Description:** -Einmalig vor Spielbeginn senden um dem Peer mitzuteilen in welchem Semestern man spiel. -**Options:** -* *SEMESTER*: Höchstes spielbares Semester des Sendenden - * int: Ganzzahl im Intervall [1,6] +**Beschreibung:** +Bestätigt das Platzieren sämtlicher Schiffe des Clients und dessen Bereitschaft mit der Partie zu beginnen. +Das Senden einer extra Nachricht ermöglicht es dem Benutzer des Client ggfs. Änderungen seiner Schiffplatzierung vorzunehmen, auch wenn alle Schiffe platziert sind + ---- -### 5. SEMESTER_ACK +### [BEGIN](#v1/api/begin)<a id="v1/api/begin"></a> **Synopsis:** ``` -SEMESTER_ACK;<SEMESTER> +BEGIN;<WHO> ``` -**Description:** -Einmalig vor Spielbeginn senden um dem Peer mitzuteilen in welchem Semestern man spiel. Es wird ``min(meinSemester, peerSemester)`` als Semester ausgewählt. Nach Empfangen von SEMESTER_ACK kann begonnen werden die Schiffe zu setzen. +**Beschreibung:** +Signalisiert dem Client durch den Host, dass die Vorbereitungsphase beendet und das Spiel begonnen wird. Der Host entscheidet durch einen Münzwurf (Zufall), welche Seite beginnt. -**Options:** -* *SEMESTER*: min(meinSemester, peerSemester) - * int: Ganzzahl im Intervall [1,6] +**Argumente:** +* <span class="opt">WHO</span>: Der beginnende Spieler + * String ∈ { "host", "client" } + +**Antwort** +* [FIRE_ACK](#v1/api/fire_ack): Die Nachricht vom Gegenspieler, dass der Spielzug akzeptiert wurde +* [ERR](#v1/api/err): Die Nachricht konnte nicht vom Gegenspieler verarbeitet werden + * *ILLEGAL_STATE*: Der Sendende ist nicht am Zug ---- -### 6. READY_CHECK +### [BEGIN_ACK](#v1/api/begin_ack)<a id="v1/api/begin_ack"></a> **Synopsis:** ``` -READY_CHECK +BEGIN_ACK;<WHO> ``` -**Description:** -Sendet Nachricht für Bereitschafts-Überprüfung an anderen Spieler. Erwartet eine Antwort. +**Beschreibung:** +Signalisiert dem Host durch den Client, dass die Beendigung der Vorbereitungsphase und der Beginn des Spiels akzeptiert wurde. +*Diese Nachricht wird als Antwort auf eine [BEGIN](#v1/api/begin)-Nachricht gesendet.* + ---- -### 7. READY_RESPONSE +### [FIRE](#v1/api/fire)<a id="v1/api/fire"></a> **Synopsis:** ``` -READY_RESPONSE;<SHIPS_PLACED> +FIRE;<ROW>;<COLUMN> ``` -**Description:** +**Beschreibung:** +Greift den Gegenspieler auf einer Koordinate an. Die -**Options:** -* *SHIPS_PLACED*: Anzahl der noch nicht platzierten Schiffe - * int: Zahl im Intervall [0, Anzahl der nicht platzierten Schiffe] +**Argumente:** +* <span class="opt">ROW:</span> Das Feld im Spielfeld welches beschossen wird + * **int**: im Intervall [0, Spielfeldgröße-1] +* <span class="opt">COLUMN:</span> Das Feld im Spielfeld welches beschossen wird + * **int**: im Intervall [0, Spielfeldgröße-1] +**Antwort** +* [FIRE_ACK](#v1/api/fire_ack): Die Nachricht vom Gegenspieler, dass der Spielzug akzeptiert wurde +* [ERR](#v1/api/err): Die Nachricht konnte nicht vom Gegenspieler verarbeitet werden + * *ILLEGAL_STATE*: Der Sendende ist nicht am Zug + ---- -### 8. START +### [FIRE_ACK](#v1/api/fire_ack)<a id="v1/api/fire_ack"></a> **Synopsis:** ``` -START;<WHO> +FIRE_ACK;<TYPE>[;<GAME_OVER>] ``` -**Description:** +**Beschreibung:** +Gibt dem Gegenspieler eine Rückmeldung, ob der Angriff auf ein spezifisches Feld getroffen hat. Bei einem Treffer (oder Zerstörung) eines Schiffes durch den Gegner erhält dieser einen weiteren Angriff. + +*Diese Nachricht wird als Antwort auf eine [FIRE](#v1/api/fire)-Nachricht gesendet.* -**Options:** -* *WHO*: String ∈ { "YOU", "ME" } +**Argumente:** +* <span class="opt">TYPE:</span> Das Ergebnis des Angriffs + * **String** ∈ {"HIT", "MISS", "SUNK"} +* <span class="opt">GAME_OVER:</span> Letztes Schiff des Sendenden versenkt + * **String** $\in$ {"true"} ---- -### 9. START_ACK +### [END](#v1/api/end)<a id="v1/api/end"></a> **Synopsis:** ``` -START_ACK;<WHO> +END;<WINNER> ``` -**Description:** +**Beschreibung:** +Bestätigt dem Client das Ende der Partie und teilt diesem das Ergebnis mit. -**Options:** -* *WHO*: - * String ∈ { "YOU", "ME" } +**Argumente:** +* <span class="opt">WINNER:</span> Das Ergebnis des Angriffs + * **String** $\in$ {"host", "client"} +**Antwort** +* [END_ACK](#v1/api/end_ack): Das Spielergebnis wurde akzeptiert +* [ERR](#v1/api/err): Die Nachricht konnte nicht vom Client verarbeitet werden + * *ILLEGAL_STATE*: Der interne Gewinner stimmt nicht mit dem Argument <WINNER> + ---- -### 10. FIRE +### [END_ACK](#v1/api/end_ack)<a id="v1/api/end_ack"></a> **Synopsis:** ``` -FIRE;<ROW>;<COLUMN> +END_ACK ``` -**Description:** - -**Options:** -* *ROW*: Das Feld im Spielfeld welches beschossen wird - * int im Intervall [0, Spielfeldgröße-1] -* *COLUMN*: Das Feld im Spielfeld welches beschossen wird - * int im Intervall [0, Spielfeldgröße-1] +**Beschreibung:** +Bestätigt dem Host das Empfangen und die Akzeptanz des Spielergebnisses. + +*Diese Nachricht wird als Antwort auf eine [END](#v1/api/end)-Nachricht gesendet.* ---- -### 11. FIRE_ACK +### [BYE](#v1/api/bye)<a id="v1/api/bye"></a> **Synopsis:** ``` -FIRE_ACK;<ROW>;<COLUMN;<STATUS> +BYE;[<CODE>;<REASON>] ``` -**Description:** +**Beschreibung:** +Informiert den Gegenspieler von einer gewollten (graceful) Beendigung der Verbindung. -**Options:** -* *ROW*: Das Feld im Spielfeld welches beschossen wird - * int im Intervall [0, Spielfeldgröße-1] -* *COLUMN*: Das Feld im Spielfeld welches beschossen wird - * int im Intervall [0, Spielfeldgröße-1] -* *STATUS*: - * String ∈ {"HIT", "MISS", "SUNK"} +**Argumente:** +* <span class="opt">CODE (optional):</span> Eine Zahl die ein konkretes Ergebnis (keinen Fehler) repräsentiert + * **int**: Eine positive Ganzzahl +* <span class="opt">REASON (optional):</span> Eine Beschreibung warum die Verbindung beendet wurde + * **String**: + * Encoding Format: UTF-8 + * Maximale Länge 255 Zeichen ---- -### 12. ERROR +### [ERR](#v1/api/err)<a id="v1/api/err"></a> **Synopsis:** ``` -ERROR;<MSG> +ERR;<CODE>;<REASON> ``` -**Description:** -Falls ein Fehler auftritt, diesen dem Mitspieler mitteilen um Debugging auf beiden Seiten ermöglichen -**Options:** -* *MSG*: Fehler-Nachricht - * String +**Beschreibung:** +Informiert den Gegenspieler von einer unerwarteten Beendigung der Verbindung. + +**Argumente:** +* <span class="opt">CODE:</span> Eine Zahl die ein konkretes Ergebnis (keinen Fehler) repräsentiert + * **int**: Eine negative Ganzzahl (siehe *Error Codes*) +* <span class="opt">REASON:</span> Eine Beschreibung warum die Verbindung beendet wurde + * **String**: + * Encoding Format: UTF-8 + * Maximale Länge 255 Zeichen + +**Error Codes** +1. *UNEXPECTED_MESSAGE*: Die empfangene Nachricht wurde nicht erwartet +2. *ILLEGAL_STATE*: Die empfangene Nachricht wurde erwartet, der Nachrichteninhalt entspricht jedoch nicht den Erwartungen +3. *ILLEGAL_ARGUMENT*: Ein oder mehrere Argumente der empfangenen Nachricht sind nicht korrekt -- GitLab