diff --git a/.idea/.gitignore b/.idea/.gitignore
index 13566b81b018ad684f3a35fee301741b2734c8f4..2fd2e631a061da0fd9d009491ab696e69f18960a 100644
--- a/.idea/.gitignore
+++ b/.idea/.gitignore
@@ -6,3 +6,5 @@
 # Datasource local storage ignored files
 /dataSources/
 /dataSources.local.xml
+/misc.xml
+
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f07edf43fd5a289e4b6ae3c41e745c07417fb94b
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
+    <data-source source="LOCAL" name="battleArena@battlearena.database.windows.net" uuid="7b1fc391-14cb-46cf-a8a0-29c091f02047">
+      <driver-ref>azure.ms</driver-ref>
+      <synchronize>true</synchronize>
+      <jdbc-driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</jdbc-driver>
+      <jdbc-url>jdbc:sqlserver://battlearena.database.windows.net:1433;database=battleArena;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;</jdbc-url>
+      <working-dir>$ProjectFileDir$</working-dir>
+    </data-source>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index e7a7ee4e1a8bb936f74453926c8d1206f86e405b..f33e38f0f5d3f09852522d1e2b2b2325f91a3785 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,7 +7,7 @@
       </list>
     </option>
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="21" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
   </component>
 </project>
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8641bbfdf2e2a8e1ae8a5ddca2037e037e9e7899
--- /dev/null
+++ b/.idea/sqldialects.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="SqlDialectMappings">
+    <file url="file://$PROJECT_DIR$/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql" dialect="AZURE" />
+    <file url="PROJECT" dialect="AZURE" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 231758b8295c2602c5156431d7eec666619df078..4f37f2aaef6c006c1cdabb857ae7787128d71766 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,13 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>5.10.0</version>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>org.apache.logging.log4j</groupId>
             <artifactId>log4j-core</artifactId>
@@ -51,6 +58,24 @@
             <version>19.0.2.1</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.oracle.database.jdbc</groupId>
