From cc6ae26d77cf88cdf2045b756928529b5e95e164 Mon Sep 17 00:00:00 2001
From: Martin <ms618@hdm-stuttgart.de>
Date: Tue, 9 Jan 2024 23:49:40 +0100
Subject: [PATCH] Update: Parser.java (method for parsing IP now contains
 additional check; method for parsing mapData completely rebuilt to allow
 different map sizes and Tile-Numbers from 0 to 99)

---
 .../DataStorage/Classes/Utilities/Parser.java | 180 ++++++++++++++----
 1 file changed, 141 insertions(+), 39 deletions(-)

diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
index 4ccec6fc..14f873d3 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
@@ -67,9 +67,9 @@ public class Parser {
         }
     }
 
-    public static void sha1HashValid(String mapID) throws ParserException {
+    public static void sha1HexHashValid(String mapID) throws ParserException {
 
-        if(!(mapID.length() == 40)){
+        if(mapID.length() != 40){
             throw new ParserException("Map-ID length not correct. Must have length of 40 characters!");
         }
 
@@ -105,90 +105,192 @@ public class Parser {
                 counter++;
             }
         }
-        if(!(counter == 3)){
+        if(counter != 3){
             throw new ParserException("IP-Address must contain exactly 3 octet dividers (.) !");
         }
 
-        Pattern pat = Pattern.compile("[^0-9]");
         for(int i = 0; address.length() > i ; i++){
-            if(!(address.charAt(i) == '.')){
-                Matcher mat = pat.matcher(address.substring(i, i+1));
-                boolean result = mat.find();
-                if(result){
-                    throw new ParserException("IP address does not consist out of numbers 0-9 and separators (.))!");
-                }
+            if(address.charAt(i) == '.' && address.charAt(i + 1) == '.'){
+                throw new ParserException("IP-Address must not contain two or more consecutive dividers (.) without number in between!");
+            }
+        }
+
+        Pattern pat = Pattern.compile("[^0-9.]");
+        for(int i = 0; address.length() > i ; i++){
+            Matcher mat = pat.matcher(address.substring(i, i+1));
+            boolean result = mat.find();
+            if(result){
+                throw new ParserException("IP address does not consist out of numbers 0-9 and separators (.) !");
             }
         }
 
         counter = 0;
-        int[] positions = new int[5];
+        int[] positions = new int[4];
         positions[0] = 0;
-        positions[4] = address.length();
         for(int i = 0; address.length() > i ; i++){
             if(address.charAt(i) == '.'){
                 counter++;
-                positions[counter] = i;
+                positions[counter] = i + 1;
             }
         }
-        for(int i = 0; 4 > i; i++){
-            if(Integer.parseInt(address.substring(positions[i], positions[i+1])) > 255){
-                throw new ParserException("Octets of IP-address must not exceed 255!");
+        for(int i = 0; positions.length > i; i++){
+            if(positions.length - 1 > i) {
+                if (Integer.parseInt(address.substring(positions[i], positions[i + 1] - 1)) > 255) {
+                    throw new ParserException("Octets of IP-address must not exceed 255!");
+                }
             }
-            if(i < 3) {
-                positions[i + 1] = positions[i + 1] + 1;
+            else{
+                if (Integer.parseInt(address.substring(positions[i], address.length())) > 255) {
+                    throw new ParserException("Octets of IP-address must not exceed 255!");
+                }
             }
         }
     }
 
     public static void mapDataValid(String mapData) throws ParserException {
 
-        if(!(mapData.length() == 647)){
-            throw new ParserException("Map-Data corrupted - must have length of 647 chars including spaces!");
+        int mapWidth = 18; //Werte können Methode auch übergeben werden
+        int mapHeight = 18;
+        int maxTileDigits = 2;  //Tile-Numbers are max 2 digits: 10 to 29
+        int minTileDigits = 1; //Tile-Numbers are min 1 digit: 0 to 9
+        int maxMapDataLength = ((mapHeight * mapWidth) - 1) + (mapHeight * mapWidth * maxTileDigits);
+        int minMapDataLength = ((mapHeight * mapWidth) - 1) + (mapHeight * mapWidth * minTileDigits);
+        int spacesAmount = (mapHeight * mapWidth) - 1;
+        int tilesAmount = mapHeight * mapWidth;
+
+        if(mapData.length() > maxMapDataLength){
+            throw new ParserException("Map-Data corrupted - mapData String must not exceed length of " + maxMapDataLength + " chars including spaces for " + mapWidth + "x" + mapHeight + " Tiles map!");
+        }
+
+        if(mapData.length() < minMapDataLength){
+            throw new ParserException("Map-Data corrupted - minimum length of mapData String must be " + minMapDataLength + " chars including spaces for " + mapWidth + "x" + mapHeight + " Tiles map!");
         }
 
-        for(int i = 1; i < 647; i = i + 2){
-            if(!(mapData.charAt(i) == ' ')){
-                throw new ParserException("Map-Data corrupted - must use space every other character!");
+        if(mapData.charAt(0) == ' ' | mapData.charAt(mapData.length() - 1) == ' '){
+            throw new ParserException("Map-Data corrupted - must not start or end with space!");
+        }
+
+        for(int i = 0; mapData.length() > i ; i++){
+            if(mapData.charAt(i) == ' ' && mapData.charAt(i + 1) == ' '){
+                throw new ParserException("Map-Data corrupted - must not contain two or more consecutive spaces without number in between!");
             }
         }
 
-        for(int i = 0; i < 647; i = i + 2){
-            if((Integer.parseInt(mapData.substring(i, i+1)) > 4) | (Integer.parseInt(mapData.substring(i, i+1)) <= 0)){
-                throw new ParserException("Map-Data corrupted - Tile number must be between 1 and 4!");
+        int counter = 0;
+        for(int i = 0; i < mapData.length(); i++){
+            if((mapData.charAt(i) == ' ')){
+                counter++;
+            }
+        }
+        if(counter != spacesAmount){
+            throw new ParserException("Map-Data corrupted - number of spaces must be " + spacesAmount + "!");
+        }
+
+        Pattern pat = Pattern.compile("[^0-9 ]");
+        for(int i = 0; mapData.length() > i ; i++){
+            Matcher mat = pat.matcher(mapData.substring(i, i+1));
+            boolean result = mat.find();
+            if(result){
+                throw new ParserException("Map-Data corrupted - must consist out of numbers 0-9 and space as separator!");
             }
         }
 
-        for(int i = 0; i < 18; i = i + 2){
-            if(!(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
+        counter = 0;
+        int[] positions = new int[tilesAmount];
+        positions[0] = 0;
+        for(int i = 0; mapData.length() > i ; i++){
+            if(mapData.charAt(i) == ' '){
+                counter++;
+                positions[counter] = i + 1;
+            }
+        }
+        for(int i = 0; positions.length > i; i++){
+            if(positions.length - 1 > i) {
+                if (Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > 29 | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < 0) {
+                    throw new ParserException("Map-Data corrupted - Tile number must be between 0 and 29!");
+                }
+            }
+            else{
+                if (Integer.parseInt(mapData.substring(positions[i], mapData.length())) > 29 | Integer.parseInt(mapData.substring(positions[i], mapData.length())) < 0) {
+                    throw new ParserException("Map-Data corrupted - Tile number must be between 0 and 29!");
+                }
+            }
+        }
+
+        //Alternative code for checking if tile number is between 0 and 29:
+
+        /*
+        String combinedNumbers = "";
+        for(int i = 0; i < mapData.length() - 1; i++){
+            if(mapData.charAt(i+1) == ' '){
+                combinedNumbers = combinedNumbers + mapData.charAt(i);
+                if((Integer.parseInt(combinedNumbers) > 29) | (Integer.parseInt(combinedNumbers) < 0)){
+                    throw new ParserException("Map-Data corrupted - Tile number must be between 0 and 29!");
+                }
+                combinedNumbers = "";
+                if(i < mapData.length() - 1){
+                    i++;
+                }
+            }
+            else if(i >= mapData.length() - 2){
+                combinedNumbers = combinedNumbers + mapData.charAt(i) + mapData.charAt(i+1);
+                if((Integer.parseInt(combinedNumbers) > 29) | (Integer.parseInt(combinedNumbers) < 0)){
+                    throw new ParserException("Map-Data corrupted - Tile number must be between 0 and 29!");
+                }
+            }
+            else{
+                combinedNumbers = combinedNumbers + mapData.charAt(i);
+            }
+        }
+        */
+
+        for(int i = 0; i < mapWidth; i++){
+            if(Integer.parseInt(mapData.substring(positions[i], positions[i+1] - 1)) > 19 | Integer.parseInt(mapData.substring(positions[i], positions[i+1] - 1)) < 10){
                 throw new ParserException("Map-Data corrupted - Top-Line must be border tiles!");
             }
         }
 
-        for(int i = 628; i < 647; i = i + 2){
-            if(!(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
-                throw new ParserException("Map-Data corrupted - Bottom-Line must be border tiles!");
+        for(int i = positions.length - mapWidth; i < positions.length; i++){
+            if(positions.length - 1 > i) {
+                if (Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > 19 | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < 10) {
+                    throw new ParserException("Map-Data corrupted - Bottom-Line must be border tiles!");
+                }
+            }
+            else{
+                if (Integer.parseInt(mapData.substring(positions[i], mapData.length())) > 19 | Integer.parseInt(mapData.substring(positions[i], mapData.length())) < 10) {
+                    throw new ParserException("Map-Data corrupted - Bottom-Line must be border tiles!");
+                }
             }
         }
 
-        for(int i = 0; i < 647; i = i + 2){
-            if(i % 36 == 0 && !(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
+        for(int i = mapWidth; i < positions.length - mapWidth; i = i + mapWidth){
+            if(i % mapWidth == 0 && Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > 19 | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < 10){
                 throw new ParserException("Map-Data corrupted - Left Edge must be border tiles!");
             }
         }
 
-        for(int i = 2; i < 647; i = i + 2){
-            if(i % 36 == 0 && !(Integer.parseInt(mapData.substring(i-2, i-1)) == 3)){
+        for(int i = mapWidth - 1; i < positions.length - mapWidth; i = i + mapWidth){
+            if((i + 1) % mapWidth == 0 && Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) > 19 | Integer.parseInt(mapData.substring(positions[i], positions[i + 1] - 1)) < 10){
                 throw new ParserException("Map-Data corrupted - Right Edge must be border tiles!");
             }
         }
 
-        if(!(Integer.parseInt(mapData.substring(38, 39)) == 1) | !(Integer.parseInt(mapData.substring(68, 69)) == 1)){
-            throw new ParserException("Map-Data corrupted - Player spawn must use walkable tile!");
+        if(Integer.parseInt(mapData.substring(positions[mapWidth + 1], positions[mapWidth + 2] - 1)) < 0 | Integer.parseInt(mapData.substring(positions[mapWidth + 1], positions[mapWidth + 2] - 1)) > 9){
+            throw new ParserException("Map-Data corrupted - Player spawn top left must use walkable tile!");
         }
 
-        if(!(Integer.parseInt(mapData.substring(578, 579)) == 1) | !(Integer.parseInt(mapData.substring(608, 609)) == 1)){
-            throw new ParserException("Map-Data corrupted - Player spawn must use walkable tile!");
+        if(Integer.parseInt(mapData.substring(positions[(mapWidth*2) - 2], positions[(mapWidth*2) - 1] - 1)) < 0 | Integer.parseInt(mapData.substring(positions[(mapWidth*2) - 2], positions[(mapWidth*2) - 1] - 1)) > 9){
+            throw new ParserException("Map-Data corrupted - Player spawn top right must use walkable tile!");
         }
+
+        if(Integer.parseInt(mapData.substring(positions[positions.length - (mapWidth*2) + 1], positions[positions.length - (mapWidth*2) + 2] - 1)) < 0 | Integer.parseInt(mapData.substring(positions[positions.length - (mapWidth*2) + 1], positions[positions.length - (mapWidth*2) + 2] - 1)) > 9) {
+            throw new ParserException("Map-Data corrupted - Player spawn bottom left must use walkable tile!");
+        }
+
+        if(Integer.parseInt(mapData.substring(positions[positions.length - mapWidth - 2], positions[positions.length - mapWidth - 1] - 1)) < 0 | Integer.parseInt(mapData.substring(positions[positions.length - mapWidth - 2], positions[positions.length - mapWidth - 1] - 1)) > 9){
+            throw new ParserException("Map-Data corrupted - Player spawn bottom right must use walkable tile!");
+        }
+
     }
 
 }
-- 
GitLab