From a03b330ee9e70cf918d441d95c4430ae46164cf0 Mon Sep 17 00:00:00 2001
From: Martin <ms618@hdm-stuttgart.de>
Date: Tue, 19 Dec 2023 21:20:18 +0100
Subject: [PATCH] Add: AccountState.java (Enum to describe type of account
 player has created) Add: AppSettings.java (to store settings of application)
 Add: MapInfo.java (to store limited Information about CommunityMaps on SQL
 Server) Add: MapType.java (ENUM for Type of map - relevant for GsonHandler
 Class) Add: PlayerAccount.java (Class to store details about player account)
 Add: playerAccount.json (Player Account info stored locally encrypted) Add:
 playerStatsLocal.json (to store player statistics for local account) Add:
 appSettings.json (to store application settings in persistence) Update:
 DDL_Script_Oracle.sql (added lines for creating player statistics table)
 Update: GsonHandler.java (added methods for saving and loading
 playerStatistics, playerAccount, appSettings and moved file paths from
 "Persistence" class) Update: Persistence.java (added some methods, moved file
 paths from "Persistence" class) Update: RuntimeInfo.java (added some methods)

---
 .../Persistance/Classes/AccountState.java     |   9 ++
 .../Persistance/Classes/AppSettings.java      |  22 ++++
 .../Persistance/Classes/GsonHandler.java      | 110 ++++++++++++++++--
 .../Persistance/Classes/MapData.java          |   2 +-
 .../Persistance/Classes/MapInfo.java          |  50 ++++++++
 .../Persistance/Classes/MapType.java          |   8 ++
 .../Persistance/Classes/OracleDB.java         |   8 +-
 .../Persistance/Classes/Persistence.java      |  71 ++++++++---
 .../Persistance/Classes/PlayerAccount.java    |  28 +++++
 .../Persistance/Classes/RuntimeInfo.java      |  43 +++++--
 .../Scripts/DDL_Script_AzureDB.sql            |  10 +-
 .../Persistance/Scripts/DDL_Script_Oracle.sql |  46 +++++++-
 .../{playerStats.json => appSettings.json}    |   0
 src/main/resources/player/playerAccount.json  |   0
 .../resources/player/playerStatsLocal.json    |   0
 15 files changed, 355 insertions(+), 52 deletions(-)
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AccountState.java
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AppSettings.java
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapInfo.java
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapType.java
 create mode 100644 src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/PlayerAccount.java
 rename src/main/resources/player/{playerStats.json => appSettings.json} (100%)
 create mode 100644 src/main/resources/player/playerAccount.json
 create mode 100644 src/main/resources/player/playerStatsLocal.json

diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AccountState.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AccountState.java
new file mode 100644
index 00000000..c97d3d74
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AccountState.java
@@ -0,0 +1,9 @@
+package de.hdm_stuttgart.battlearena.Persistance.Classes;
+
+public enum AccountState {
+
+    NONE,
+    LOCAL,
+    ONLINE
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AppSettings.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AppSettings.java
new file mode 100644
index 00000000..a950b235
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AppSettings.java
@@ -0,0 +1,22 @@
+package de.hdm_stuttgart.battlearena.Persistance.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/Persistance/Classes/GsonHandler.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/GsonHandler.java
index f0ae2281..4fd108e0 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/GsonHandler.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/GsonHandler.java
@@ -17,29 +17,119 @@ public class GsonHandler {
 
     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();
 
-    public ArrayList<MapData> loadMaps(String filePath) throws DatabaseError{
+    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 DatabaseError{
+        String filePath;
+        if(type == MapType.COREMAP){
+            filePath = filePathCoreMaps;
+        }
+        else{
+            filePath = filePathCommunityMaps;
+        }
         try (FileReader reader = new FileReader(filePath)) {
-            ArrayList<MapData> maps = new ArrayList<MapData>();
-            maps = gson.fromJson(reader, mapDataType);
+            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 DatabaseError("Error Loading Maps!");
+            log.info("GSON - Loading maps from JSON failed");
+            throw new DatabaseError("Error loading maps!");
         }
     }
 
-    public void saveMaps(ArrayList<MapData> maps, String filePath) throws DatabaseError{
+    public void saveMaps(ArrayList<MapData> maps, MapType type) throws DatabaseError{
+        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) {
+        } catch (Exception e) {
+            log.info(e);
+            log.info("GSON - Saving maps to JSON failed");
+            throw new DatabaseError("Error saving maps!");
+        }
+    }
+
+    public PlayerStatistics loadStats() throws DatabaseError{
+        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 DatabaseError("Error loading player statistics!");
+        }
+    }
+
+    public void saveStats(PlayerStatistics stats) throws DatabaseError{
+        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 DatabaseError("Error saving player statistics!");
+        }
+    }
+
+    public AppSettings loadSettings() throws DatabaseError{
+        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 DatabaseError("Error Loading settings!");
+        }
+    }
+
+    public void saveSettings(AppSettings settings) throws DatabaseError{
+        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 DatabaseError("Error saving settings!");
+        }
+    }
+
+    public PlayerAccount loadAccount() throws DatabaseError{
+        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 DatabaseError("Error loading player account information!");
+        }
+    }
+
+    public void saveAccount(PlayerAccount account) throws DatabaseError{
+        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 Maps to JSON failed");
-            throw new DatabaseError("Error Loading Maps!");
+            log.info("GSON - Saving player account information to JSON failed");
+            throw new DatabaseError("Error loading player account information!");
         }
     }
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapData.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapData.java
index ccd39d5d..8153d35c 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapData.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapData.java
@@ -4,7 +4,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 public class MapData {
-    private static final Logger log = LogManager.getLogger(Persistence.class);
+    private static final Logger log = LogManager.getLogger(MapData.class);
 
     private String mapID;
     private String mapName;
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapInfo.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapInfo.java
new file mode 100644
index 00000000..9af17fed
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapInfo.java
@@ -0,0 +1,50 @@
+package de.hdm_stuttgart.battlearena.Persistance.Classes;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class MapInfo {
+
+    private static final Logger log = LogManager.getLogger(MapInfo.class);
+
+    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) {
+        try {
+            this.mapID = mapID;
+            this.mapName = mapName;
+            this.mapWidth = mapWidth;
+            this.mapHeight = mapHeight;
+            this.mapDownloads = mapDownloads;
+        }
+        catch (Exception e){
+            log.error(e);
+        }
+    }
+
+    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/Persistance/Classes/MapType.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapType.java
new file mode 100644
index 00000000..e1ec32ca
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapType.java
@@ -0,0 +1,8 @@
+package de.hdm_stuttgart.battlearena.Persistance.Classes;
+
+public enum MapType {
+
+    COREMAP,
+    COMMUNITYMAP
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/OracleDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/OracleDB.java
index 596c158b..b3f2eb45 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/OracleDB.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/OracleDB.java
@@ -57,17 +57,17 @@ public class OracleDB implements IDataBase {
         }
     }
 
-    public ArrayList<String> getCommunityMapsList() throws DatabaseError{
+    public ArrayList<MapInfo> getCommunityMapsList() throws DatabaseError{
         try(Connection connection = connect()) {
-            ArrayList<String> tempList = new ArrayList<String>();
-            String sql = "SELECT map_name FROM battlearenadata.communitymaps";
+            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(rs.getString("map_name"));
+                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();
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/Persistence.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/Persistence.java
index 527d13cc..85191446 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/Persistence.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/Persistence.java
@@ -11,18 +11,12 @@ 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();
-    private final DBalt sqlHandler = new DBalt(); //??
-    private Connection connection;          //??
+    protected OracleDB db = new OracleDB(); //evtl. Methoden von OracleDB static machen und von GSON Handler
     protected ArrayList<MapData> coreMaps;
     protected ArrayList<MapData> communityMaps;
-    private final String filePathCoreMaps = "src/main/resources/maps/coreMaps.json";
-    private final String filePathCommunityMaps = "src/main/resources/maps/communityMaps.json";
-    private int[] sizeArrayInt;             //??
-    private String sizeString;              //??
-    protected static PlayerStatistics statistics = new PlayerStatistics("", 0,0,0,0,0,0);
-    //suggestion: rename to "playerData"
-    protected OracleDB db = new OracleDB(); //for testing purposes; evtl. Methoden von OracleDB static machen und von GSON Handler
-
+    protected PlayerStatistics statistics;
+    protected PlayerAccount account;
+    private AppSettings settings;
 
 
 
@@ -34,8 +28,19 @@ public class Persistence {
 
     public void loadCoreMaps(){
         try {
-            coreMaps = gsonHandler.loadMaps(filePathCoreMaps);
-            log.info("Maps successfully loaded from file");
+            coreMaps = gsonHandler.loadMaps(MapType.COREMAP);
+            log.info("Core-Maps successfully loaded from file");
+            //log.info(coreMaps.get(0).getMapName());                 //for testing purposes
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+    public void loadCommunityMaps(){
+        try {
+            communityMaps = gsonHandler.loadMaps(MapType.COMMUNITYMAP);
+            log.info("Community-Maps successfully loaded from file");
             //log.info(coreMaps.get(0).getMapName());                 //for testing purposes
         }
         catch(Exception e){
@@ -46,7 +51,7 @@ public class Persistence {
     public void updateCoreMaps(){
         try {
             coreMaps = db.getCoreMaps();
-            gsonHandler.saveMaps(coreMaps, filePathCoreMaps);
+            gsonHandler.saveMaps(coreMaps, MapType.COREMAP);
             log.info("Maps successfully updated from SQL-Server");
             //log.info(coreMaps.get(0).getMapName());                 //for testing purposes
         }
@@ -58,7 +63,7 @@ public class Persistence {
     public void getCommunityMap(String mapSelected){
         try {
             communityMaps.add(db.getCommunityMapByID(mapSelected));
-            gsonHandler.saveMaps(communityMaps, filePathCommunityMaps);
+            gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
             log.info("Community Map successfully retrieved from SQL-Server!");
         }
         catch(Exception e){
@@ -70,18 +75,48 @@ public class Persistence {
         try {
             db.uploadCommunityMapByID(map);
             communityMaps.add(map);         //hier noch prüfen, ob die Map lokal bereits existiert (falls eine Verbindung zur DB scheitern sollte, kann man sie dennoch lokal speichern
-            gsonHandler.saveMaps(communityMaps, filePathCommunityMaps);
-            log.info("Maps successfully updated from SQL-Server!");
+            gsonHandler.saveMaps(communityMaps, MapType.COMMUNITYMAP);
+            log.info("Community-Maps successfully published");
         }
         catch(Exception e){
             log.error(e);
         }
     }
 
-    public void createPlayer (){
+    public void loadSettings(){
+        try {
+            settings = gsonHandler.loadSettings();
+            log.info("Application settings successfully loaded from file");
+            //log.info(coreMaps.get(0).getMapName());                 //for testing purposes
+        }
+        catch(Exception e){
+            log.error(e);
+        }
+    }
+
+    public void loadPlayerAccount() {
+        try {
+            account = gsonHandler.loadAccount();
+            //hier muss dann Entschlüsselung stattfinden, da GSON zuerst die verschlüsselten Accountdaten (Passwort und Username) als String speichert
+        }
+        catch(Exception e){
+                log.error(e);
+            }
     }
 
-    public void loadStatistics(){
+    public void loadPlayerStatistics(){
+        try {
+            if (account.getAccountState() == AccountState.NONE) {
+                //error - user must create account
+            } else if (account.getAccountState() == AccountState.LOCAL) {
+                statistics = gsonHandler.loadStats();
+            } else {
+                //load stats from SQL with playername
+            }
+        }
+        catch(Exception e){
+            log.error(e);
+        }
     }
 
 }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/PlayerAccount.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/PlayerAccount.java
new file mode 100644
index 00000000..46a63c5f
--- /dev/null
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/PlayerAccount.java
@@ -0,0 +1,28 @@
+package de.hdm_stuttgart.battlearena.Persistance.Classes;
+
+public class PlayerAccount {
+
+    private String playerName;
+    private String accountPassword;
+    private AccountState accountState;
+
+
+    public PlayerAccount(String playerName, String accountPassword, AccountState accountState) {
+        this.playerName = playerName;
+        this.accountPassword = accountPassword;
+        this.accountState = accountState;
+    }
+
+    public String getPlayerName() {
+        return playerName;
+    }
+
+    public String getAccountPassword() {
+        return accountPassword;
+    }
+
+    public AccountState getAccountState() {
+        return accountState;
+    }
+
+}
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/RuntimeInfo.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/RuntimeInfo.java
index f20d3f53..c25901ca 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/RuntimeInfo.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/RuntimeInfo.java
@@ -12,16 +12,14 @@ public class RuntimeInfo {
     private static final RuntimeInfo runtimeInfoSingleton = new RuntimeInfo();
     private final Persistence persistenceInst = Persistence.getInstance();
     private LinkedHashMap<String, String> mapNames;
-    public MapData mapCreated;  //to store parsed Data from MapCreator for Upload to SQL
-    public String communityMapSelected;
+    protected MapData mapCreated;  //to store parsed Data from MapCreator for Upload to SQL
+    protected String communityMapSelected;
     protected ArrayList<String> coreMapsListLocal;
     protected ArrayList<String> communityMapsListLocal;
-    protected ArrayList<String> communityMapsListRemote;
+    protected ArrayList<MapInfo> communityMapsListRemote;
     protected String mapDataGame;
 
 
-
-
     private RuntimeInfo(){};
     public static RuntimeInfo getInstance(){
         return runtimeInfoSingleton;
@@ -31,6 +29,31 @@ public class RuntimeInfo {
         return mapDataGame;
     }
 
+    public MapData getMapCreated() {
+        return mapCreated;
+    }
+
+    public void setMapCreated(MapData mapCreated) {
+        this.mapCreated = mapCreated;
+    }
+
+    public String getCommunityMapSelected() {
+        return communityMapSelected;
+    }
+
+    public void setCommunityMapSelected(String communityMapSelected) {
+        this.communityMapSelected = communityMapSelected;
+    }
+
+    public void startup(){
+        persistenceInst.loadPlayerAccount();  //must be called before "loadPlayerStatistics()"
+        //wenn playeraccunt type "none" ist, dann Create-Player scene und dafür noch eine "Create account" methode schreiben, die dann auch die Daten mit GSON speichert (verschlüsselt)
+        persistenceInst.loadSettings();
+        persistenceInst.loadCoreMaps();
+        persistenceInst.loadCommunityMaps();
+        persistenceInst.loadPlayerStatistics();
+    }
+
     private void setGameMap(String mapSelected, boolean choseCoremaps){
         mapSelected = mapSelected.substring(mapSelected.indexOf("(") + 1, mapSelected.length() - 1);
 
@@ -64,13 +87,13 @@ public class RuntimeInfo {
         //update SQL
     }
 
-    public void createCoreMapsList(){
+    public void createCoreMapsList(){               //for dropdown list in "create" scene
         for(int i = 0; i < persistenceInst.coreMaps.size(); i++){
             coreMapsListLocal.add(persistenceInst.coreMaps.get(i).getMapName() + " (" + persistenceInst.coreMaps.get(i).getMapID() + ")");
         }
     }
 
-    public void createCommunityMapsListLocal(){
+    public void createCommunityMapsListLocal(){     //for dropdown list in "create" scene
         try {
             for (int i = 0; i < persistenceInst.communityMaps.size(); i++) {
                 communityMapsListLocal.add(persistenceInst.communityMaps.get(i).getMapName() + " (" + persistenceInst.communityMaps.get(i).getMapID() + ")");
@@ -86,13 +109,17 @@ public class RuntimeInfo {
         try {
             communityMapsListRemote = persistenceInst.db.getCommunityMapsList();
             log.info("MapList successfully retrieved from server!");
-            log.info(communityMapsListRemote.get(0));                 //for testing purposes
+            log.info(communityMapsListRemote.get(0).getMapName());                 //for testing purposes
         }
         catch(Exception e){
             log.error(e);
         }
     }
 
+    public void updateStats(){
+        //after game round finished update stats locally and optional in remote
+    }
+
     public void getStatsByID(String playerID){
         //fetches from SQL stats by player with provided ID - players can display stats of other players in "Statistics" Scene
     }
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_AzureDB.sql b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_AzureDB.sql
index e3160edb..618539d3 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_AzureDB.sql
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_AzureDB.sql
@@ -1,7 +1,7 @@
 --Note: DDL to be run as admin on MsSQL (AzureDB);
+--Backup SQL only for CoreMaps Download
 
 DROP TABLE coremaps;
-DROP TABLE communitymaps;
 
 CREATE TABLE coremaps(
                                          map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex
@@ -10,13 +10,6 @@ CREATE TABLE coremaps(
                                          map_height INTEGER NOT NULL,
                                          map_data VARCHAR(1682) NOT NULL); --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);  --allows for map size up to 29x29
-
 INSERT INTO coremaps (map_id, map_name, map_width, map_height, map_data)
 VALUES ('a593cafd1d061f0f463a2d2051bf4718aaaf5c48',
         'Arena1',
@@ -30,4 +23,3 @@ VALUES ('e559d8fbb53b333f5839cb3c6c0c515395afe344',
         18,
         18,
         '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');
-
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_Oracle.sql b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_Oracle.sql
index aab3ddae..2cde9f0d 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_Oracle.sql
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_Oracle.sql
@@ -2,6 +2,7 @@
 
 DROP TABLE battlearenadata.coremaps;
 DROP TABLE battlearenadata.communitymaps;
+DROP TABLE battlearenadata.players;
 
 DROP USER battlearenaplayer;
 DROP USER battlearenadata;
@@ -23,10 +24,22 @@ CREATE TABLE battlearenadata.communitymaps(
                                               map_name VARCHAR(30) NOT NULL,
                                               map_width INTEGER NOT NULL,
                                               map_height INTEGER NOT NULL,
-                                              map_data VARCHAR(1682) NOT NULL);  --allows for map size up to 29x29
+                                              map_data VARCHAR(1682) NOT NULL,  --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 ('a593cafd1d061f0f463a2d2051bf4718aaaf5c48',
@@ -42,7 +55,36 @@ VALUES ('e559d8fbb53b333f5839cb3c6c0c515395afe344',
         18,
         '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');
 
+INSERT INTO battlearenadata.communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads)
+VALUES ('a593cafd1d061f0f463a2d2051bf4718aaaf5c48',
+        'Arena1',
+        18,
+        18,
+        '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',
+        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;
\ No newline at end of file
+GRANT SELECT, INSERT ON battlearenadata.communitymaps TO battlearenaplayer;
+
+GRANT SELECT, INSERT, UPDATE ON battlearenadata.players TO battlearenaplayer;
\ No newline at end of file
diff --git a/src/main/resources/player/playerStats.json b/src/main/resources/player/appSettings.json
similarity index 100%
rename from src/main/resources/player/playerStats.json
rename to src/main/resources/player/appSettings.json
diff --git a/src/main/resources/player/playerAccount.json b/src/main/resources/player/playerAccount.json
new file mode 100644
index 00000000..e69de29b
diff --git a/src/main/resources/player/playerStatsLocal.json b/src/main/resources/player/playerStatsLocal.json
new file mode 100644
index 00000000..e69de29b
-- 
GitLab