+            <artifactId>ojdbc11</artifactId>
+            <version>23.3.0.23.09</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.microsoft.sqlserver</groupId>
+            <artifactId>mssql-jdbc</artifactId>
+            <version>12.4.2.jre11</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.10.1</version>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
index 513c8c606c6b4883bc6cb67f99b187c09332bf27..2d90bb00e2c3503261084d7acf6b1dfd98593c61 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/GameSceneController.java
@@ -108,4 +108,4 @@ public class GameSceneController implements Initializable {
     public int getScaledTileSize() {
         return scaledTileSize;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AccountType.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AccountType.java
new file mode 100644
index 0000000000000000000000000000000000000000..145d7a4f6f54bad787231fc80b276a2abaae261b
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AccountType.java
@@ -0,0 +1,9 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+public enum AccountType {
+
+    NONE,
+    LOCAL,
+    ONLINE
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AppSettings.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AppSettings.java
new file mode 100644
index 0000000000000000000000000000000000000000..24d7de8bba503c2d58df72b95d3de8901cd7a91b
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AppSettings.java
@@ -0,0 +1,22 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+public class AppSettings {
+
+    private Double sfxVolume;
+    private int musicVolume;
+
+
+    public AppSettings(Double sfxVolume, int musicVolume) {
+        this.sfxVolume = sfxVolume;
+        this.musicVolume = musicVolume;
+    }
+
+    public Double getSfxVolume() {
+        return sfxVolume;
+    }
+
+    public int getMusicVolume() {
+        return musicVolume;
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
new file mode 100644
index 0000000000000000000000000000000000000000..b138e76967b758555477fbde0c736ff98e2f7690
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java
@@ -0,0 +1,258 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.CryptoException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.SQLException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.CryptoUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+
+public class AzureDB implements ISQLDataBase {
+
+    /*this class is only here for showcasing the interchangeability of the DBMS*/
+
+    private static String user="";
+    private static String password="";
+    private static String[] parts= new String[2];
+
+    static File encryptedFile = new File("src\\main\\resources\\database\\AzureDB_logindetails");
+
+    private static final Logger log = LogManager.getLogger(OracleDB.class);
+
+    public static void getLoginData() throws CryptoException {
+        parts = CryptoUtils.decrypt(encryptedFile);
+        user = parts[0];
+        password = parts[1];
+        log.info("AzureDB_logindetails:  user: " + user + "  password: " +  password);
+    }
+
+    @Override
+    public Connection connect() throws SQLException {
+        try {
+            getLoginData();
+            String url = "jdbc:sqlserver://battlearena.database.windows.net;encrypt=true;user=" + user + ";password=" + password + ";databaseName=battleArena;";
+
+            log.info("Connecting to the database!");
+            Connection connection = DriverManager.getConnection(url);
+            log.info("Database connection test" + connection.getCatalog());
+
+            connection.setAutoCommit(true);
+
+            return connection;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("SQL Connection Error! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ArrayList<MapData> getCoreMaps() throws SQLException {
+        try(Connection connection = connect()) {
+            ArrayList<MapData> newMaps = new ArrayList<MapData>();
+            String sql = "SELECT * FROM CoreMaps";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+
+            while(rs.next()){
+                newMaps.add(new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data")));
+            }
+            log.info("SQL query successful");
+            rs.close();
+            stmt.close();
+            return newMaps;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving Coremaps! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ArrayList<MapInfo> getCommunityMapsList() throws SQLException {
+        try(Connection connection = connect()) {
+            ArrayList<MapInfo> tempList = new ArrayList<MapInfo>();
+            String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM communitymaps";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+
+            while(rs.next()){
+                tempList.add(new MapInfo(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getInt("map_downloads")));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Community map names retrieved successfully");
+            return tempList;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving community map names! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public MapData getCommunityMapByID(String mapID) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT * FROM communitymaps WHERE map_ID = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, mapID);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+            MapData mapChosen = new MapData("", "",0,0, "");
+            if(rs.next() == false){             //if no data matches
+                throw new SQLException("No match on Database");
+            }
+            while(rs.next()) {
+                mapChosen = new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data"));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Community map retrieved successfully");
+
+            String sql2 = "UPDATE communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
+            PreparedStatement stmt2 = connection.prepareStatement(sql2);
+            stmt2.setString(1, mapID);
+            stmt2.executeQuery();
+            log.info("Sending SQL statement to update Download-Counter");
+            stmt2.close();
+
+            return mapChosen;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving community map! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void uploadCommunityMap(MapData map) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data) VALUES (?, ?, ?, ?, ?)";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, map.getMapID());
+            stmt.setString(2, map.getMapName());
+            stmt.setInt(3, map.getMapWidth());
+            stmt.setInt(4, map.getMapHeight());
+            stmt.setString(5, map.getMapData());
+
+            log.info("Sending SQL statement");
+            stmt.executeQuery();
+
+            stmt.close();
+            log.info("Community Map uploaded successfully");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error uploading created community map! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void createPlayer(String playerName, String playerPW) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+            stmt.setString(2, playerPW);
+
+            log.info("Sending SQL statement");
+            stmt.executeQuery();
+
+            stmt.close();
+            log.info("Online account created successfully");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error creating online account! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public String checkCredentials(String playerName) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT player_pw FROM players WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+
+            String password = "";
+            while(rs.next()) {
+                password = rs.getString("player_pw");
+            }
+            rs.close();
+            stmt.close();
+            log.info("Player credentials retrieved successfully");
+            return password;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving retrieving player credentials! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public PlayerStatistics getStatistics(String playerName) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM players WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+            if(rs.next() == false){             //if no data matches
+                throw new SQLException("No match on Database");
+            }
+            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+            while(rs.next()) {
+                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Player statistics retrieved successfully");
+            return stats;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving player statistics! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "UPDATE players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setInt(1, stats.getGamesWon());
+            stmt.setInt(2, stats.getGamesLost());
+            stmt.setInt(3, stats.getKills());
+            stmt.setInt(4, stats.getDeaths());
+            stmt.setInt(5, stats.getBlocksDestroyed());
+            stmt.setInt(6, stats.getGameTime());
+            stmt.setString(7, account.getPlayerName());
+
+            log.info("Sending SQL statement");
+            stmt.executeQuery();
+
+            stmt.close();
+            log.info("Player statistics updated successfully");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error updating player statistics! " + e.getMessage());
+        }
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/CryptoException.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/CryptoException.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bb0c30885d3d243bf25ff82449b3c33fc7dc72b
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/CryptoException.java
@@ -0,0 +1,7 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions;
+
+public class CryptoException extends Exception{
+    public CryptoException(String message, Throwable throwable) {
+        super(message, throwable);
+    }
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/DatabaseException.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/DatabaseException.java
new file mode 100644
index 0000000000000000000000000000000000000000..57a4b7f978103f55a4a83525db1353be7b1fe4fb
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/DatabaseException.java
@@ -0,0 +1,12 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions;
+
+public class DatabaseException extends Exception{
+
+    public DatabaseException() {}
+
+    public DatabaseException(String message2)
+    {
+        super(message2);
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/GSONException.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/GSONException.java
new file mode 100644
index 0000000000000000000000000000000000000000..f16aa2d2831903fca6ccbd1555c798b53132f872
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/GSONException.java
@@ -0,0 +1,12 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions;
+
+public class GSONException extends Exception{
+
+    public GSONException() {}
+
+    public GSONException(String message2)
+    {
+        super(message2);
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/ParserException.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/ParserException.java
new file mode 100644
index 0000000000000000000000000000000000000000..27bd887ed9a7b5cb604d63e2194c818c91cae56a
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/ParserException.java
@@ -0,0 +1,12 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions;
+
+public class ParserException extends Exception{
+
+    public ParserException() {}
+
+    public ParserException(String message2)
+    {
+        super(message2);
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/SQLException.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/SQLException.java
new file mode 100644
index 0000000000000000000000000000000000000000..adbdfa7fac0321fd39687bd957c7f05f542aaaa9
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Exceptions/SQLException.java
@@ -0,0 +1,12 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions;
+
+public class SQLException extends Exception{
+
+    public SQLException() {}
+
+    public SQLException(String message2)
+    {
+        super(message2);
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..b330be1f110d65125e9dfb9b413adcac5c90a10e
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/GsonHandler.java
@@ -0,0 +1,137 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.GSONException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+
+public class GsonHandler {
+    Gson gson = new GsonBuilder().setPrettyPrinting().create();
+
+    private static final Logger log = LogManager.getLogger(GsonHandler.class);
+    Type mapDataType = new TypeToken<ArrayList<MapData>>(){}.getType();
+    Type playerStatsType = new TypeToken<PlayerStatistics>(){}.getType();
+    Type settingsType = new TypeToken<AppSettings>(){}.getType();
+    Type accountType = new TypeToken<PlayerAccount>(){}.getType();
+
+    private final String filePathCoreMaps = "src/main/resources/maps/coreMaps.json";
+    private final String filePathCommunityMaps = "src/main/resources/maps/communityMaps.json";
+    private final String filePathPlayerStats = "src/main/resources/player/playerStatsLocal.json";
+    private final String filePathPlayerAccount = "src/main/resources/player/playerAccount.json";
+    private final String filePathSettings = "src/main/resources/player/appSettings.json";
+
+    public ArrayList<MapData> loadMaps(MapType type) throws GSONException {
+        String filePath;
+        if(type == MapType.COREMAP){
+            filePath = filePathCoreMaps;
+        }
+        else{
+            filePath = filePathCommunityMaps;
+        }
+        try (FileReader reader = new FileReader(filePath)) {
+            ArrayList<MapData> maps = gson.fromJson(reader, mapDataType);
+            log.info("GSON - Maps successfully loaded from JSON");
+            return maps;
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Loading maps from JSON failed");
+            throw new GSONException("Error loading maps!");
+        }
+    }
+
+    public void saveMaps(ArrayList<MapData> maps, MapType type) throws GSONException {
+        String filePath;
+        if(type == MapType.COREMAP){
+            filePath = filePathCoreMaps;
+        }
+        else{
+            filePath = filePathCommunityMaps;
+        }
+        try (FileWriter writer = new FileWriter(filePath)) {
+            gson.toJson(maps, writer);
+            log.info("GSON - Maps successfully saved to JSON");
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Saving maps to JSON failed");
+            throw new GSONException("Error saving maps!");
+        }
+    }
+
+    public PlayerStatistics loadStats() throws GSONException {
+        try (FileReader reader = new FileReader(filePathPlayerStats)) {
+            PlayerStatistics stats = gson.fromJson(reader, playerStatsType);
+            log.info("GSON - Player statistics successfully loaded from JSON");
+            return stats;
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Loading player statistics from JSON failed");
+            throw new GSONException("Error loading player statistics!");
+        }
+    }
+
+    public void saveStats(PlayerStatistics stats) throws GSONException {
+        try (FileWriter writer = new FileWriter(filePathPlayerStats)) {
+            gson.toJson(stats, writer);
+            log.info("GSON - Player statistics successfully saved to JSON");
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Saving player statistics to JSON failed");
+            throw new GSONException("Error saving player statistics!");
+        }
+    }
+
+    public AppSettings loadSettings() throws GSONException {
+        try (FileReader reader = new FileReader(filePathSettings)) {
+            AppSettings settings = gson.fromJson(reader, settingsType);
+            log.info("GSON - Settings successfully loaded from JSON");
+            return settings;
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Loading settings from JSON failed");
+            throw new GSONException("Error Loading settings!");
+        }
+    }
+
+    public void saveSettings(AppSettings settings) throws GSONException {
+        try (FileWriter writer = new FileWriter(filePathSettings)) {
+            gson.toJson(settings, writer);
+            log.info("GSON - Settings successfully saved to JSON");
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Saving settings to JSON failed");
+            throw new GSONException("Error saving settings!");
+        }
+    }
+
+    public PlayerAccount loadAccount() throws GSONException {
+        try (FileReader reader = new FileReader(filePathPlayerAccount)) {
+            PlayerAccount account = gson.fromJson(reader, accountType);
+            log.info("GSON - Player account information successfully loaded from JSON");
+            return account;
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Loading player account information from JSON failed");
+            throw new GSONException("Error loading player account information!");
+        }
+    }
+
+    public void saveAccount(PlayerAccount account) throws GSONException {
+        try (FileWriter writer = new FileWriter(filePathPlayerAccount)) {
+            gson.toJson(account, writer);
+            log.info("GSON - Player account information successfully saved to JSON");
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Saving player account information to JSON failed");
+            throw new GSONException("Error loading player account information!");
+        }
+    }
+
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ISQLDataBase.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ISQLDataBase.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd7bb2f0eb72ddd6eac0a59ce72e0654f522a3ab
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/ISQLDataBase.java
@@ -0,0 +1,23 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.SQLException;
+
+import java.sql.Connection;
+import java.util.ArrayList;
+
+public interface ISQLDataBase {
+
+    //Establish Connection
+    Connection connect() throws SQLException;
+
+    //CRUD Operations in SQL
+    ArrayList<MapData> getCoreMaps() throws SQLException;
+    ArrayList<MapInfo> getCommunityMapsList() throws SQLException;
+    MapData getCommunityMapByID(String mapID) throws SQLException;
+    void uploadCommunityMap(MapData map) throws SQLException;
+    void createPlayer(String playerName, String playerPW) throws SQLException;
+    String checkCredentials(String playerName) throws SQLException;
+    PlayerStatistics getStatistics(String playerName) throws SQLException;
+    void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException;
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapData.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapData.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a88a714ec211cc081dfb511673568de0d2ba6fd
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapData.java
@@ -0,0 +1,38 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+public class MapData {
+    private String mapID;
+    private String mapName;
+    private int mapWidth;   //included for future use (to allow maps of different size)
+    private int mapHeight;  //included for future use (to allow maps of different size)
+    private String mapData;
+
+    protected MapData(String mapID, String mapName, int mapWidth, int mapHeight, String mapData) {
+            this.mapID = mapID;
+            this.mapName = mapName;
+            this.mapWidth = mapWidth;
+            this.mapHeight = mapHeight;
+            this.mapData = mapData;
+    }
+
+    public String getMapID() {
+        return mapID;
+    }
+
+    public String getMapName() {
+        return mapName;
+    }
+
+    public int getMapWidth() {
+        return mapWidth;
+    }
+
+    public int getMapHeight() {
+        return mapHeight;
+    }
+
+    public String getMapData() {
+        return mapData;
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapInfo.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..17fcfdfc65a8777e255f3501ed59e103bfb13f3b
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapInfo.java
@@ -0,0 +1,40 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+public class MapInfo {
+
+    private String mapID;
+    private String mapName;
+    private int mapWidth;   //included for future use (to allow maps of different size)
+    private int mapHeight;  //included for future use (to allow maps of different size)
+    private int mapDownloads; //only used for communityMapsList
+
+    protected MapInfo(String mapID, String mapName, int mapWidth, int mapHeight, int mapDownloads) {
+            this.mapID = mapID;
+            this.mapName = mapName;
+            this.mapWidth = mapWidth;
+            this.mapHeight = mapHeight;
+            this.mapDownloads = mapDownloads;
+    }
+
+    public String getMapID() {
+        return mapID;
+    }
+
+    public String getMapName() {
+        return mapName;
+    }
+
+    public int getMapWidth() {
+        return mapWidth;
+    }
+
+    public int getMapHeight() {
+        return mapHeight;
+    }
+
+    public int getMapDownloads() {
+        return mapDownloads;
+    }
+
+}
+
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapType.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapType.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7738b3c5205d4f217e2a27f0e88578cc34f6fa1
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapType.java
@@ -0,0 +1,8 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+public enum MapType {
+
+    COREMAP,
+    COMMUNITYMAP
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
new file mode 100644
index 0000000000000000000000000000000000000000..070e42d3bbd2fcbed93881fea80a7e5aac077733
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/OracleDB.java
@@ -0,0 +1,257 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.CryptoUtils;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.CryptoException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.SQLException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.File;
+import java.sql.*;
+import java.util.ArrayList;
+
+import oracle.jdbc.pool.OracleDataSource;
+
+
+public class OracleDB implements ISQLDataBase {
+    private static String user="";
+    private static String password="";
+    private static String[] parts= new String[2];
+
+    static File encryptedFile = new File("src\\main\\resources\\database\\OracleDB_logindetails");
+
+    //static File encryptedFile = new File("src\\main\\resources\\database\\document.encrypted");
+    //static File decryptedFile = new File("src\\main\\resources\\database\\document.decrypted");
+
+    private static final Logger log = LogManager.getLogger(OracleDB.class);
+    public static void getLoginData() throws CryptoException {
+        parts = CryptoUtils.decrypt(encryptedFile);
+        user = parts[0];
+        password = parts[1];
+        //log.info("OracleDB_logindetails:  user: " + user + "  password: " +  password);
+    }
+
+    @Override
+    public Connection connect() throws SQLException {
+        try {
+            getLoginData();
+            OracleDataSource ods = new OracleDataSource();
+            ods.setURL("jdbc:oracle:thin:@(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=adb.eu-frankfurt-1.oraclecloud.com))(connect_data=(service_name=g093caf2cf1fea4_battlearena_high.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))");
+            ods.setUser(user);
+            ods.setPassword(password);
+            Connection conn = ods.getConnection();
+
+            log.info("Connecting to the database!");
+
+            return conn;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("SQL connection error! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ArrayList<MapData> getCoreMaps() throws SQLException {
+        try(Connection connection = connect()) {
+            ArrayList<MapData> newMaps = new ArrayList<MapData>();
+            String sql = "SELECT * FROM battlearenadata.coremaps";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+
+            while(rs.next()){
+             newMaps.add(new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data")));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Coremaps retrieved successfully");
+            return newMaps;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving coremaps! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ArrayList<MapInfo> getCommunityMapsList() throws SQLException {
+        try(Connection connection = connect()) {
+            ArrayList<MapInfo> tempList = new ArrayList<MapInfo>();
+            String sql = "SELECT map_id, map_name, map_width, map_height, map_downloads FROM battlearenadata.communitymaps";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+
+            while(rs.next()){
+                tempList.add(new MapInfo(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getInt("map_downloads")));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Community map names retrieved successfully");
+            return tempList;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving community map names! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public MapData getCommunityMapByID(String mapID) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT * FROM battlearenadata.communitymaps WHERE map_ID = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, mapID);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+            MapData mapChosen = new MapData("", "",0,0, "");
+            if(rs.next() == false){             //if no data matches
+                throw new SQLException("No match on Database");
+            }
+            while(rs.next()) {
+                mapChosen = new MapData(rs.getString("map_id"), rs.getString("map_name"), rs.getInt("map_width"), rs.getInt("map_height"), rs.getString("map_data"));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Community map retrieved successfully");
+
+            String sql2 = "UPDATE battlearenadata.communitymaps SET map_downloads = map_downloads + 1 WHERE map_id = ?";
+            PreparedStatement stmt2 = connection.prepareStatement(sql2);
+            stmt2.setString(1, mapID);
+            stmt2.executeQuery();
+            log.info("Sending SQL statement to update Download-Counter");
+            stmt2.close();
+
+            return mapChosen;
+        }
+        catch(Exception e){
+            log.error(e.getMessage());
+            throw new SQLException("Error retrieving community map! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void uploadCommunityMap(MapData map) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data) VALUES (?, ?, ?, ?, ?)";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, map.getMapID());
+            stmt.setString(2, map.getMapName());
+            stmt.setInt(3, map.getMapWidth());
+            stmt.setInt(4, map.getMapHeight());
+            stmt.setString(5, map.getMapData());
+
+            log.info("Sending SQL statement");
+            stmt.executeQuery();
+
+            stmt.close();
+            log.info("Community Map uploaded successfully");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error uploading created community map! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void createPlayer(String playerName, String playerPW) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) VALUES (?, ?, 0, 0, 0, 0, 0, 0)";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+            stmt.setString(2, playerPW);
+
+            log.info("Sending SQL statement");
+            stmt.executeQuery();
+
+            stmt.close();
+            log.info("Online account created successfully");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error creating online account! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public String checkCredentials(String playerName) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT player_pw FROM battlearenadata.players WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+
+            String password = "";
+            while(rs.next()) {
+                password = rs.getString("player_pw");
+            }
+            rs.close();
+            stmt.close();
+            log.info("Player credentials retrieved successfully");
+            return password;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving retrieving player credentials! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public PlayerStatistics getStatistics(String playerName) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "SELECT games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time FROM battlearenadata.players WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setString(1, playerName);
+
+            log.info("Sending SQL statement");
+            ResultSet rs = stmt.executeQuery();
+            if(rs.next() == false){             //if no data matches
+                throw new SQLException("No match on database");
+            }
+            PlayerStatistics stats = new PlayerStatistics(0, 0, 0, 0, 0, 0);
+            while(rs.next()) {
+                stats = new PlayerStatistics(rs.getInt("games_won"), rs.getInt("games_lost"), rs.getInt("kills"), rs.getInt("deaths"), rs.getInt("blocks_destroyed"), rs.getInt("ingame_time"));
+            }
+            rs.close();
+            stmt.close();
+            log.info("Player statistics retrieved successfully");
+            return stats;
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error retrieving player statistics! " + e.getMessage());
+        }
+    }
+
+    @Override
+    public void updatePlayerStats(PlayerStatistics stats, PlayerAccount account) throws SQLException {
+        try(Connection connection = connect()) {
+            String sql = "UPDATE battlearenadata.players SET games_won = ?, games_lost = ?, kills = ?, deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?";
+            PreparedStatement stmt = connection.prepareStatement(sql);
+            stmt.setInt(1, stats.getGamesWon());
+            stmt.setInt(2, stats.getGamesLost());
+            stmt.setInt(3, stats.getKills());
+            stmt.setInt(4, stats.getDeaths());
+            stmt.setInt(5, stats.getBlocksDestroyed());
+            stmt.setInt(6, stats.getGameTime());
+            stmt.setString(7, account.getPlayerName());
+
+            log.info("Sending SQL statement");
+            stmt.executeQuery();
+
+            stmt.close();
+            log.info("Player statistics updated successfully");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new SQLException("Error updating player statistics! " + e.getMessage());
+        }
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8dd5bf0303003f3ab525b04a8b2ea6db4588403
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Persistence.java
@@ -0,0 +1,286 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.GSONException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.SQLException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.HashGenerator;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.DatabaseException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.Parser;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+import java.util.ArrayList;
+
+public class Persistence {
+
+    private static final Logger log = LogManager.getLogger(Persistence.class);
+    private static final Persistence persistenceSingleton = new Persistence();
+    private final GsonHandler gsonHandler = new GsonHandler();
+    protected OracleDB db = new OracleDB(); //evtl. Methoden von OracleDB static machen und von GSON Handler
+    protected ArrayList<MapData> coreMaps;
+    protected ArrayList<MapData> communityMaps;
+    protected PlayerStatistics statistics;
+    protected PlayerAccount account;
+    private AppSettings settings;
+
+
+
+    private Persistence (){}
+
+    public static Persistence getInstance(){
+        return persistenceSingleton;
+    }
+
+    public void loadCoreMaps() throws DatabaseException {
+        try {
+            coreMaps = gsonHandler.loadMaps(MapType.COREMAP);
+            log.info("Core-Maps successfully loaded from file");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Loading core maps from local storage failed!");
+        }
+    }
+
+    public void loadCommunityMaps() throws DatabaseException {
+        try {
+            communityMaps = gsonHandler.loadMaps(MapType.COMMUNITYMAP);
+            log.info("Community-Maps successfully loaded from file");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Loading community maps from local storage failed!");
+        }
+    }
+
+    public void updateCoreMaps() throws DatabaseException {
+        try {
+            coreMaps = db.getCoreMaps();
+            gsonHandler.saveMaps(coreMaps, MapType.COREMAP);
+            log.info("Maps successfully updated from SQL-Server");
+        }
+        catch(Exception e){
+            log.error(e);
+            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException("No connection to SQL server!");
+            }
+            else{
+                throw new DatabaseException("Unknown Database Error. Retrieving Core-Map update failed!");
+            }
+        }
+    }
+
+    public void getCommunityMap(String mapID) throws DatabaseException {
+        for(int i = 0; communityMaps.size() > i; i++){
+            if(communityMaps.get(i).getMapID().equals(mapID)){
+                throw new DatabaseException("Identical map already saved locally. See map name: " + communityMaps.get(i).getMapID());
+            }
+        }
+        try {
+            communityMaps.add(db.getCommunityMapByID(mapID));
+            gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
+            log.info("Community Map successfully retrieved from SQL-Server!");
+        }
+        catch(Exception e){
+            log.error(e);
+            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException("No connection to SQL server!");
+            }
+            else if(e.getMessage().equals("No match on Database")){
+                throw new DatabaseException("No map existing for mapID: " + mapID);
+            }
+            else{
+                throw new DatabaseException("Unknown Database Error. Retrieving Community-Map failed!");
+            }
+        }
+    }
+
+    public void saveCreatedMapLocally(MapData map) throws DatabaseException {
+        try {
+            for(int i = 0; communityMaps.size() > i; i++){
+                if(communityMaps.get(i).getMapID().equals(map.getMapID())){
+                    throw new DatabaseException("Identical map already saved locally. See map name: " + communityMaps.get(i).getMapID());
+                }
+            }
+            communityMaps.add(map);
+            gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
+            log.info("Newly created map stored successfully in JSON");
+        }
+        catch(Exception e){
+            log.error(e);
+            if(e.getMessage().contains("Identical map already saved") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException(e.getMessage());
+            }
+            else{
+                throw new DatabaseException("Unknown Database Error. Saving newly created Community-Map locally failed!");
+            }
+        }
+    }
+
+    public void uploadCreatedMap(MapData map) throws DatabaseException {
+        try {
+            db.uploadCommunityMap(map);
+            log.info("Newly created Community-Map successfully published!");
+        }
+        catch(Exception e){
+            log.error(e);
+            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException("No connection to SQL server!");
+            }
+            else if(e.getMessage().contains("ORA-00001")){
+                throw new DatabaseException("Map already existing on communityMaps server!\n Look for mapID: " + map.getMapID());
+            }
+            else{
+                throw new DatabaseException("Unknown Database Error. Saving to SQL communityMap server failed!");
+            }
+        }
+    }
+
+    public void loadSettings() throws DatabaseException {
+        try {
+            settings = gsonHandler.loadSettings();
+            log.info("Application settings successfully loaded from file");
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Loading settings from local storage failed!");
+        }
+    }
+
+    public void createAccount(String playerName, String password, AccountType type) throws DatabaseException {
+        try {
+            Parser.usernameValid(playerName);
+            if(type == AccountType.LOCAL) {
+                account = new PlayerAccount(playerName, "", type);
+            }
+            else if(type == AccountType.ONLINE) {
+                Parser.passwordValid(password);
+                String hashedPassword = HashGenerator.hashAndHex(password);
+                db.createPlayer(playerName, hashedPassword);
+                account = new PlayerAccount(playerName, hashedPassword, type);
+            }
+            else{
+                throw new DatabaseException("Corrupted Account-Type. Please restart game.");
+            }
+            gsonHandler.saveAccount(account);
+        }
+        catch(ParserException e){
+            log.error(e);
+            throw new DatabaseException(e.getMessage());
+        }
+        catch(SQLException e){
+            log.error(e);
+            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException("No connection to SQL server! Do you want to create a local account?");
+            }
+            else if(e.getMessage().equals("ORA-00001")){
+                throw new DatabaseException("Player name already taken. Please change name, use local account or login with existing account!");
+            }
+            else{
+                throw new DatabaseException("Connection to SQL server failed! Do you want to create a local account?");
+            }
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Error creating account. Please restart game or download game files again.");
+        }
+    }
+
+    public void loadPlayerAccount() throws DatabaseException {
+        try {
+            gsonHandler.loadAccount();
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Loading player account data from local storage failed!");
+        }
+    }
+
+    public void verifyPlayerAccount() throws DatabaseException {
+        try {
+            if (account.getAccountType() == AccountType.NONE) {
+                throw new DatabaseException("Must create playerAccount first");
+            } else if (account.getAccountType() == AccountType.LOCAL) {
+                Parser.usernameValid(account.getPlayerName());
+            } else if (account.getAccountType() == AccountType.ONLINE) {
+                Parser.usernameValid(account.getPlayerName());
+                Parser.sha1HashValid(account.getAccountPassword());
+                if (!(account.getAccountPassword().equals(db.checkCredentials(account.getPlayerName())))){
+                    throw new DatabaseException("Locally stored password does not match online password. Please reenter credentials!");
+                }
+            }
+            else{
+                throw new DatabaseException("AccountType invalid - accountData corrupted! Please create new Account or login with existing!");
+            }
+        }
+        catch(ParserException e){
+            log.error(e);
+            throw new DatabaseException(e.getMessage());
+        }
+        catch(SQLException e){
+            log.error(e);
+            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException("No connection to SQL server! Do you want to continue without tracking statistics?");
+            }
+            else if(e.getMessage().contains("No match on Database")){
+                throw new DatabaseException("No entry for player name " + account.getPlayerName() + " on SQL server. Please create account or login with different username!");
+            }
+            else{
+                throw new DatabaseException("Connection to SQL server failed! Do you want to continue without tracking statistics");
+            }
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new DatabaseException("Loading player account data from local storage failed! Please create new account!");
+        }
+    }
+
+    public void loadPlayerStatistics() throws DatabaseException {
+        try {
+            if (account.getAccountType() == AccountType.LOCAL) {
+                statistics = gsonHandler.loadStats();
+            } else {
+                statistics = db.getStatistics(account.getPlayerName());
+            }
+        }
+        catch(SQLException e){
+            log.error(e);
+            if(e.getMessage().contains("ORA-17868") | e.getMessage().contains("ORA-01017")){
+                throw new DatabaseException("No connection to SQL server!");
+            }
+            else{
+                throw new DatabaseException("Unknown Database Error. Retrieving statistics from SQL server failed!");
+            }
+        }
+        catch(GSONException e){
+            log.error(e);
+            throw new DatabaseException(e.getMessage());
+        }
+    }
+
+    public void updatePlayerStatistics(int kills, int deaths, int gameTime, boolean gameWon){  //after game round
+        statistics.setKills(statistics.getKills() + kills);
+        statistics.setDeaths(statistics.getDeaths() + deaths);
+        statistics.setGameTime(statistics.getGameTime() + gameTime);
+        if(gameWon){
+            statistics.setGamesWon(statistics.getGamesWon() + 1);
+        }
+        else{
+            statistics.setGamesWon(statistics.getGamesLost() + 1);
+        }
+    }
+
+    public void savePlayerStatistics(){     //on shutdown of game
+        try {
+            if (account.getAccountType() == AccountType.LOCAL) {
+                gsonHandler.saveStats(statistics);
+            } else if (account.getAccountType() == AccountType.ONLINE) {
+                db.updatePlayerStats(statistics, account);
+            }
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerAccount.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerAccount.java
new file mode 100644
index 0000000000000000000000000000000000000000..a028edd30e66fc1116615efb7764503e3746469a
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerAccount.java
@@ -0,0 +1,28 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+public class PlayerAccount {
+
+    private String playerName;
+    private String accountPassword;     //only used for Online-Account; "" for local account
+    private AccountType accountType;
+
+
+    public PlayerAccount(String playerName, String accountPassword, AccountType accountType) {
+        this.playerName = playerName;
+        this.accountPassword = accountPassword;
+        this.accountType = accountType;
+    }
+
+    public String getPlayerName() {
+        return playerName;
+    }
+
+    public String getAccountPassword() {
+        return accountPassword;
+    }
+
+    public AccountType getAccountType() {
+        return accountType;
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
new file mode 100644
index 0000000000000000000000000000000000000000..532324238dd5b1b7a19c8de5a0555bc3e2c83fba
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java
@@ -0,0 +1,74 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+public class PlayerStatistics {
+    private static final Logger log = LogManager.getLogger(PlayerStatistics.class);
+
+    private int gamesLost = 0;
+    private int gamesWon = 0;
+    private int kills = 0;
+    private int deaths = 0;
+    private int blocksDestroyed = 0;
+    private int gameTime = 0;
+
+    public PlayerStatistics(int gamesLost, int gamesWon, int kills, int deaths, int blocksDestroyed, int gameTime) {
+        this.gamesLost = gamesLost;
+        this.gamesWon = gamesWon;
+        this.kills = kills;
+        this.deaths = deaths;
+        this.blocksDestroyed = blocksDestroyed;
+        this.gameTime = gameTime;
+    }
+
+
+    public int getGamesLost() {
+        return gamesLost;
+    }
+
+    public void setGamesLost(int gamesLost) {
+        this.gamesLost = gamesLost;
+    }
+
+    public int getGamesWon() {
+        return gamesWon;
+    }
+
+    public void setGamesWon(int gamesWon) {
+        this.gamesWon = gamesWon;
+    }
+
+    public int getKills() {
+        return kills;
+    }
+
+    public void setKills(int kills) {
+        this.kills = kills;
+    }
+
+    public int getDeaths() {
+        return deaths;
+    }
+
+    public void setDeaths(int deaths) {
+        this.deaths = deaths;
+    }
+
+    public int getBlocksDestroyed() {
+        return blocksDestroyed;
+    }
+
+    public void setBlocksDestroyed(int blocksDestroyed) {
+        this.blocksDestroyed = blocksDestroyed;
+    }
+
+    public int getGameTime() {
+        return gameTime;
+    }
+
+    public void setGameTime(int gameTime) {
+        this.gameTime = gameTime;
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..641449a5164e3aaa72e5aef97324569ec1c7b3c2
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/RuntimeInfo.java
@@ -0,0 +1,89 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.HashGenerator;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.Parser;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.ArrayList;
+
+public class RuntimeInfo {
+
+    private static final Logger log = LogManager.getLogger(RuntimeInfo.class);
+    private static final RuntimeInfo runtimeInfoSingleton = new RuntimeInfo();
+    private final Persistence persistenceInst = Persistence.getInstance();
+    protected ArrayList<String> coreMapsListLocal;      //for drop-down list
+    protected ArrayList<String> communityMapsListLocal;  //for drop-down list
+    protected ArrayList<MapInfo> communityMapsListRemote;  //for community map browser
+    protected String mapDataGame;
+    protected boolean offlineMode;  //if Account-Type is online but no SQL connection: start game without stats tracking
+
+
+    private RuntimeInfo(){};
+
+    public static RuntimeInfo getInstance(){
+        return runtimeInfoSingleton;
+    }
+
+    public String getMapDataGame() {
+        return mapDataGame;
+    }
+
+    public MapData createMap(String mapName, String mapData) throws ParserException {
+        try {
+            Parser.mapDataValid(mapData);
+            Parser.mapNameValid(mapName);
+            return new MapData(HashGenerator.hashAndHex(mapData), mapName, 18, 18, mapData);
+        }
+        catch(Exception e){
+            log.error(e);
+            throw new ParserException(e.getMessage());
+        }
+    }
+
+    public void setGameMap(String mapSelected, boolean choseCoremaps){
+        String mapID = mapSelected.substring(mapSelected.indexOf("(") + 1, mapSelected.length() - 1);
+
+        if(choseCoremaps) {
+            for (int index = 0; index < persistenceInst.coreMaps.size(); index++) {
+                if (persistenceInst.coreMaps.get(index).getMapID().equals(mapID)) {
+                    mapDataGame = persistenceInst.coreMaps.get(index).getMapID();
+                }
+            }
+        }
+        else  {
+            for (int index = 0; index < persistenceInst.communityMaps.size(); index++) {
+                if (persistenceInst.communityMaps.get(index).getMapID().equals(mapID)) {
+                    mapDataGame = persistenceInst.coreMaps.get(index).getMapID();
+                }
+            }
+        }
+    }
+
+    public void createCoreMapsList(){               //for dropdown list in "create" scene
+        coreMapsListLocal = new ArrayList<String>();
+        for(int i = 0; i < persistenceInst.coreMaps.size(); i++){
+            coreMapsListLocal.add(persistenceInst.coreMaps.get(i).getMapName() + " (" + persistenceInst.coreMaps.get(i).getMapID() + ")");
+        }
+    }
+
+    public void createLocalCommunityMapsList(){     //for dropdown list in "create" scene
+        communityMapsListLocal = new ArrayList<String>();
+        for (int i = 0; i < persistenceInst.communityMaps.size(); i++) {
+            communityMapsListLocal.add(persistenceInst.communityMaps.get(i).getMapName() + " (" + persistenceInst.communityMaps.get(i).getMapID() + ")");
+        }
+    }
+
+    public void createRemoteCommunityMapsList(){        //for Map-Browser
+        try {
+            communityMapsListRemote = persistenceInst.db.getCommunityMapsList();
+            log.info("MapList successfully retrieved from server!");
+            //log.info(communityMapsListRemote.get(0).getMapName());                 //for testing purposes
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/CryptoUtils.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/CryptoUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..757543af9f7227b44495bed77f991b06ca34716a
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/CryptoUtils.java
@@ -0,0 +1,159 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.CryptoException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.*;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+
+import java.nio.charset.StandardCharsets;
+
+
+public class CryptoUtils{
+    private static String parts[] = new String[2];
+    private static final String ALGORITHM = "AES";
+    private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
+    private static String key = "Peters Olivenöl";
+    private static String  encrypted_as_word = "encrypted;";
+    private static boolean alreadyencrypted = false;
+    private static boolean multipleencryptions = false;
+    private static int encryptionreturn;
+
+    private static final Logger log = LogManager.getLogger(CryptoUtils.class);
+
+
+    public static int encrypt(File inputFile,  boolean multipleencryptions) throws CryptoException {
+        alreadyencrypted = check_if_file_already_encrypted(inputFile);
+        if(multipleencryptions){
+            doCrypto(Cipher.ENCRYPT_MODE, key, inputFile);
+            log.info("This File can be encrypted multiple times");
+            return encryptionreturn = 0;
+        }
+        else if(!alreadyencrypted && !multipleencryptions){
+            doCrypto(Cipher.ENCRYPT_MODE, key, inputFile);
+            log.info("This File can only be encryptet once and this is now!");
+            return encryptionreturn = 1;
+        }else {
+            log.info("This file is already encrypted and doesnt need to be encrypted anymore! " + inputFile);
+            return encryptionreturn = 2;
+        }
+    }
+
+    public static String[] decrypt(File inputFile) throws CryptoException {
+        doCrypto(Cipher.DECRYPT_MODE, key, inputFile);
+        return parts;
+    }
+
+    private static String[] doCrypto(int cipherMode, String key, File inputFile) throws CryptoException {
+        try {
+            Key secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
+            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+            cipher.init(cipherMode, secretKey);
+
+            FileInputStream inputStream = new FileInputStream(inputFile);
+            byte[] inputBytes = new byte[(int) inputFile.length()];
+            inputStream.read(inputBytes);   //liest from inputstream into BufferArray
+
+            byte[] outputBytes = cipher.doFinal(inputBytes);
+
+            String completeString = new String(outputBytes, StandardCharsets.UTF_8);
+            //log.info("completeString/outputBytes: " + completeString);
+            parts = completeString.split(";");
+
+                if(cipherMode == Cipher.ENCRYPT_MODE){
+                    FileOutputStream outputStream = new FileOutputStream(inputFile);
+                    outputStream.write(outputBytes);//outputBytes
+                    outputStream.close();
+                    multipleencryptions = true;
+                }
+            inputStream.close();
+
+        } catch (NoSuchPaddingException | NoSuchAlgorithmException
+                 | InvalidKeyException | BadPaddingException
+                 | IllegalBlockSizeException | IOException ex) {
+            throw new CryptoException("Error encrypting/decrypting file", ex);
+        }
+        return parts;
+    }
+    public static boolean check_if_file_already_encrypted(File inputFile){
+        String filename =  inputFile.getName();
+        //log.info("filename: " + filename);
+            if(filename.contains(encrypted_as_word)){
+                return alreadyencrypted =true;
+            }
+        inputFile.renameTo(new File("src\\main\\resources\\database\\" + encrypted_as_word + filename));
+        return alreadyencrypted = false;
+    }
+
+       /*public static String[] doCrypto(int cipherMode, String key, File inputFile) throws CryptoException {
+        try {
+
+            String filename = inputFile.getName();
+            //String encrypted_as_word = "encrypted;";
+            byte[] encryptet_as_word_as_bytes = encrypted_as_word.getBytes();
+
+            Key secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
+            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
+            cipher.init(cipherMode, secretKey);
+
+            FileInputStream inputStream = new FileInputStream(inputFile);
+            byte[] inputBytes = new byte[(int) inputFile.length()];
+            inputStream.read(inputBytes);   //liest from inputstream into BufferArray
+
+            String inputbytes = new String(inputBytes, StandardCharsets.UTF_8);
+            String[] wellencrypted = inputbytes.split(";");
+
+            log.info("encrypted_as_word.substring(0,encrypted_as_word.length()-1): " + encrypted_as_word.substring(0,encrypted_as_word.length()-1));
+
+            if(wellencrypted[0].equals(encrypted_as_word.substring(0,encrypted_as_word.length()-1))){
+                wellencrypted = Arrays.copyOfRange(wellencrypted,1,wellencrypted.length);
+                inputBytes = wellencrypted[0].getBytes();
+                log.info("Das Wort encrypted ist enthalten!");
+                log.info("inputBytes: " + new String(inputBytes, StandardCharsets.UTF_8));
+
+            }
+            log.info("wellencrypted[0]: " +wellencrypted[0]);
+            log.info("wel[0]: " + wel[0]);
+             log.info("inputbytes: " + inputbytes);
+            log.info("inputBytes: " + new String(inputBytes, StandardCharsets.UTF_8));
+
+            byte[] outputBytes = cipher.doFinal(inputBytes);
+
+
+            String completeString = new String(outputBytes, StandardCharsets.UTF_8);
+            log.info("completeString/outputBytes: " + completeString);
+            parts = completeString.split(";");
+
+                if(cipherMode == Cipher.ENCRYPT_MODE){
+                    FileOutputStream outputStream = new FileOutputStream(inputFile);
+                    ByteArrayOutputStream outputStream12 = new ByteArrayOutputStream( );
+                    outputStream12.write(encryptet_as_word_as_bytes);
+                    outputStream12.write(outputBytes);
+                    byte combined[] = outputStream12.toByteArray( );
+                    String combinedbytes = new String(combined, StandardCharsets.UTF_8);
+                    log.info("combined: " + combinedbytes);
+
+
+                    outputStream.write(combined);//outputBytes
+
+                    outputStream.close();
+                }
+
+            inputStream.close();
+
+        } catch (NoSuchPaddingException | NoSuchAlgorithmException
+                 | InvalidKeyException | BadPaddingException
+                 | IllegalBlockSizeException | IOException ex) {
+            throw new CryptoException("Error encrypting/decrypting file", ex);
+        }
+        return parts;
+    }*/
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/HashGenerator.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/HashGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6bead225f6a2d53dd83766c6af73a6204be0afc
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/HashGenerator.java
@@ -0,0 +1,26 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class HashGenerator {
+
+    private static final Logger log = LogManager.getLogger(HashGenerator.class);
+
+    public static String hashAndHex(String input) throws NoSuchAlgorithmException {
+        //Generates SHA1 Hash from input string and converts bytes from hash to hexadecimal resulting in hexadecimal String
+        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
+        byte[] sha1Hash = sha1.digest((input).getBytes());
+        String result = "";
+        for (int i=0; i < sha1Hash.length; i++) {
+            result +=
+                    Integer.toString( ( sha1Hash[i] & 0xff ) + 0x100, 16).substring( 1 );
+        }
+        return result;
+    }
+
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..4ccec6fc0d9eb8956792cdcc5290cbc1455dae10
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java
@@ -0,0 +1,194 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Parser {
+
+    /*
+    Includes public static Parser methods for:
+    -username + password fields when creating account or logging in with existing credentials
+    -map name, when creating map
+    -IP-address field when joining game
+    -Map-name or map-ID, when searching for a map
+    -Parser for mapData from newly created map (length, formatting (spaces), tile-types, border-tiles etc.)
+    */
+
+    public static void usernameValid(String username) throws ParserException {
+
+        if(username.length() < 4){
+            throw new ParserException("Username too short! Min length is 4 characters.");
+        }
+        if(username.length() > 40){
+            throw new ParserException("Username too long! Max length is 40 characters.");
+        }
+
+        Pattern pat = Pattern.compile("[^a-z0-9_-]", Pattern.CASE_INSENSITIVE);
+        Matcher mat = pat.matcher(username);
+        boolean result = mat.find();
+        if(result){
+            throw new ParserException("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !");
+        }
+    }
+
+    public static void passwordValid(String password) throws ParserException {
+
+        if(password.length() < 4){
+            throw new ParserException("Password too short! Min length is 4 characters.");
+        }
+        if(password.length() > 40){
+            throw new ParserException("Password too long! Max length is 40 characters.");
+        }
+
+        Pattern pat = Pattern.compile("[^a-z0-9_-]", Pattern.CASE_INSENSITIVE);
+        Matcher mat = pat.matcher(password);
+        boolean result = mat.find();
+        if(result){
+            throw new ParserException("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !");
+        }
+    }
+
+    public static void mapNameValid(String mapName) throws ParserException {
+
+        if(mapName.length() < 4){
+            throw new ParserException("Map-Name too short! Min length is 4 characters.");
+        }
+        if(mapName.length() > 30){
+            throw new ParserException("Map-Name too long! Max length is 30 characters.");
+        }
+
+        Pattern pat = Pattern.compile("[^a-z0-9_-]", Pattern.CASE_INSENSITIVE);
+        Matcher mat = pat.matcher(mapName);
+        boolean result = mat.find();
+        if(result){
+            throw new ParserException("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !");
+        }
+    }
+
+    public static void sha1HashValid(String mapID) throws ParserException {
+
+        if(!(mapID.length() == 40)){
+            throw new ParserException("Map-ID length not correct. Must have length of 40 characters!");
+        }
+
+        Pattern pat = Pattern.compile("[^a-f0-9]");         //maybe make case-insensitive -> letters can be uppercase and still be valid hex number
+        Matcher mat = pat.matcher(mapID);
+        boolean result = mat.find();
+        if(result){
+            throw new ParserException("Forbidden characters used! Map ID only consists out of letters a-f and/or numbers 0-9!");
+        }
+    }
+
+    public static void ipAddressValid(String address) throws ParserException {
+
+        if(address.equals("localhost")){
+            return;
+        }
+
+        if(address.length() > 15){
+            throw new ParserException("IP-Address too long. Must have length of 15 characters including octet dividers (.) !");
+        }
+
+        if(address.length() < 7){
+            throw new ParserException("IP-Address too short. Must have length of 7 characters including octet dividers (.) !");
+        }
+
+        if(address.charAt(0) == '.' | address.charAt(address.length()-1) == '.'){
+            throw new ParserException("IP-Address must not start nor end with octet dividers (.) !");
+        }
+
+        int counter = 0;
+        for(int i = 0; address.length() > i ; i++){
+            if(address.charAt(i) == '.'){
+                counter++;
+            }
+        }
+        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 (.))!");
+                }
+            }
+        }
+
+        counter = 0;
+        int[] positions = new int[5];
+        positions[0] = 0;
+        positions[4] = address.length();
+        for(int i = 0; address.length() > i ; i++){
+            if(address.charAt(i) == '.'){
+                counter++;
+                positions[counter] = i;
+            }
+        }
+        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!");
+            }
+            if(i < 3) {
+                positions[i + 1] = positions[i + 1] + 1;
+            }
+        }
+    }
+
+    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!");
+        }
+
+        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!");
+            }
+        }
+
+        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!");
+            }
+        }
+
+        for(int i = 0; i < 18; i = i + 2){
+            if(!(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
+                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 = 0; i < 647; i = i + 2){
+            if(i % 36 == 0 && !(Integer.parseInt(mapData.substring(i, i+1)) == 3)){
+                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)){
+                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(578, 579)) == 1) | !(Integer.parseInt(mapData.substring(608, 609)) == 1)){
+            throw new ParserException("Map-Data corrupted - Player spawn must use walkable tile!");
+        }
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
new file mode 100644
index 0000000000000000000000000000000000000000..64e90f19dee42b333ff193b2041cbe3e29723604
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql
@@ -0,0 +1,75 @@
+--Note: DDL to be run as admin on MsSQL (AzureDB);
+--Backup SQL only for CoreMaps Download
+
+
+DROP TABLE coremaps;
+DROP TABLE communitymaps;
+DROP TABLE players;
+
+CREATE TABLE coremaps(
+                                         map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
+                                         map_name VARCHAR(30) NOT NULL,
+                                         map_width INTEGER NOT NULL,
+                                         map_height INTEGER NOT NULL,
+                                         map_data VARCHAR(1682) NOT NULL UNIQUE); --allows for map size up to 29x29
+
+CREATE TABLE communitymaps(
+                                              map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
+                                              map_name VARCHAR(30) NOT NULL,
+                                              map_width INTEGER NOT NULL,
+                                              map_height INTEGER NOT NULL,
+                                              map_data VARCHAR(1682) NOT NULL UNIQUE,  --allows for map size up to 29x29
+                                              map_downloads INTEGER NOT NULL);
+
+CREATE TABLE players(
+                                        player_name VARCHAR(40) NOT NULL UNIQUE, --Player name is PlayerID
+                                        player_pw VARCHAR(40) NOT NULL,
+                                        games_won INTEGER NOT NULL,
+                                        games_lost INTEGER NOT NULL,
+                                        kills INTEGER NOT NULL,
+                                        deaths INTEGER NOT NULL,
+                                        blocks_destroyed INTEGER NOT NULL,
+                                        ingame_time INTEGER NOT NULL);
+
+
+INSERT INTO coremaps (map_id, map_name, map_width, map_height, map_data)
+VALUES ('72e1c81687463ab159b4cb8d935e347a26d7fe40',
+        'Arena1',
+        18,
+        18,
+        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+
+INSERT INTO coremaps (map_id, map_name, map_width, map_height, map_data)
+VALUES ('f7e1fc56cefbacacb9ba403220476f3ac258de06',
+        'Arena2',
+        18,
+        18,
+        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 3 3 3 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+
+INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+VALUES ('c8ce8e85e4a9b99e4fa956e2486e55df73b2cf08',
+        'Arena1',
+        18,
+        18,
+        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3',
+        0);
+
+INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
+VALUES ('Player1',
+        'password',
+        18,
+        0,
+        80,
+        0,
+        140,
+        5000);
+
+INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
+VALUES ('Player2',
+        'password',
+        15,
+        3,
+        50,
+        5,
+        110,
+        6000);
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
new file mode 100644
index 0000000000000000000000000000000000000000..af8c0ca3e9ee71ca652b85f47c5ad018fa79725e
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_Oracle.sql
@@ -0,0 +1,92 @@
+--Note: DDL to be run as admin on OracleDB; Passwords for user accounts are not included and must be inserted before execution
+
+DROP TABLE battlearenadata.coremaps;
+DROP TABLE battlearenadata.communitymaps;
+DROP TABLE battlearenadata.players;
+
+DROP USER battlearenaplayer;
+DROP USER battlearenadata;
+
+CREATE USER battlearenaplayer IDENTIFIED BY "insertPasswordHere";
+CREATE USER battlearenadata IDENTIFIED BY "insertPasswordHere";
+
+GRANT CONNECT TO battlearenaplayer;
+
+CREATE TABLE battlearenadata.coremaps(
+                                         map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
+                                         map_name VARCHAR(30) NOT NULL,
+                                         map_width INTEGER NOT NULL,
+                                         map_height INTEGER NOT NULL,
+                                         map_data VARCHAR(1682) NOT NULL UNIQUE); --allows for map size up to 29x29
+
+CREATE TABLE battlearenadata.communitymaps(
+                                              map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
+                                              map_name VARCHAR(30) NOT NULL,
+                                              map_width INTEGER NOT NULL,
+                                              map_height INTEGER NOT NULL,
+                                              map_data VARCHAR(1682) NOT NULL UNIQUE,  --allows for map size up to 29x29
+                                              map_downloads INTEGER NOT NULL);
+
+CREATE TABLE battlearenadata.players(
+                        player_name VARCHAR(40) NOT NULL UNIQUE, --Player name is PlayerID
+                        player_pw VARCHAR(40) NOT NULL,
+                        games_won INTEGER NOT NULL,
+                        games_lost INTEGER NOT NULL,
+                        kills INTEGER NOT NULL,
+                        deaths INTEGER NOT NULL,
+                        blocks_destroyed INTEGER NOT NULL,
+                        ingame_time INTEGER NOT NULL);
+
+ALTER USER battlearenadata QUOTA 500M ON coremaps;
+ALTER USER battlearenadata QUOTA 500M ON communitymaps;
+ALTER USER battlearenadata QUOTA 500M ON players;
+
+INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data)
+VALUES ('72e1c81687463ab159b4cb8d935e347a26d7fe40',
+        'Arena1',
+        18,
+        18,
+        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+
+INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data)
+VALUES ('f7e1fc56cefbacacb9ba403220476f3ac258de06',
+        'Arena2',
+        18,
+        18,
+        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 3 3 3 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3');
+
+INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+VALUES ('c8ce8e85e4a9b99e4fa956e2486e55df73b2cf08',
+        'Arena1',
+        18,
+        18,
+        '3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3',
+        0);
+
+INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
+VALUES ('Player1',
+        'password',
+        18,
+        0,
+        80,
+        0,
+        140,
+        5000);
+
+INSERT INTO battlearenadata.players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)
+VALUES ('Player2',
+        'password',
+        15,
+        3,
+        50,
+        5,
+        110,
+        6000);
+
+GRANT SELECT ON battlearenadata.coremaps TO battlearenaplayer;
+
+GRANT SELECT, INSERT ON battlearenadata.communitymaps TO battlearenaplayer;
+
+GRANT SELECT, INSERT, UPDATE ON battlearenadata.players TO battlearenaplayer;
+
+GRANT UPDATE (map_downloads) ON battlearenadata.communitymaps  TO battlearenaplayer;
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Client.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Client.java
index 87189a54b8a83db73c96f74eee8e46702322b5f4..23b1c65ccd218152576cc9c7d366e68c65d1c591 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Client.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Client.java
@@ -12,7 +12,6 @@ public class Client {
     private PrintWriter out;
     private BufferedReader in;
 
-
     private static final Logger log = LogManager.getLogger(Client.class);
 
     public void startConnection(String ip, int port) throws IOException {
@@ -24,7 +23,7 @@ public class Client {
     public int[] sendcords(int[] cords) throws IOException {
         String message = String.join(",", Arrays.stream(cords).mapToObj(String::valueOf).toArray(String[]::new));
         out.println(message);
-        log.info("Sent coordinates: " + message);
+      //  log.info("Sent coordinates: " + message);
         String resp = in.readLine();
         return convertStringToArray(resp);
     }
@@ -42,7 +41,6 @@ public class Client {
         return result;
     }
 
-
     public void stopConnection() throws IOException {
         in.close();
         out.close();
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/ConnectionHandler.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/ConnectionHandler.java
index 67529ff1e0e3eb4cc9f2b0f01ef637a2190415e7..b47419daa11eea14e292ecab5dac7e0ae483f2b6 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/ConnectionHandler.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/ConnectionHandler.java
@@ -11,48 +11,57 @@ public class ConnectionHandler {
 
     private static int pX = 0;
     private static int pY = 0;
-    private int enemyX;
-    private int enemyY;
+    private static int enemyX = 0;
+    private static int enemyY = 0;
     private static int playerID = 0;
     private static int[] coordinates = {pX,pY,playerID};
-
+    private static String ipaddress = "localhost";
     private static final Logger log = LogManager.getLogger(ConnectionHandler.class);
 
-    public static void main(String[] args) throws IOException, InterruptedException {
+    public void startHandler() throws IOException, InterruptedException {
 
         Client client = new Client();
-        client.startConnection("localhost", 4444);
-        while (true){
-            int[] cords = client.sendcords(coordinates);
-            System.out.println("Enemy X: " + cords[0]);
-            System.out.println("Enemy Y: " + cords[1]);
-            System.out.println("Your PlayerID is " + cords[2]);
-            pX++;
-            pY++;
-            playerID = cords[2];
-            //Assign the Values to the message to send:
-            coordinates[0] = pX;
-            coordinates[1] = pY;
-            coordinates[2] = playerID;
-
-            TimeUnit.SECONDS.sleep(1);
-        }
+        client.startConnection(ipaddress, 4444);
+
+        ConnectionThread connectionthread = new ConnectionThread(client);
+        connectionthread.start();
 
-        //stop the connection:
-        //client.stopConnection();
     }
 
-    class ConnectionThread implements Runnable {
-        public void run() {
+    private static class ConnectionThread extends Thread {
+        private final Client client;
+
+        public ConnectionThread(Client client) {
+            this.client = client;
+        }
 
+        public void run() {
             try {
-                Thread.sleep(250);
-            } catch (InterruptedException e){
-                log.error("Error in Thread.sleep()");
+                while (!Thread.interrupted()) {
+                    int[] cords = client.sendcords(coordinates);
+                    enemyX = cords[0];
+                    enemyY = cords[1];
+                //    System.out.println("Enemy X: " + enemyX);
+                //    System.out.println("Enemy Y: " + enemyY);
+                //    System.out.println("Your PlayerID is " + cords[2]);
+                    playerID = cords[2];
+                    // Assign the Values to the message to send:
+                    coordinates[0] = pX;
+                    coordinates[1] = pY;
+                    coordinates[2] = playerID;
+
+                    Thread.sleep(16);
+                }
+            } catch (InterruptedException | IOException e) {
+                e.printStackTrace(); // Handle the exception as needed
             }
         }
     }
 
+    public int getPlayerID() {
+        return playerID;
+    }
+
     public int getpX() {
         return pX;
     }
@@ -72,17 +81,12 @@ public class ConnectionHandler {
     public int getEnemyX() {
         return enemyX;
     }
-
-    public void setEnemyX(int enemyX) {
-        this.enemyX = enemyX;
-    }
-
     public int getEnemyY() {
         return enemyY;
     }
 
-    public void setEnemyY(int enemyY) {
-        this.enemyY = enemyY;
+    public static void setIpaddress(String ipaddress) {
+        ConnectionHandler.ipaddress = ipaddress;
     }
 }
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Server.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Server.java
index e9226a37ba2b57a3d708a2f022e243b8f66d68da..fddc2fae68590bac4fc51d13f466b7bd8684012c 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Server.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/Server.java
@@ -23,18 +23,28 @@ public class Server {
     private static int playerID;
     private static int playercount = 0;
     private static int[] cords;
-
     private static int[] returncords = {enemyx,enemyy,playerID};
+    private boolean started = false;
+    private static String ipaddress = "localhost";
+
+//Uncomment these lines to test the server starting manually:
+  /*  public static void main(String[] args) throws IOException { //main method for testing purposes
+        Server server = new Server();
+        log.info("server starting...");
+        server.start(ipaddress, 4444);
+    } */
 
-    public static void main(String[] args) throws IOException {
+    //use this method to start the server from another class
+     public void startServer() throws IOException {
         Server server = new Server();
         log.info("server starting...");
-        server.start("localhost",4444);
+        server.start(ipaddress,4444);
     }
 
-    public void start(String localhost, int port) throws IOException {
+    public void start(String host_ip, int port) throws IOException {
         serverSocket = new ServerSocket(port);
         log.info("server started!");
+        started = true;
         while (true){
             new ServerHandler(serverSocket.accept()).start();
         }
@@ -132,7 +142,7 @@ public class Server {
                 } catch (IOException e) {
                     throw new RuntimeException(e);
                 }
-            }, 0, 250, TimeUnit.MILLISECONDS);
+            }, 0, 50, TimeUnit.MILLISECONDS);
         }
     }
 
@@ -145,4 +155,10 @@ public class Server {
         }
     }
 
+    public boolean isStarted() {
+        return started;
+    }
+    public static void setIpaddress(String ipaddress) {
+        Server.ipaddress = ipaddress;
+    }
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/TestMap.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/TestMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6d7fdf0800d787b23fb6df532afdb898733d53c
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Multiplayer/TestMap.java
@@ -0,0 +1,113 @@
+package de.hdm_stuttgart.battlearena.Model.Multiplayer;
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.input.KeyCode;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.Stage;
+import java.util.concurrent.TimeUnit;
+
+import java.io.IOException;
+
+public class TestMap extends Application {
+    private static final int SQUARE_SIZE = 50;
+    private static Rectangle square;
+    private static Rectangle enemy;
+    private Color color = Color.BLACK;
+
+    @Override
+    public void start(Stage primaryStage) throws IOException, InterruptedException {
+
+        ConnectionHandler handler = new ConnectionHandler();
+        handler.startHandler();
+
+        TimeUnit.SECONDS.sleep(1);
+
+        square = new Rectangle(SQUARE_SIZE, SQUARE_SIZE, color);
+        enemy = new Rectangle(SQUARE_SIZE, SQUARE_SIZE, color);
+
+        Pane root = new Pane();
+        root.getChildren().add(square);
+        root.getChildren().add(enemy);
+
+        Scene scene = new Scene(root, 400, 400);
+
+        scene.setOnKeyPressed(event -> handleKeyPress(event.getCode(), handler));
+
+        primaryStage.setTitle("Player #" + handler.getPlayerID());
+        primaryStage.setScene(scene);
+        primaryStage.show();
+
+        if(handler.getPlayerID() == 1){
+            square.setX(50);
+            square.setY(50);
+            enemy.setX(200);
+            enemy.setY(50);
+        } else if(handler.getPlayerID() == 2){
+            square.setX(200);
+            square.setY(50);
+            enemy.setX(50);
+            enemy.setY(50);
+        }
+
+        UpdateThread update = new UpdateThread(handler);
+        update.start();
+
+    }
+
+    private void handleKeyPress(KeyCode code, ConnectionHandler handler) {
+        switch (code) {
+            case UP:
+                square.setY(square.getY() - 20);
+                handler.setpY(handler.getpY() - 20);
+                break;
+            case DOWN:
+                square.setY(square.getY() + 20);
+                handler.setpY(handler.getpY() + 20);
+                break;
+            case LEFT:
+                square.setX(square.getX() - 20);
+                handler.setpX(handler.getpX() - 20);
+                break;
+            case RIGHT:
+                square.setX(square.getX() + 20);
+                handler.setpX(handler.getpX() + 20);
+                break;
+        }
+    }
+
+    private static class UpdateThread extends Thread {
+        private final ConnectionHandler handler;
+
+        private UpdateThread(ConnectionHandler handler) {
+            this.handler = handler;
+        }
+
+        public void run() {
+            while (true){
+
+                handler.setpX((int) square.getX());
+                handler.setpY((int) square.getY());
+
+                //receive cords
+                enemy.setX(handler.getEnemyX());
+                enemy.setY(handler.getEnemyY());
+
+
+                try {
+                    Thread.sleep(16);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+
+
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+            launch(args);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/DataBase.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/DataBase.java
deleted file mode 100644
index e766e18264ef67496e300c52199eae616e794db6..0000000000000000000000000000000000000000
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/DataBase.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.hdm_stuttgart.battlearena.Persistance;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-public class DataBase implements IDataBase{
-
-    private static final Logger log = LogManager.getLogger(DataBase.class);
-
-}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/IDataBase.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/IDataBase.java
deleted file mode 100644
index 17187e8f1400a7d8e1af04e9e33392998a38246c..0000000000000000000000000000000000000000
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/IDataBase.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package de.hdm_stuttgart.battlearena.Persistance;
-
-public interface IDataBase {
-}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index e154cc0323db15ac6a2b92f324888773b82f03e6..2350a517d6af6b0318a876694b89460514fc8e56 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -3,10 +3,16 @@ module gui {
     requires javafx.fxml;
     requires javafx.media;
     requires org.apache.logging.log4j;
+    requires java.sql;
+    requires com.google.gson;
+    requires com.oracle.database.jdbc;
+    requires java.naming;
 
 
     opens de.hdm_stuttgart.battlearena to javafx.fxml;
-    opens de.hdm_stuttgart.battlearena.Controller to javafx.fxml;
+    opens de.hdm_stuttgart.battlearena.Model.DataStorage.Classes to com.google.gson;
+    opens de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions to com.google.gson;
+    opens de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities to com.google.gson;
     exports de.hdm_stuttgart.battlearena.Main;
     exports de.hdm_stuttgart.battlearena.Controller;
     exports de.hdm_stuttgart.battlearena.Model.Entity;
diff --git a/src/main/resources/database/AzureDB_logindetails b/src/main/resources/database/AzureDB_logindetails
new file mode 100644
index 0000000000000000000000000000000000000000..88e4927a50d6dbc1bdf561cf31ab96067cc6286c
--- /dev/null
+++ b/src/main/resources/database/AzureDB_logindetails
@@ -0,0 +1 @@
+��z����%�\<��$�d<iA�pA5��ś]\&q<��#����ߤVr
\ No newline at end of file
diff --git a/src/main/resources/database/OracleDB_logindetails b/src/main/resources/database/OracleDB_logindetails
new file mode 100644
index 0000000000000000000000000000000000000000..231cb64d34a6d7c284298e353721a36b706e58d5
Binary files /dev/null and b/src/main/resources/database/OracleDB_logindetails differ
diff --git a/src/main/resources/database/document.encrypted b/src/main/resources/database/document.encrypted
new file mode 100644
index 0000000000000000000000000000000000000000..837a9fbcf781d32fe5ecb8608ad6a314235ba395
Binary files /dev/null and b/src/main/resources/database/document.encrypted differ
diff --git a/src/main/resources/database/encrypted;encryptiondecryptiontestFile.txt b/src/main/resources/database/encrypted;encryptiondecryptiontestFile.txt
new file mode 100644
index 0000000000000000000000000000000000000000..575b3c72b847f7e1e6e83c5d02a75fe9c5906c67
--- /dev/null
+++ b/src/main/resources/database/encrypted;encryptiondecryptiontestFile.txt
@@ -0,0 +1 @@
+Hier steht ein Testtext.
\ No newline at end of file
diff --git a/src/main/resources/database/encryptiondecryptiontestFile.txt b/src/main/resources/database/encryptiondecryptiontestFile.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4b7d67bb3df7989061607a0fd4a1869f4fbdda21
--- /dev/null
+++ b/src/main/resources/database/encryptiondecryptiontestFile.txt
@@ -0,0 +1 @@
+èkæÝ9z"²œÓF'ÙøŒ­®[4]ÙqŠð(/
\ No newline at end of file
diff --git a/src/main/resources/de/hdm_stuttgart/battlearena/config.properties b/src/main/resources/de/hdm_stuttgart/battlearena/config.properties
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..dbd084cebdb997732b0b641b24d6d1d4a64c1c55 100644
--- a/src/main/resources/de/hdm_stuttgart/battlearena/config.properties
+++ b/src/main/resources/de/hdm_stuttgart/battlearena/config.properties
@@ -0,0 +1,3 @@
+url=jdbc:sqlserver://battlearena.database.windows.net:1433;database=battleArena;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;
+user=battleArenaAdmin@battlearena;
+password=krassesRPGGame23#
diff --git a/src/main/resources/maps/communityMaps.json b/src/main/resources/maps/communityMaps.json
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/main/resources/maps/coreMaps.json b/src/main/resources/maps/coreMaps.json
new file mode 100644
index 0000000000000000000000000000000000000000..84828ae2b407d2ff4b089fdb479656a518e3a688
--- /dev/null
+++ b/src/main/resources/maps/coreMaps.json
@@ -0,0 +1,16 @@
+[
+  {
+    "mapID": "a593cafd1d061f0f463a2d2051bf4718aaaf5c48",
+    "mapName": "Arena1",
+    "mapWidth": 18,
+    "mapHeight": 18,
+    "mapData": "4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 1 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"
+  },
+  {
+    "mapID": "e559d8fbb53b333f5839cb3c6c0c515395afe344",
+    "mapName": "Arena2",
+    "mapWidth": 18,
+    "mapHeight": 18,
+    "mapData": "4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 2 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 3 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"
+  }
+]
\ No newline at end of file
diff --git a/src/main/resources/player/appSettings.json b/src/main/resources/player/appSettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/main/resources/player/playerAccount.json b/src/main/resources/player/playerAccount.json
new file mode 100644
index 0000000000000000000000000000000000000000..1cecf8373c050f15e816dae79f50e4b326d4f090
--- /dev/null
+++ b/src/main/resources/player/playerAccount.json
@@ -0,0 +1,5 @@
+{
+  "playerName": "Player1",
+  "accountPassword": "7c4a8d09ca3762af61e59520943dc26494f8941b",
+  "accountType": "ONLINE"
+}
\ No newline at end of file
diff --git a/src/main/resources/player/playerStatsLocal.json b/src/main/resources/player/playerStatsLocal.json
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/CryptoUtilsTest.java b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/CryptoUtilsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fe7a78190c6e19cc745d4aaec49d281970665cf
--- /dev/null
+++ b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/CryptoUtilsTest.java
@@ -0,0 +1,101 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
+
+//import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.CryptoException;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.CryptoException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.jupiter.api.*;
+
+import java.io.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class CryptoUtilsTest {
+    private static File encryptiondecryptiontestFile = new File("src\\main\\resources\\database\\encryptiondecryptiontestFile.txt");
+    private static File encryptedtestFile = new File("src\\main\\resources\\database\\encrypted;encryptedtestFile.txt");
+    private static boolean alreadyencrypted;
+    private static int encryptionreturn;
+    private static String text="";
+    private static String[] parts;
+    private static String testtext = "Hier steht ein Testtext.";
+    private static boolean multipleencryptions = false;
+    private static final Logger log = LogManager.getLogger(CryptoUtilsTest.class);
+
+    @BeforeEach
+    void beforeEachTest(TestInfo testInfo) {
+        log.info(() -> String.format("About to execute [%s]",
+                testInfo.getDisplayName()));
+    }
+    @AfterEach
+    void afterEachTest(TestInfo testInfo) {
+        log.info(() -> String.format("Finished executing [%s]",
+                testInfo.getDisplayName()));
+    }
+    @Test
+    void encryptDecryptiontest() throws IOException {
+        BufferedWriter writer = new BufferedWriter(new FileWriter(encryptiondecryptiontestFile));
+        writer.write(testtext);
+        writer.close();
+        try {
+            CryptoUtils.encrypt(encryptiondecryptiontestFile, true);
+            parts = CryptoUtils.decrypt(encryptiondecryptiontestFile);
+            text = parts[0];
+            System.out.println(text);
+        } catch (CryptoException ex) {
+            System.out.println(ex.getMessage());
+            ex.printStackTrace();
+        }
+        assertEquals(testtext,text);
+    }
+    @RepeatedTest(3)
+    void repeatedCheckFileEncryptingMultipleTimes() throws IOException {
+        BufferedWriter writer = new BufferedWriter(new FileWriter(encryptiondecryptiontestFile));
+        writer.write(testtext);
+        writer.close();
+        try {
+            encryptionreturn = CryptoUtils.encrypt(encryptiondecryptiontestFile, true);
+            parts = CryptoUtils.decrypt(encryptiondecryptiontestFile);
+            text = parts[0];
+            System.out.println(text);
+        } catch (CryptoException ex) {
+            System.out.println(ex.getMessage());
+            ex.printStackTrace();
+        }
+        assertEquals(encryptionreturn, 0);
+        assertEquals(testtext,text);            //Change
+    }
+    @Test
+    void checkFileEncryptingOnce() throws IOException {
+        BufferedWriter writer = new BufferedWriter(new FileWriter(encryptiondecryptiontestFile));
+        writer.write(testtext);
+        writer.close();
+        try {
+            encryptionreturn = CryptoUtils.encrypt(encryptiondecryptiontestFile, false);
+            parts = CryptoUtils.decrypt(encryptiondecryptiontestFile);
+            text = parts[0];
+            System.out.println(text);
+        } catch (CryptoException ex) {
+            System.out.println(ex.getMessage());
+            ex.printStackTrace();
+        }
+        assertEquals(encryptionreturn, 1);
+        assertEquals(testtext,text);        //Change
+    }
+    @Test
+    void checkIfFileAlreadyEncrypted(){
+        alreadyencrypted = CryptoUtils.check_if_file_already_encrypted(encryptedtestFile);
+        assertTrue(alreadyencrypted);
+    }
+    @Test
+    void checkIfFileNotYetEncrypted(){
+        alreadyencrypted = CryptoUtils.check_if_file_already_encrypted(encryptiondecryptiontestFile);
+        assertFalse(alreadyencrypted);
+    }
+    @Test
+    void exceptionTestingFileNotFound() {
+        CryptoException exception = assertThrows(CryptoException.class, () ->
+                CryptoUtils.decrypt(new File("src/main/resources/database/thisFileShouldn'tExist")));
+        assertEquals("Error encrypting/decrypting file", exception.getMessage());
+    }
+}
diff --git a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..62f0b705af1053613a39adfe2a296fc69099dd98
--- /dev/null
+++ b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java
@@ -0,0 +1,166 @@
+package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities;
+
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.*;
+class ParserTest {
+
+
+    @ParameterizedTest
+    @ValueSource(strings = {"Player1",
+                            "Player2",
+                            "HelloWorld"})
+    void usernameValid(String test){
+        assertDoesNotThrow(() -> Parser.usernameValid(test));
+    }
+
+    @Test
+    void usernameValidException() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("hi"));
+        assertTrue(testMe.getMessage().contains("Username too short! Min length is 4 characters."));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        assertTrue(testMe.getMessage().contains("Username too long! Max length is 40 characters."));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.usernameValid("SELECT * FROM"));
+        assertTrue(testMe.getMessage().contains("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !"));
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"pw123456",
+                            "Passwort",
+                            "lololol"})
+    void passwordValid(String test){
+        assertDoesNotThrow(() -> Parser.passwordValid(test));
+    }
+
+    @Test
+    void passwordValidException() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("hi"));
+        assertTrue(testMe.getMessage().contains("Password too short! Min length is 4 characters."));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        assertTrue(testMe.getMessage().contains("Password too long! Max length is 40 characters."));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.passwordValid("SELECT * FROM"));
+        assertTrue(testMe.getMessage().contains("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !"));
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"Map_1",
+                            "de_dust",
+                            "Ziba-Tower"})
+    void mapNameValid(String test){
+        assertDoesNotThrow(() -> Parser.mapNameValid(test));
+    }
+
+    @Test
+    void mapNameValidException() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("hi"));
+        assertTrue(testMe.getMessage().contains("Map-Name too short! Min length is 4 characters."));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        assertTrue(testMe.getMessage().contains("Map-Name too long! Max length is 30 characters."));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapNameValid("SELECT * FROM"));
+        assertTrue(testMe.getMessage().contains("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !"));
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"a593cafd1d061f0f463a2d2051bf4718aaaf5c48",
+                            "e559d8fbb53b333f5839cb3c6c0c515395afe344",
+                            "a593cafd1d061f0f463a2d2051bf4718aaaf5c48"})
+    void mapIDValid(String test){
+        assertDoesNotThrow(() -> Parser.sha1HashValid(test));
+    }
+
+    @Test
+    void mapIDValidException() {
+
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.sha1HashValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi"));
+        assertTrue(testMe.getMessage().contains("Map-ID length not correct. Must have length of 40 characters!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.sha1HashValid("XYZ3cafd1d061f0f463a2d2051bf4718aaaf5c48"));
+        assertTrue(testMe.getMessage().contains("Forbidden characters used! Map ID only consists out of letters a-f and/or numbers 0-9!"));
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"255.255.255.255",
+                            "0.0.0.0",
+                            "12.12.12.1",
+                            "localhost"})
+    void ipAddressValid(String test){
+        assertDoesNotThrow(() -> Parser.ipAddressValid(test));
+    }
+
+    @Test
+    void ipAddressValidException() {
+
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("255.255.255.255.255.255"));
+        assertTrue(testMe.getMessage().contains("IP-Address too long. Must have length of 15 characters including octet dividers (.) !"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("0.0.0"));
+        assertTrue(testMe.getMessage().contains("IP-Address too short. Must have length of 7 characters including octet dividers (.) !"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid(".25.255.25."));
+        assertTrue(testMe.getMessage().contains("IP-Address must not start nor end with octet dividers (.) !"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("12.3.0.12.12"));
+        assertTrue(testMe.getMessage().contains("IP-Address must contain exactly 3 octet dividers (.) !"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("255.ff.12.12"));
+        assertTrue(testMe.getMessage().contains("IP address does not consist out of numbers 0-9 and separators (.))!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.ipAddressValid("2555.800.12.12"));
+        assertTrue(testMe.getMessage().contains("Octets of IP-address must not exceed 255!"));
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3",
+                            "3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 3 3 3 1 1 1 3 1 1 3 3 1 1 1 1 1 3 1 1 1 1 1 1 1 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 1 1 1 1 1 3 3 3 1 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3",
+                            "3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"})
+    void mapDataValid(String test){
+        assertDoesNotThrow(() -> Parser.mapDataValid(test));
+    }
+
+    @Test
+    void mapDataValidException() {
+        ParserException testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("hi"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must have length of 647 chars including spaces!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3a3a3a3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - must use space every other character!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 8 9 7 7 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Tile number must be between 1 and 4!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Top-Line must be border tiles!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 1 1 1 1 1 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Bottom-Line must be border tiles!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Left Edge must be border tiles!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Right Edge must be border tiles!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+
+        testMe = assertThrows(ParserException.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3"));
+        assertTrue(testMe.getMessage().contains("Map-Data corrupted - Player spawn must use walkable tile!"));
+
+    }
+
+}
\ No newline at end of file