diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml index 202cd50f9c4409d6939d4254c8f800abdc8d38f1..8641bbfdf2e2a8e1ae8a5ddca2037e037e9e7899 100644 --- a/.idea/sqldialects.xml +++ b/.idea/sqldialects.xml @@ -1,10 +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/Persistance/Scripts/DDL_Script_Oracle.sql" dialect="AZURE" /> + <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> - <component name="SqlResolveMappings"> - <file url="file://$PROJECT_DIR$/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/DBalt.java" scope="{"node":{ "@negative":"1", "group":{ "@kind":"root", "node":{ "@negative":"1" } } }}" /> - </component> </project> \ No newline at end of file diff --git a/pom.xml b/pom.xml index 36eb916d13a61d55187df911e80f4a17af79d830..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> diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Exceptions/DatabaseError.java b/src/main/java/de/hdm_stuttgart/battlearena/Exceptions/DatabaseError.java deleted file mode 100644 index 3c2e953535ca48de2903cebcd893380cebe023af..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Exceptions/DatabaseError.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.hdm_stuttgart.battlearena.Exceptions; - -public class DatabaseError extends Exception{ - - public DatabaseError() {} - - public DatabaseError(String message2) - { - super(message2); - } - -} 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/Persistance/Classes/MapData.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapData.java similarity index 74% rename from src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapData.java rename to src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapData.java index ccd39d5d8cf3dba53a9fac07181fb0cc46dc617c..2a88a714ec211cc081dfb511673568de0d2ba6fd 100644 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/MapData.java +++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/MapData.java @@ -1,11 +1,6 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes; public class MapData { - private static final Logger log = LogManager.getLogger(Persistence.class); - private String mapID; private String mapName; private int mapWidth; //included for future use (to allow maps of different size) @@ -13,16 +8,11 @@ public class MapData { private String mapData; protected MapData(String mapID, String mapName, int mapWidth, int mapHeight, String mapData) { - try { this.mapID = mapID; this.mapName = mapName; this.mapWidth = mapWidth; this.mapHeight = mapHeight; this.mapData = mapData; - } - catch (Exception e){ - log.error(e); - } } public String getMapID() { 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/Persistance/Classes/PlayerStatistics.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java similarity index 69% rename from src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/PlayerStatistics.java rename to src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java index fc46205131b8ea5a2a2dd37d17823261eaad90fa..532324238dd5b1b7a19c8de5a0555bc3e2c83fba 100644 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/PlayerStatistics.java +++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/PlayerStatistics.java @@ -1,4 +1,4 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; +package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; @@ -6,16 +6,14 @@ import org.apache.logging.log4j.LogManager; public class PlayerStatistics { private static final Logger log = LogManager.getLogger(PlayerStatistics.class); - private String playerName; - private int gamesLost; - private int gamesWon; - private int kills; - private int deaths; - private int blocksDestroyed; - private int gameTime; + 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(String playerName, int gamesLost, int gamesWon, int kills, int deaths, int blocksDestroyed, int gameTime) { - this.playerName = playerName; + public PlayerStatistics(int gamesLost, int gamesWon, int kills, int deaths, int blocksDestroyed, int gameTime) { this.gamesLost = gamesLost; this.gamesWon = gamesWon; this.kills = kills; @@ -24,13 +22,6 @@ public class PlayerStatistics { this.gameTime = gameTime; } - public String getPlayerName() { - return playerName; - } - - public void setPlayerName(String playerName) { - this.playerName = playerName; - } public int getGamesLost() { return gamesLost; @@ -80,6 +71,4 @@ public class PlayerStatistics { 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/Persistance/Classes/AzureDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AzureDB.java deleted file mode 100644 index 7fca7c404662488c81f3c3e85c21e077d82d94dd..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/AzureDB.java +++ /dev/null @@ -1,86 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import de.hdm_stuttgart.battlearena.Exceptions.DatabaseError; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.ArrayList; - -public class AzureDB implements IDataBase{ - - /*this class is only here for showcasing the interchangeability of the DBMS*/ - - private static final Logger log = LogManager.getLogger(OracleDB.class); - - @Override - public Connection connect() throws DatabaseError { - try { - String url = "jdbc:sqlserver://battlearena.database.windows.net;encrypt=true;user=battleArenaAdmin;password=krassesRPGGame23#;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 DatabaseError("SQL Connection Error"); - } - } - - @Override - public ArrayList<MapData> getCoreMaps() throws DatabaseError{ - 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 DatabaseError("Error retrieving Coremaps"); - } - } - - public ArrayList<String> getCommunityMapsList() throws DatabaseError{ - try(Connection connection = connect()) { - ArrayList<String> tempList = new ArrayList<String>(); - String sql = "SELECT map_name FROM CommunityMaps"; - PreparedStatement stmt = connection.prepareStatement(sql); - - log.info("Sending SQL statement"); - ResultSet rs = stmt.executeQuery(); - - while(rs.next()){ - tempList.add(rs.getString("map_name")); - } - log.info("SQL query successful"); - rs.close(); - stmt.close(); - return tempList; - } - catch(Exception e){ - log.error(e); - throw new DatabaseError("Error retrieving MapList"); - } - } - - -} diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/DBalt.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/DBalt.java deleted file mode 100644 index ddb1c2ba3bd5aac87f5231a7c78ae45bd306da87..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/DBalt.java +++ /dev/null @@ -1,191 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - - -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Properties; -import java.sql.*; - -public class DBalt implements IDataBasealt { - - private static final Logger log = LogManager.getLogger(DBalt.class); - - - @Override - public Connection connect() throws IOException, SQLException { - - log.info("Loading the properties File!"); - Properties properties = new Properties(); - properties.load(getClass().getClassLoader().getResourceAsStream("config.properties")); - - log.info("Connecting to the database!"); - Connection connection = DriverManager.getConnection(properties.getProperty("url"), properties.getProperty("user"), properties.getProperty("password")); - log.info("Database connection test" + connection.getCatalog()); - - connection.setAutoCommit(true); - - return connection; - } - - - @Override - public void createNewPlayer(String playerName) throws SQLException, IOException { - try(Connection connection = connect()) { - String sql = "INSERT INTO players (player_name, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time)" + "VALUES (?,?,?,?,?,?,?)"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, playerName); - preparedStatement.setInt(2, 0); - preparedStatement.setInt(3, 0); - preparedStatement.setInt(4, 0); - preparedStatement.setInt(5, 0); - preparedStatement.setInt(6, 0); - preparedStatement.setInt(7, 0); - - log.info("Inserting new player"); - preparedStatement.execute(); - } - } - - @Override - public void createMap(String name, int length, int width, String mapData) throws SQLException, IOException { - try(Connection connection = connect()) { - String mapSize = length + "X" + width; - - String sql = "INSERT INTO battleArena.dbo.maps (map_name, map_size, map_data, map_version, map_hash) VALUES(?,?,?,?,?)"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, name); - preparedStatement.setString(2, mapSize); - preparedStatement.setString(3, mapData); - - log.info("Inserting new map"); - preparedStatement.execute(); - } - } - - @Override - public LinkedHashMap<String, String> getMapNames() throws SQLException, IOException { - LinkedHashMap<String, String> mapNames = new LinkedHashMap<>(); - - try(Connection connection = connect()) { - String sql = "SELECT maps.map_id, maps.map_name FROM maps"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - ResultSet results = preparedStatement.executeQuery(); - log.info("Getting map names"); - while (results.next()) { - mapNames.put(results.getString("map_id"), results.getString("map_name")); - } - connection.close(); - return mapNames; - } - } - - @Override - public String getMapByID(String ID) throws SQLException, IOException { - try(Connection connection = connect()) { - String sql = "SELECT map_name FROM maps WHERE map_id = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, ID); - log.info("Getting Map..."); - String map = preparedStatement.executeQuery().toString(); - return map; - } - } - - @Override - public String getMapSizeByID(String ID) throws SQLException, IOException { - try(Connection connection = connect()) { - String sql = "SELECT map_size FROM maps WHERE battleArena.dbo.maps.map_id=?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, ID); - ResultSet result = preparedStatement.executeQuery(); - log.info("getting map size..."); - String mapSize = result.getString("map_size"); - return mapSize; - } - } - - @Override - public ResultSet getStatistics(String playerName) throws SQLException, IOException { - try(Connection connection = connect()){ - String sql = "SELECT * FROM players where player_name = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, playerName); - ResultSet resultSet = preparedStatement.executeQuery(); - log.info("getting statistics..."); - return resultSet; - } - } - - @Override - public void updateMap(String mapID, String mapName, String mapData) throws SQLException, IOException { - try(Connection connection = connect()) { - String sql = "UPDATE maps SET map_name = ?, map_data = ? WHERE map_id = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, mapName); - preparedStatement.setString(2, mapData); - preparedStatement.setString(3, mapID); - preparedStatement.execute(); - log.info("updating map in Database"); - } - } - - - @Override - public void updatePlayerName(String playerNameNew, String playerNameOld) throws SQLException, IOException { - try(Connection connection = connect()){ - String sql = "UPDATE players SET player_name = ? WHERE player_name = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, playerNameNew); - preparedStatement.setString(2, playerNameOld); - preparedStatement.execute(); - log.info("updating player name in Database..."); - } - } - - @Override - public void updatePlayerStatistics(String playerName, int gamesWon, int gamesLost, int kills, int deaths, int blocksDestroyed, int gameTime) throws SQLException, IOException { - try (Connection connection = connect()){ - String sql = "UPDATE players SET games_won = ?, games_lost = ?, kills = ?, " + "deaths = ?, blocks_destroyed = ?, ingame_time = ? WHERE player_name = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setInt(1, gamesWon); - preparedStatement.setInt(2, gamesLost); - preparedStatement.setInt(3, kills); - preparedStatement.setInt(4, deaths); - preparedStatement.setInt(5, blocksDestroyed); - preparedStatement.setInt(6, gameTime); - preparedStatement.setString(7, playerName); - preparedStatement.execute(); - log.info("updating player statistics"); - - } - } - - - @Override - public void deletePlayer(String playerName) throws IOException, SQLException { - try(Connection connection = connect()) { - String sql = "DELETE FROM players WHERE player_name=?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, playerName); - preparedStatement.execute(); - log.info("deleting player"); - - } - } - - @Override - public void deleteMap(String mapID) throws SQLException, IOException { - try(Connection connection = connect()) { - String sql = "DELETE * FROM maps WHERE map_id = ?"; - PreparedStatement preparedStatement = connection.prepareStatement(sql); - preparedStatement.setString(1, mapID); - preparedStatement.execute(); - log.info("deleting map..."); - } - } - - -} 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 deleted file mode 100644 index f0ae2281b4bc5dc4c928ab622c1363d99ff21995..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/GsonHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.reflect.TypeToken; -import de.hdm_stuttgart.battlearena.Exceptions.DatabaseError; -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(); - - public ArrayList<MapData> loadMaps(String filePath) throws DatabaseError{ - try (FileReader reader = new FileReader(filePath)) { - ArrayList<MapData> maps = new 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!"); - } - } - - public void saveMaps(ArrayList<MapData> maps, String filePath) throws DatabaseError{ - 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 DatabaseError("Error Loading Maps!"); - } - } -} diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/IDataBase.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/IDataBase.java deleted file mode 100644 index cab1ba1463de1d506f2c5ea4b98affcb2f0c53d8..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/IDataBase.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import de.hdm_stuttgart.battlearena.Exceptions.DatabaseError; - -import java.sql.Connection; -import java.util.ArrayList; - -public interface IDataBase { - - Connection connect() throws DatabaseError; - - ArrayList<MapData> getCoreMaps() throws DatabaseError; - -} diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/IDataBasealt.java b/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/IDataBasealt.java deleted file mode 100644 index fbd43943e8c18c1a57b381107379bf018375d238..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/IDataBasealt.java +++ /dev/null @@ -1,42 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.LinkedHashMap; - -public interface IDataBasealt { - - //connection-Methods - Connection connect() throws IOException, SQLException; - - - //CRUD Operations - - //Create Operations - void createNewPlayer(String playerName) throws SQLException, IOException; - - void createMap(String name, int length, int width, String mapData) throws SQLException, IOException; - - //Read-operations - LinkedHashMap<String, String> getMapNames() throws SQLException, IOException; - String getMapByID(String ID) throws SQLException, IOException; - String getMapSizeByID(String ID) throws SQLException, IOException; - - - - ResultSet getStatistics(String playerName) throws SQLException, IOException; - - //Update-operations - void updateMap(String mapID , String mapName, String mapData) throws SQLException, IOException; - - void updatePlayerName(String playerNameNew, String PlayerNameOld) throws SQLException, IOException; - - void updatePlayerStatistics(String playerName, int gamesWon, int gamesLost, int kills, int deaths, int blocksDestroyed, int gameTime) throws SQLException, IOException; - - - //Delete-operations - void deletePlayer(String playerName) throws IOException, SQLException; - void deleteMap(String mapID) throws SQLException, IOException; -} 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 deleted file mode 100644 index 596c158beaa32fa2339fd8c56e44c39906d71e6d..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/OracleDB.java +++ /dev/null @@ -1,133 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import de.hdm_stuttgart.battlearena.Exceptions.DatabaseError; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.sql.*; -import java.util.ArrayList; -import java.util.Properties; - -import oracle.jdbc.pool.OracleDataSource; -import oracle.jdbc.OracleConnection; - -public class OracleDB implements IDataBase { - - private static final Logger log = LogManager.getLogger(OracleDB.class); - @Override - public Connection connect() throws DatabaseError{ - try { - 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("battlearenaplayer"); - ods.setPassword("jo3+++w3rw+s##AA"); - Connection conn = ods.getConnection(); - - log.info("Connecting to the database!"); - - return conn; - } - catch(Exception e){ - log.error(e); - throw new DatabaseError("SQL connection error"); - } - } - - @Override - public ArrayList<MapData> getCoreMaps() throws DatabaseError{ - 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 DatabaseError("Error retrieving coremaps"); - } - } - - public ArrayList<String> getCommunityMapsList() throws DatabaseError{ - try(Connection connection = connect()) { - ArrayList<String> tempList = new ArrayList<String>(); - String sql = "SELECT map_name 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")); - } - rs.close(); - stmt.close(); - log.info("Community map names retrieved successfully"); - return tempList; - } - catch(Exception e){ - log.error(e); - throw new DatabaseError("Error retrieving community map names"); - } - } - - public MapData getCommunityMapByID(String mapID) throws DatabaseError{ - 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(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"); - return mapChosen; - } - catch(Exception e){ - log.error(e); - throw new DatabaseError("Error retrieving community map"); - } - } - - public void uploadCommunityMapByID(MapData map) throws DatabaseError{ - 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 retrieved successfully"); - } - catch(Exception e){ - log.error(e); - throw new DatabaseError("Error uploading created community map"); - } - } - -/* - public void updateCommunityStats(Persistence persistence){ - //Update the commulative Stats - } -*/ - -} 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 deleted file mode 100644 index 527d13cc18f8c0024382033257fcb58be4335739..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/Persistence.java +++ /dev/null @@ -1,87 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.sql.Connection; -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(); - private final DBalt sqlHandler = new DBalt(); //?? - private Connection connection; //?? - 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 - - - - - private Persistence (){} - - public static Persistence getInstance(){ - return persistenceSingleton; - } - - public void loadCoreMaps(){ - try { - coreMaps = gsonHandler.loadMaps(filePathCoreMaps); - log.info("Maps successfully loaded from file"); - //log.info(coreMaps.get(0).getMapName()); //for testing purposes - } - catch(Exception e){ - log.error(e); - } - } - - public void updateCoreMaps(){ - try { - coreMaps = db.getCoreMaps(); - gsonHandler.saveMaps(coreMaps, filePathCoreMaps); - log.info("Maps successfully updated from SQL-Server"); - //log.info(coreMaps.get(0).getMapName()); //for testing purposes - } - catch(Exception e){ - log.error(e); - } - } - - public void getCommunityMap(String mapSelected){ - try { - communityMaps.add(db.getCommunityMapByID(mapSelected)); - gsonHandler.saveMaps(communityMaps, filePathCommunityMaps); - log.info("Community Map successfully retrieved from SQL-Server!"); - } - catch(Exception e){ - log.error(e); - } - } - - public void uploadCommunityMap(MapData map){ - 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!"); - } - catch(Exception e){ - log.error(e); - } - } - - public void createPlayer (){ - } - - public void loadStatistics(){ - } - -} 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 deleted file mode 100644 index f20d3f5359fb8b2baa6883de990fa0fb99aacc35..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Classes/RuntimeInfo.java +++ /dev/null @@ -1,100 +0,0 @@ -package de.hdm_stuttgart.battlearena.Persistance.Classes; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.LinkedHashMap; - -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(); - private LinkedHashMap<String, String> mapNames; - public MapData mapCreated; //to store parsed Data from MapCreator for Upload to SQL - public String communityMapSelected; - protected ArrayList<String> coreMapsListLocal; - protected ArrayList<String> communityMapsListLocal; - protected ArrayList<String> communityMapsListRemote; - protected String mapDataGame; - - - - - private RuntimeInfo(){}; - public static RuntimeInfo getInstance(){ - return runtimeInfoSingleton; - } - - public String getMapDataGame() { - return mapDataGame; - } - - private void setGameMap(String mapSelected, boolean choseCoremaps){ - mapSelected = mapSelected.substring(mapSelected.indexOf("(") + 1, mapSelected.length() - 1); - - if(choseCoremaps) { - for (int mapListIndex = 0; mapListIndex < persistenceInst.coreMaps.size(); mapListIndex++) { - if (persistenceInst.coreMaps.get(mapListIndex).getMapID().equals("mapSelected")) { - mapDataGame = persistenceInst.coreMaps.get(mapListIndex).getMapID(); - } - } - } - else { - for (int mapListIndex = 0; mapListIndex < persistenceInst.communityMaps.size(); mapListIndex++) { - if (persistenceInst.communityMaps.get(mapListIndex).getMapID().equals("mapSelected")) { - mapDataGame = persistenceInst.coreMaps.get(mapListIndex).getMapID(); - } - } - } - } - - public void getCommunityMap(){ - persistenceInst.getCommunityMap(communityMapSelected); - } - - public void uploadMapCreated(){ - persistenceInst.uploadCommunityMap(mapCreated); - } - //add Hash-Creator for creating map_ID and parse if map_data is according to specs - - private void updateStats(String outcome, String kills, String deaths, int gameTime){ - //update PlayerStatistics - //update SQL - } - - public void createCoreMapsList(){ - for(int i = 0; i < persistenceInst.coreMaps.size(); i++){ - coreMapsListLocal.add(persistenceInst.coreMaps.get(i).getMapName() + " (" + persistenceInst.coreMaps.get(i).getMapID() + ")"); - } - } - - public void createCommunityMapsListLocal(){ - try { - for (int i = 0; i < persistenceInst.communityMaps.size(); i++) { - communityMapsListLocal.add(persistenceInst.communityMaps.get(i).getMapName() + " (" + persistenceInst.communityMaps.get(i).getMapID() + ")"); - } - } - catch (Exception e){ - log.info(e); - } - } - //if no Data in JSON throw Exception and inform user - - public void fetchCommunityMapListRemote(){ - try { - communityMapsListRemote = persistenceInst.db.getCommunityMapsList(); - log.info("MapList successfully retrieved from server!"); - log.info(communityMapsListRemote.get(0)); //for testing purposes - } - catch(Exception e){ - log.error(e); - } - } - - 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 deleted file mode 100644 index e3160edb42558c0e634ee0ba4efc3fa29c979013..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_AzureDB.sql +++ /dev/null @@ -1,33 +0,0 @@ ---Note: DDL to be run as admin on MsSQL (AzureDB); - -DROP TABLE coremaps; -DROP TABLE communitymaps; - -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); --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', - 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'); - -INSERT INTO coremaps (map_id, map_name, map_width, map_height, map_data) -VALUES ('e559d8fbb53b333f5839cb3c6c0c515395afe344', - 'Arena2', - 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 deleted file mode 100644 index aab3ddaec52c271354f8f716b7f4d5e56cced707..0000000000000000000000000000000000000000 --- a/src/main/java/de/hdm_stuttgart/battlearena/Persistance/Scripts/DDL_Script_Oracle.sql +++ /dev/null @@ -1,48 +0,0 @@ ---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 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); --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); --allows for map size up to 29x29 - -ALTER USER battlearenadata QUOTA 500M ON coremaps; -ALTER USER battlearenadata QUOTA 500M ON communitymaps; - -INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data) -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'); - -INSERT INTO battlearenadata.coremaps (map_id, map_name, map_width, map_height, map_data) -VALUES ('e559d8fbb53b333f5839cb3c6c0c515395afe344', - 'Arena2', - 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'); - - -GRANT SELECT ON battlearenadata.coremaps TO battlearenaplayer; - -GRANT SELECT, INSERT ON battlearenadata.communitymaps TO battlearenaplayer; \ No newline at end of file diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 1a97b90a492f0829b9c187285fc7a83603bff975..709ade468a755a08cdc96ccb0e622f9f5e6effc6 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -10,7 +10,9 @@ module gui { opens de.hdm_stuttgart.battlearena to javafx.fxml; - opens de.hdm_stuttgart.battlearena.Persistance.Classes to com.google.gson; + 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.Multiplayer; 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/player/player.txt b/src/main/resources/player/appSettings.json similarity index 100% rename from src/main/resources/player/player.txt 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 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/playerStats.json b/src/main/resources/player/playerStatsLocal.json similarity index 100% rename from src/main/resources/player/playerStats.json rename to src/main/resources/player/playerStatsLocal.json 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