Merge pull request 'database-update-1' (#106) from database-update-1 into master
Reviewed-on: https://git.austinwhoover.com/gitadmin/Renderer/pulls/106
This commit is contained in:
		
						commit
						12900a9b26
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -27,3 +27,6 @@ | ||||
| #docs backup files | ||||
| /docs/~$NetworkFlow.drawio.bkp | ||||
| /docs/~$NetworkFlow.drawio.dtmp | ||||
| 
 | ||||
| #saves | ||||
| /saves/arena | ||||
|  | ||||
							
								
								
									
										7
									
								
								Scripts/auth/createAuthTables.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Scripts/auth/createAuthTables.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| 
 | ||||
| -- accounts definition | ||||
| CREATE TABLE accounts ( | ||||
| 	id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | ||||
| 	username TEXT NOT NULL, | ||||
| 	pwdhash TEXT NOT NULL | ||||
| ); | ||||
							
								
								
									
										3
									
								
								Scripts/auth/retrievePassHash.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Scripts/auth/retrievePassHash.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| 
 | ||||
| --given username=testusername | ||||
| SELECT pwdhash FROM accounts WHERE username='testusername'; | ||||
							
								
								
									
										10
									
								
								Scripts/character/createCharacterTables.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Scripts/character/createCharacterTables.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| 
 | ||||
| --characters | ||||
| --positions | ||||
| CREATE TABLE charaWorldPositions (playerId INTEGER PRIMARY KEY, id INTEGER, posX INTEGER, posY INTEGER); | ||||
| CREATE INDEX charaWorldPositionsIDIndex ON charaWorldPositions (id); | ||||
| CREATE INDEX charaWorldPositionsPosIndex ON charaWorldPositions (posX, posY); | ||||
| 
 | ||||
| --data | ||||
| CREATE TABLE charaData (playerId INTEGER PRIMARY KEY, id INTEGER, dataVal VARCHAR); | ||||
| CREATE INDEX charaDataIDIndex ON charaData (id); | ||||
| @ -3,36 +3,7 @@ | ||||
| CREATE TABLE mainTable (propName VARCHAR PRIMARY KEY, propValue VARCHAR); | ||||
| INSERT INTO mainTable (propName, propValue) VALUES ("ver","1"); | ||||
| 
 | ||||
| --characters | ||||
| --positions | ||||
| CREATE TABLE charaWorldPositions (id INTEGER PRIMARY KEY, charID INTEGER, posX INTEGER, posY INTEGER); | ||||
| CREATE INDEX charaWorldPositionsIDIndex ON charaWorldPositions (charID); | ||||
| CREATE INDEX charaWorldPositionsPosIndex ON charaWorldPositions (posX, posY); | ||||
| 
 | ||||
| --data | ||||
| CREATE TABLE charaData (id INTEGER PRIMARY KEY, charID INTEGER, dataVal VARCHAR); | ||||
| CREATE INDEX charaDataIDIndex ON charaData (charID); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| --towns | ||||
| --positions | ||||
| CREATE TABLE townWorldPositions (id INTEGER PRIMARY KEY, townID INTEGER, posX INTEGER, posY INTEGER); | ||||
| CREATE INDEX townWorldPositionsIDIndex ON townWorldPositions (townID); | ||||
| CREATE INDEX townWorldPositionsPosIndex ON townWorldPositions (posX, posY); | ||||
| 
 | ||||
| --data | ||||
| CREATE TABLE townData (id INTEGER PRIMARY KEY, townID INTEGER, dataVal VARCHAR); | ||||
| CREATE INDEX townDataIDIndex ON townData (townID); | ||||
| 
 | ||||
| 
 | ||||
| --structures | ||||
| --positions | ||||
| CREATE TABLE structWorldPositions (id INTEGER PRIMARY KEY, structID INTEGER, posX INTEGER, posY INTEGER); | ||||
| CREATE INDEX structWorldPositionsIDIndex ON structWorldPositions (structID); | ||||
| CREATE INDEX structWorldPositionsPosIndex ON structWorldPositions (posX, posY); | ||||
| 
 | ||||
| --data | ||||
| CREATE TABLE structData (id INTEGER PRIMARY KEY, structID INTEGER, dataVal VARCHAR); | ||||
| CREATE INDEX structDataIDIndex ON structData (structID); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										10
									
								
								Scripts/structs/createStructsTables.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Scripts/structs/createStructsTables.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| 
 | ||||
| --structures | ||||
| --positions | ||||
| CREATE TABLE structWorldPositions (id INTEGER PRIMARY KEY, structID INTEGER, posX INTEGER, posY INTEGER); | ||||
| CREATE INDEX structWorldPositionsIDIndex ON structWorldPositions (structID); | ||||
| CREATE INDEX structWorldPositionsPosIndex ON structWorldPositions (posX, posY); | ||||
| 
 | ||||
| --data | ||||
| CREATE TABLE structData (id INTEGER PRIMARY KEY, structID INTEGER, dataVal VARCHAR); | ||||
| CREATE INDEX structDataIDIndex ON structData (structID); | ||||
							
								
								
									
										10
									
								
								Scripts/towns/createTownsTables.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Scripts/towns/createTownsTables.sql
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| 
 | ||||
| --towns | ||||
| --positions | ||||
| CREATE TABLE townWorldPositions (id INTEGER PRIMARY KEY, townID INTEGER, posX INTEGER, posY INTEGER); | ||||
| CREATE INDEX townWorldPositionsIDIndex ON townWorldPositions (townID); | ||||
| CREATE INDEX townWorldPositionsPosIndex ON townWorldPositions (posX, posY); | ||||
| 
 | ||||
| --data | ||||
| CREATE TABLE townData (id INTEGER PRIMARY KEY, townID INTEGER, dataVal VARCHAR); | ||||
| CREATE INDEX townDataIDIndex ON townData (townID); | ||||
							
								
								
									
										162
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										162
									
								
								pom.xml
									
									
									
									
									
								
							| @ -12,111 +12,126 @@ | ||||
|         <lwjgl.version>3.2.3</lwjgl.version> | ||||
|         <joml.version>1.9.19</joml.version> | ||||
|     </properties> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <!-- https://mvnrepository.com/artifact/org.lwjgl/lwjgl --> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-assimp</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-glfw</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-opengl</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-opengles</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-openal</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-stb</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <!-- generic LWJGL runtimes --> | ||||
|         <!--License: BSD--> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
|         <!-- assimp runtimes --> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>import</scope> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!--ASSIMP--> | ||||
|         <!--License: BSD--> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-assimp</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-assimp</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
|         <!-- GLFW runtimes --> | ||||
| 
 | ||||
|         <!--GLFW--> | ||||
|         <!--License: BSD--> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-glfw</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-glfw</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
|         <!-- opengl runtimes --> | ||||
| 
 | ||||
|         <!--OpenGL--> | ||||
|         <!--License: BSD--> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-opengl</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-opengl</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
|         <!-- Embedded opengl runtimes --> | ||||
| 
 | ||||
|         <!--OpenGL ES--> | ||||
|         <!--License: BSD--> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-opengles</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-opengles</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
|         <!-- Audio runtimes --> | ||||
| 
 | ||||
|         <!--OpenAL--> | ||||
|         <!--License: BSD--> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-openal</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-openal</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!--STD--> | ||||
|         <!--License: BSD--> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-stb</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.lwjgl</groupId> | ||||
|             <artifactId>lwjgl-stb</artifactId> | ||||
|             <version>${lwjgl.version}</version> | ||||
|             <classifier>${lwjgl.natives}</classifier> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
|          | ||||
|         <!--JOML--> | ||||
|         <!--License: MIT--> | ||||
|         <dependency> | ||||
|             <groupId>org.joml</groupId> | ||||
|             <artifactId>joml</artifactId> | ||||
|             <version>${joml.version}</version> | ||||
|         </dependency> | ||||
| 
 | ||||
| 
 | ||||
|         <!--GSON--> | ||||
|         <!--License: Apache--> | ||||
|         <dependency> | ||||
|             <groupId>com.google.code.gson</groupId> | ||||
|             <artifactId>gson</artifactId> | ||||
|             <version>2.8.6</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!--jBulletFork--> | ||||
|         <!--License: ZLIB--> | ||||
|         <!-- | ||||
|         manual: http://www.cs.kent.edu/~ruttan/GameEngines/lectures/Bullet_User_Manual | ||||
|         because their docs ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/CylinderShape.html ) suck | ||||
| @ -128,22 +143,8 @@ | ||||
|             <version>0.1</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!-- | ||||
|         Potential alternative binding for bullet ? | ||||
|         <dependency> | ||||
|             <groupId>com.badlogicgames.gdx</groupId> | ||||
|             <artifactId>gdx-bullet</artifactId> | ||||
|             <version>1.10.0</version> | ||||
|         </dependency> | ||||
|         --> | ||||
| 
 | ||||
|         <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-crypto --> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.commons</groupId> | ||||
|             <artifactId>commons-crypto</artifactId> | ||||
|             <version>1.1.0</version> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <!--SQLITE-JDBC--> | ||||
|         <!--License: Apache--> | ||||
|         <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc --> | ||||
|         <dependency> | ||||
|             <groupId>org.xerial</groupId> | ||||
| @ -190,38 +191,7 @@ | ||||
|         </profile> | ||||
|     </profiles> | ||||
|     <build> | ||||
|         <resources> | ||||
|             <resource> | ||||
|                 <directory>${basedir}/src/main/resources</directory> | ||||
|                 <includes> | ||||
|                     <include>**/*</include> | ||||
|                 </includes> | ||||
|             </resource> | ||||
|         </resources> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <artifactId>maven-assembly-plugin</artifactId> | ||||
|                 <configuration> | ||||
|                     <archive> | ||||
|                         <manifest> | ||||
|                             <addClasspath>true</addClasspath> | ||||
|                             <mainClass>electrosphere.main.Main</mainClass> | ||||
|                         </manifest> | ||||
|                     </archive> | ||||
|                     <descriptorRefs> | ||||
|                         <descriptorRef>jar-with-dependencies</descriptorRef> | ||||
|                     </descriptorRefs> | ||||
|                 </configuration> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|                         <id>assemble-all</id> | ||||
|                         <phase>package</phase> | ||||
|                         <goals> | ||||
|                             <goal>single</goal> | ||||
|                         </goals> | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-shade-plugin</artifactId> | ||||
|  | ||||
| @ -1,11 +1,81 @@ | ||||
| package electrosphere.auth; | ||||
| 
 | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| import java.security.spec.InvalidKeySpecException; | ||||
| import java.security.spec.KeySpec; | ||||
| import java.util.Arrays; | ||||
| import java.util.Base64; | ||||
| 
 | ||||
| import javax.crypto.SecretKeyFactory; | ||||
| import javax.crypto.spec.PBEKeySpec; | ||||
| 
 | ||||
| import electrosphere.game.server.db.DatabaseResult; | ||||
| import electrosphere.game.server.db.DatabaseResultRow; | ||||
| import electrosphere.logger.LoggerInterface; | ||||
| import electrosphere.main.Globals; | ||||
| 
 | ||||
| public class AuthenticationManager { | ||||
|      | ||||
| 
 | ||||
|     public boolean authenticate(String username, String password){ | ||||
|         boolean rVal = true; | ||||
|         //TODO: actually authenticate | ||||
|         //first we hash the input password | ||||
|         String hashedPassword = getHashedString(password); | ||||
|         //then query the database for the username and hash for the input username | ||||
|         DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT id, username, pwdhash FROM accounts WHERE username=?;",username); | ||||
|         if(result.hasResult()){ | ||||
|             boolean foundRow = false; | ||||
|             //if we get a valid response from the database, check that it actually matches hashes | ||||
|             for(DatabaseResultRow row : result){ | ||||
|                 foundRow = true; | ||||
|                 String pwdhash = row.getAsString("pwdhash"); | ||||
|                 if(pwdhash.equals(hashedPassword)){ | ||||
|                     LoggerInterface.loggerAuth.INFO("Authenticated user " + username); | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|             //If we didn't find a single account, go ahead and create it | ||||
|             if(!foundRow){ | ||||
|                 LoggerInterface.loggerAuth.INFO("Created user " + username); | ||||
|                 Globals.dbController.executePreparedStatement("INSERT INTO accounts (username, pwdhash) VALUES(?, ?);",username,hashedPassword); | ||||
|                 //TODO: verify we created the account | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         LoggerInterface.loggerAuth.INFO("Failed to authenticate user " + username); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     static final int saltLength = 16; | ||||
|     public static String getHashedString(String input){ | ||||
|         String rVal = ""; | ||||
| 
 | ||||
|         //generate salt | ||||
|         char[] charArray = input.toCharArray(); | ||||
|         byte[] salt = new byte[saltLength]; | ||||
|         for(int i = 0; i < saltLength; i++){ | ||||
|             if(i < charArray.length){ | ||||
|                 salt[i] = (byte)charArray[i]; | ||||
|             } else { | ||||
|                 salt[i] = (byte)i; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         //perform hash | ||||
|         KeySpec spec = new PBEKeySpec(charArray, salt, 65536, 512); | ||||
|         try { | ||||
|             SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); | ||||
|             byte[] hash = f.generateSecret(spec).getEncoded(); | ||||
|             Base64.Encoder enc = Base64.getEncoder(); | ||||
|             // System.out.printf("salt: %s%n", enc.encodeToString(salt)); | ||||
|             // System.out.printf("hash: %s%n", enc.encodeToString(hash)); | ||||
|             // System.out.println(Arrays.toString(hash)); | ||||
|             rVal = enc.encodeToString(hash); | ||||
|         } catch (NoSuchAlgorithmException e) { | ||||
|             LoggerInterface.loggerAuth.ERROR("NoSuchAlgorithmException in hash string", e); | ||||
|         } catch (InvalidKeySpecException e) { | ||||
|             LoggerInterface.loggerAuth.ERROR("InvalidKeySpecException in hash string", e); | ||||
|         } | ||||
|          | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -773,7 +773,7 @@ public class ControlHandler { | ||||
|         controls.get(INPUT_CODE_CHARACTER_OPEN).setOnClick(new ControlMethod(){public void execute(){ | ||||
|             if(InventoryUtils.hasEquipInventory(Globals.playerEntity) && Globals.elementManager.getWindow(WindowStrings.WINDOW_CHARACTER) == null){ | ||||
|                 //create window | ||||
|                 Window mainMenuWindow = MenuGenerators.createCharacterMenu(InventoryUtils.getEquipInventory(Globals.playerEntity)); | ||||
|                 Window mainMenuWindow = MenuGenerators.createCharacterInventoryMenu(InventoryUtils.getEquipInventory(Globals.playerEntity)); | ||||
|                 //register | ||||
|                 Globals.elementManager.registerWindow(WindowStrings.WINDOW_CHARACTER, mainMenuWindow); | ||||
|                 //make visible | ||||
|  | ||||
| @ -36,6 +36,7 @@ import electrosphere.game.server.terrain.models.TerrainModification; | ||||
| import electrosphere.game.server.town.Town; | ||||
| import electrosphere.game.server.world.MacroData; | ||||
| import electrosphere.game.server.datacell.DataCellManager; | ||||
| import electrosphere.game.server.db.DatabaseUtils; | ||||
| import electrosphere.game.simulation.MicroSimulation; | ||||
| import electrosphere.logger.LoggerInterface; | ||||
| import electrosphere.main.Globals; | ||||
| @ -65,8 +66,12 @@ import electrosphere.game.server.unit.UnitUtils; | ||||
| import electrosphere.renderer.ui.DrawableElement; | ||||
| import electrosphere.renderer.ui.WidgetUtils; | ||||
| import electrosphere.renderer.ui.Window; | ||||
| import electrosphere.util.FileUtils; | ||||
| import electrosphere.util.Utilities; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Random; | ||||
| @ -183,6 +188,12 @@ public class LoadingThread extends Thread { | ||||
|                 initServerArenaWorldData(); | ||||
|                 //init data cell manager | ||||
|                 initDataCellManager(); | ||||
|                 //for testing purposes | ||||
|                 FileUtils.recursivelyDelete("/home/satellite/temp/saves/arena"); | ||||
|                 //init database connection | ||||
|                 SaveUtils.initSave("arena"); | ||||
|                 //connect to database | ||||
|                 SaveUtils.loadSave("arena"); | ||||
|                 //init authentication | ||||
|                 initAuthenticationManager(); | ||||
|                 //initialize the server thread (server only) | ||||
| @ -416,7 +427,6 @@ public class LoadingThread extends Thread { | ||||
|         Thread clientThread = null; | ||||
|         if(Globals.RUN_CLIENT){ | ||||
|             Globals.clientConnection = new ClientNetworking(NetUtils.getAddress(),NetUtils.getPort()); | ||||
|             System.out.println(Globals.clientConnection.socket); | ||||
|             clientThread = new Thread(Globals.clientConnection); | ||||
|             clientThread.start(); | ||||
|         } | ||||
|  | ||||
| @ -30,41 +30,74 @@ public class DatabaseController { | ||||
|             conn = DriverManager.getConnection(fullAddress, connectionProps); | ||||
|         } catch (SQLException ex) { | ||||
|             LoggerInterface.loggerFileIO.ERROR("Failure to connect to db", ex); | ||||
|             ex.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| //    public boolean executeStatement(String statementRaw){ | ||||
| //        boolean rVal = false; | ||||
| //        try { | ||||
| //            PreparedStatement statement = conn.prepareStatement(statementRaw); | ||||
| //            rVal = statement.execute(); | ||||
| //        } catch (SQLException ex) { | ||||
| //            LoggerInterface.loggerFileIO.ERROR("SQL statement execution error", ex); | ||||
| //        } | ||||
| //        return rVal; | ||||
| //    } | ||||
|      | ||||
|     public DatabaseResult executeStatement(String statementRaw){ | ||||
|         DatabaseResult rVal = DatabaseResult.createStatement(statementRaw); | ||||
|     /** | ||||
|      * Executes a write statement to the database | ||||
|      * @param statementRaw The raw string for the statement | ||||
|      * @param arguments The arguments to be inserted into the raw sql | ||||
|      */ | ||||
|     public boolean executePreparedStatement(String statementRaw, Object...arguments){ | ||||
|         try { | ||||
|             PreparedStatement statement = conn.prepareStatement(statementRaw); | ||||
|             statement.execute(); | ||||
|             ResultSet results = statement.getResultSet(); | ||||
|             if(results != null){ | ||||
|                 rVal.addResultSet(results); | ||||
|             //Set arguments for prepared statements | ||||
|             int argumentIndex = 1; | ||||
|             for(Object currentArg : arguments){ | ||||
|                 if(currentArg instanceof String){ | ||||
|                     statement.setString(argumentIndex, (String)currentArg); | ||||
|                 } else if(currentArg instanceof Integer){ | ||||
|                     statement.setInt(argumentIndex, (int)currentArg); | ||||
|                 } else if(currentArg instanceof Float){ | ||||
|                     statement.setFloat(argumentIndex, (float)currentArg); | ||||
|                 } else if(currentArg instanceof Boolean){ | ||||
|                     statement.setBoolean(argumentIndex, (boolean)currentArg); | ||||
|                 } else if(currentArg instanceof Long){ | ||||
|                     statement.setLong(argumentIndex, (long)currentArg); | ||||
|                 } else if(currentArg instanceof Double){ | ||||
|                     statement.setDouble(argumentIndex, (double)currentArg); | ||||
|                 } | ||||
|                 argumentIndex++; | ||||
|             } | ||||
|             //actually execute | ||||
|             return statement.execute(); | ||||
|         } catch (SQLException ex) { | ||||
|             rVal.succeeded = false; | ||||
|             rVal.hasResultSet = false; | ||||
|             LoggerInterface.loggerFileIO.ERROR("SQL statement execution error", ex); | ||||
|             LoggerInterface.loggerFileIO.ERROR("SQL query execution error", ex); | ||||
|         } | ||||
|         return rVal; | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     public DatabaseResult executeQuery(String statementRaw){ | ||||
|         DatabaseResult rVal = DatabaseResult.createStatement(statementRaw); | ||||
|     /** | ||||
|      * Executes a query against the database | ||||
|      * @param statementRaw The raw sql | ||||
|      * @param arguments The arguments to be injected into the raw sql | ||||
|      * @return A DatabaseResult representing the results of the query, or null if there was no result | ||||
|      */ | ||||
|     public DatabaseResult executePreparedQuery(String statementRaw, Object...arguments){ | ||||
|         DatabaseResult rVal = DatabaseResult.createQuery(statementRaw); | ||||
|         try { | ||||
|             PreparedStatement statement = conn.prepareStatement(statementRaw); | ||||
| 
 | ||||
|             //Set arguments for prepared statements | ||||
|             int argumentIndex = 1; | ||||
|             for(Object currentArg : arguments){ | ||||
|                 if(currentArg instanceof String){ | ||||
|                     statement.setString(argumentIndex, (String)currentArg); | ||||
|                 } else if(currentArg instanceof Integer){ | ||||
|                     statement.setInt(argumentIndex, (int)currentArg); | ||||
|                 } else if(currentArg instanceof Float){ | ||||
|                     statement.setFloat(argumentIndex, (float)currentArg); | ||||
|                 } else if(currentArg instanceof Boolean){ | ||||
|                     statement.setBoolean(argumentIndex, (boolean)currentArg); | ||||
|                 } else if(currentArg instanceof Long){ | ||||
|                     statement.setLong(argumentIndex, (long)currentArg); | ||||
|                 } else if(currentArg instanceof Double){ | ||||
|                     statement.setDouble(argumentIndex, (double)currentArg); | ||||
|                 } | ||||
|                 argumentIndex++; | ||||
|             } | ||||
|             //actually execute | ||||
|             ResultSet results = statement.executeQuery(); | ||||
|             if(results != null){ | ||||
|                 rVal.addResultSet(results); | ||||
| @ -79,6 +112,9 @@ public class DatabaseController { | ||||
|      | ||||
|     public boolean isConnected(){ | ||||
|         boolean rVal = false; | ||||
|         if(conn == null){ | ||||
|             return false; | ||||
|         } | ||||
|         try { | ||||
|             rVal = conn.isValid(100); | ||||
|         } catch (SQLException ex) { | ||||
|  | ||||
| @ -4,6 +4,7 @@ import com.google.gson.Gson; | ||||
| import electrosphere.logger.LoggerInterface; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.Iterator; | ||||
| import java.util.logging.Level; | ||||
| import java.util.logging.Logger; | ||||
| 
 | ||||
| @ -11,7 +12,8 @@ import java.util.logging.Logger; | ||||
|  * | ||||
|  * @author amaterasu | ||||
|  */ | ||||
| public class DatabaseResult { | ||||
| public class DatabaseResult implements Iterable<DatabaseResultRow> { | ||||
| 
 | ||||
|     boolean isQuery = false; | ||||
|     boolean isStatement = false; | ||||
|     boolean succeeded = false; | ||||
| @ -25,29 +27,30 @@ public class DatabaseResult { | ||||
|     } | ||||
|      | ||||
|      | ||||
|     public static DatabaseResult createQuery(String code){ | ||||
|     protected static DatabaseResult createQuery(String code){ | ||||
|         DatabaseResult rVal = new DatabaseResult(); | ||||
|         rVal.isQuery = true; | ||||
|         rVal.code = code; | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|     public static DatabaseResult createStatement(String code){ | ||||
|     protected static DatabaseResult createStatement(String code){ | ||||
|         DatabaseResult rVal = new DatabaseResult(); | ||||
|         rVal.isStatement = true; | ||||
|         rVal.code = code; | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|     public void addResultSet(ResultSet rs){ | ||||
|     protected void addResultSet(ResultSet rs){ | ||||
|         hasResultSet = true; | ||||
|         this.rs = rs; | ||||
|     } | ||||
|      | ||||
|     public ResultSet getResultSet(){ | ||||
|     protected ResultSet getResultSet(){ | ||||
|         return rs; | ||||
|     } | ||||
|      | ||||
|     public boolean hasResultSet(){ | ||||
|     public boolean hasResult(){ | ||||
|         return hasResultSet; | ||||
|     } | ||||
|      | ||||
| @ -77,4 +80,9 @@ public class DatabaseResult { | ||||
|      | ||||
|     public void logRawResult(){ | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public DatabaseResultIterator iterator() { | ||||
|         return new DatabaseResultIterator(rs); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,98 @@ | ||||
| package electrosphere.game.server.db; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.ResultSetMetaData; | ||||
| import java.sql.SQLException; | ||||
| import java.sql.Types; | ||||
| import java.util.Iterator; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import electrosphere.logger.LoggerInterface; | ||||
| 
 | ||||
| public class DatabaseResultIterator implements Iterator<DatabaseResultRow> { | ||||
| 
 | ||||
|     ResultSet rs; | ||||
|     ResultSetMetaData metadata; | ||||
|     List<Integer> typeList; | ||||
|      | ||||
|     /** | ||||
|      * Creates a result iterator -- used internal to package | ||||
|      * @param result | ||||
|      */ | ||||
|     protected DatabaseResultIterator(ResultSet result){ | ||||
|         this.rs = result; | ||||
|         try { | ||||
|             this.metadata = this.rs.getMetaData(); | ||||
|             int columnCount = metadata.getColumnCount(); | ||||
|             this.typeList = new LinkedList<Integer>(); | ||||
|             for(int i = 0; i < columnCount; i++){ | ||||
|                 //result sets are indexed starting at 1 | ||||
|                 this.typeList.add(metadata.getColumnType(i+1)); | ||||
|             } | ||||
|             //the sqlite driver doesn't support reverse navigation unfortunatelly | ||||
|             //if it did, we'd call this to be explicitly clear where we want to start | ||||
|             //instead the assumption is it always starts ON the first element | ||||
|             // this.rs.first(); | ||||
|         } catch (SQLException e) { | ||||
|             LoggerInterface.loggerEngine.ERROR("SQL Exception", e); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Lets us know if the result has a next value | ||||
|      */ | ||||
|     @Override | ||||
|     public boolean hasNext() { | ||||
|         try { | ||||
|             return !rs.isAfterLast(); | ||||
|         } catch (SQLException e) { | ||||
|             LoggerInterface.loggerEngine.ERROR("Critical failure in DatabaseResultIterator", e); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the next value in the result | ||||
|      */ | ||||
|     @Override | ||||
|     public DatabaseResultRow next() { | ||||
|         DatabaseResultRow row = new DatabaseResultRow(); | ||||
|         int columnIncrementer = 0; | ||||
|         //basically go through each type and add it to the row object that we return | ||||
|         //the types are stored in the typeList field on this object when it is created | ||||
|         try { | ||||
|             for(int type : typeList){ | ||||
|                 //increment at the beginning because result sets are indexed starting at 1 | ||||
|                 columnIncrementer++; | ||||
|                 switch(type){ | ||||
|                     case Types.INTEGER: | ||||
|                     row.putValue(metadata.getColumnName(columnIncrementer), rs.getInt(columnIncrementer)); | ||||
|                     break; | ||||
|                     case Types.VARCHAR: | ||||
|                     row.putValue(metadata.getColumnName(columnIncrementer), rs.getString(columnIncrementer)); | ||||
|                     break; | ||||
|                     case Types.BIGINT: | ||||
|                     row.putValue(metadata.getColumnName(columnIncrementer), rs.getLong(columnIncrementer)); | ||||
|                     break; | ||||
|                     case Types.FLOAT: | ||||
|                     row.putValue(metadata.getColumnName(columnIncrementer), rs.getFloat(columnIncrementer)); | ||||
|                     break; | ||||
|                     case Types.DOUBLE: | ||||
|                     row.putValue(metadata.getColumnName(columnIncrementer), rs.getDouble(columnIncrementer)); | ||||
|                     break; | ||||
|                     default: | ||||
|                     LoggerInterface.loggerEngine.WARNING("Unsupported type from database in DatabaseResultIterator " + type); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             //make sure to increment the result set so we don't infinitely loop the first element | ||||
|             this.rs.next(); | ||||
|         } catch (SQLException e){ | ||||
|             LoggerInterface.loggerEngine.ERROR("Unhandled SQL exception", e); | ||||
|         } | ||||
|         return row; | ||||
|     } | ||||
|      | ||||
| } | ||||
| @ -0,0 +1,76 @@ | ||||
| package electrosphere.game.server.db; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| public class DatabaseResultRow { | ||||
|      | ||||
|     // protected addColumn(int column) | ||||
| 
 | ||||
|     //stores all the values of the row in an easily indexible-by-column-name format | ||||
|     Map<String,Object> values = new HashMap<String,Object>(); | ||||
| 
 | ||||
|     /** | ||||
|      * Used internally for putting values into the row | ||||
|      * @param columnName | ||||
|      * @param value | ||||
|      */ | ||||
|     protected void putValue(String columnName, Object value){ | ||||
|         values.put(columnName,value); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the given value | ||||
|      * @param columnName the name of the column to check | ||||
|      * @return the value on said column | ||||
|      */ | ||||
|     public Object getValue(String columnName){ | ||||
|         return values.get(columnName); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the given value as a string | ||||
|      * @param columnName the name of the column to check | ||||
|      * @return the value on said column as a string | ||||
|      */ | ||||
|     public String getAsString(String columnName){ | ||||
|         return (String)values.get(columnName); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the given value as an integer | ||||
|      * @param columnName the name of the column to check | ||||
|      * @return the value on said column as an integer | ||||
|      */ | ||||
|     public int getAsInteger(String columnName){ | ||||
|         return (Integer)values.get(columnName); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the given value as a long | ||||
|      * @param columnName the name of the column to check | ||||
|      * @return the value on said column as a long | ||||
|      */ | ||||
|     public long getAsLong(String columnName){ | ||||
|         return (Long)values.get(columnName); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the given value as a float | ||||
|      * @param columnName the name of the column to check | ||||
|      * @return the value on said column as a float | ||||
|      */ | ||||
|     public float getAsFloat(String columnName){ | ||||
|         return (Float)values.get(columnName); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the given value as a double | ||||
|      * @param columnName the name of the column to check | ||||
|      * @return the value on said column as a double | ||||
|      */ | ||||
|     public double getAsDouble(String columnName){ | ||||
|         return (Double)values.get(columnName); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,6 +1,7 @@ | ||||
| package electrosphere.game.server.db; | ||||
| 
 | ||||
| import electrosphere.logger.LoggerInterface; | ||||
| import electrosphere.main.Globals; | ||||
| import electrosphere.util.FileUtils; | ||||
| import java.io.IOException; | ||||
| import java.util.logging.Level; | ||||
| @ -11,29 +12,58 @@ import java.util.logging.Logger; | ||||
|  * @author satellite | ||||
|  */ | ||||
| public class DatabaseUtils { | ||||
| 
 | ||||
|      | ||||
|     public static boolean initCentralDBFile(String path){ | ||||
|         String sanitizedPath = "." + FileUtils.sanitizeFilePath(path); | ||||
|         String sanitizedPath = FileUtils.sanitizeFilePath(path); | ||||
|         if(!FileUtils.checkFileExists(sanitizedPath)){ | ||||
|             return false; | ||||
|         } | ||||
|         String dbFilePath = sanitizedPath + "/central.db"; | ||||
|         DatabaseController controller = new DatabaseController(); | ||||
|         controller.connect(dbFilePath); | ||||
|         if(Globals.dbController == null){ | ||||
|             Globals.dbController = new DatabaseController(); | ||||
|         } | ||||
|         if(!Globals.dbController.isConnected()){ | ||||
|             Globals.dbController.connect(dbFilePath); | ||||
|         } | ||||
|         runScript(Globals.dbController,"createTables.sql"); | ||||
|         //both of these are used for arena mode as well as main game | ||||
|         runScript(Globals.dbController,"/auth/createAuthTables.sql"); | ||||
|         runScript(Globals.dbController,"/character/createCharacterTables.sql"); | ||||
|         //create adventure-only files | ||||
|         if(!dbFilePath.equals("./saves/arena/central.db")){ | ||||
|             //we only want to create these if we're not in arena mode | ||||
|             runScript(Globals.dbController,"/towns/createTownsTables.sql"); | ||||
|             runScript(Globals.dbController,"/structs/createStructsTables.sql"); | ||||
|         } | ||||
|         Globals.dbController.disconnect(); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     public static boolean runScript(DatabaseController controller, String scriptPath){ | ||||
|         String rawScript = ""; | ||||
|         try { | ||||
|             rawScript = FileUtils.getSQLScriptFileAsString("createTables.sql"); | ||||
|             rawScript = FileUtils.getSQLScriptFileAsString(scriptPath); | ||||
|         } catch (IOException ex) { | ||||
|             LoggerInterface.loggerEngine.ERROR("Failure reading create db script", ex); | ||||
|             return false; | ||||
|         } | ||||
|         String[] scriptLines = rawScript.split("\n"); | ||||
|         String accumulatorString = ""; | ||||
|         for(String line : scriptLines){ | ||||
|             if(line.length() > 1 && !line.startsWith("--")){ | ||||
|                 System.out.println("EXECUTE: " + line); | ||||
|                 controller.executeStatement(line); | ||||
|                 if(line.contains(";")){ | ||||
|                     accumulatorString = accumulatorString + line; | ||||
|                     System.out.println("EXECUTE: " + accumulatorString); | ||||
|                     controller.executePreparedStatement(accumulatorString); | ||||
|                     accumulatorString = ""; | ||||
|                 } else { | ||||
|                     accumulatorString = accumulatorString + line; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         controller.disconnect(); | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -16,7 +16,8 @@ import java.util.List; | ||||
| public class SaveUtils { | ||||
|      | ||||
|     static String deriveSaveDirectoryPath(String saveName){ | ||||
|         return "./saves/" + saveName; | ||||
|         String path = "/home/satellite/temp/saves/" + saveName; | ||||
|         return path; | ||||
|     } | ||||
|      | ||||
|     /** | ||||
| @ -61,8 +62,10 @@ public class SaveUtils { | ||||
|         String dirPath = deriveSaveDirectoryPath(saveName); | ||||
|         String dbFilePath = FileUtils.sanitizeFilePath(dirPath) + "/central.db"; | ||||
|         Globals.dbController.connect(dbFilePath); | ||||
|         if(!saveName.equals("arena")){ | ||||
|             Globals.serverTerrainManager.load(saveName); | ||||
|             Globals.serverWorldData = FileUtils.loadObjectFromSavePath(saveName, "world.json", ServerWorldData.class); | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|      | ||||
|  | ||||
| @ -2,6 +2,7 @@ package electrosphere.game.server.structure.virtual; | ||||
| 
 | ||||
| import com.google.gson.Gson; | ||||
| import electrosphere.game.server.db.DatabaseResult; | ||||
| import electrosphere.game.server.db.DatabaseResultRow; | ||||
| import electrosphere.logger.LoggerInterface; | ||||
| import electrosphere.main.Globals; | ||||
| import java.sql.ResultSet; | ||||
| @ -29,24 +30,19 @@ public class StructureManager { | ||||
|     public static Structure createStructure(int worldX, int worldY, float localX, float localY, String type){ | ||||
|         structIDIterator++; | ||||
|         Structure rVal = new Structure(worldX, worldY, localX, localY, type); | ||||
|         Globals.dbController.executeStatement("INSERT INTO structWorldPositions (structID,posX,posY) VALUES (" + structIDIterator + "," + worldX + "," + worldY + ");"); | ||||
|         Globals.dbController.executeStatement("INSERT INTO structData(structID,propName,propValue) VALUES(" + structIDIterator + ",'localX','" + localX + "');"); | ||||
|         Globals.dbController.executeStatement("INSERT INTO structData(structID,propName,propValue) VALUES(" + structIDIterator + ",'localY','" + localY + "');"); | ||||
|         Globals.dbController.executePreparedStatement("INSERT INTO structWorldPositions (structID,posX,posY) VALUES (?,?,?);",structIDIterator,worldX,worldY); | ||||
|         Globals.dbController.executePreparedStatement("INSERT INTO structData(structID,propName,propValue) VALUES(?,'localX','?');",structIDIterator,localX); | ||||
|         Globals.dbController.executePreparedStatement("INSERT INTO structData(structID,propName,propValue) VALUES(?,'localY','?');",structIDIterator,localY); | ||||
|         return rVal; | ||||
|     } | ||||
|      | ||||
|     public static List<Structure> getStructuresInChunk(int worldX, int worldY){ | ||||
|         List<Structure> rVal = new LinkedList<Structure>(); | ||||
|         DatabaseResult result = Globals.dbController.executeStatement("SELECT * FROM structWorldPositions WHERE posX = " + worldX + " AND posY = " + worldY + ";"); | ||||
|         DatabaseResult result = Globals.dbController.executePreparedQuery("SELECT * FROM structWorldPositions WHERE posX = ? AND posY = ?;",worldX,worldY); | ||||
|         List<Integer> returnedIDs = new LinkedList<Integer>(); | ||||
|         if(result.hasResultSet()){ | ||||
|             ResultSet positionSet = result.getResultSet(); | ||||
|             try { | ||||
|                 while(positionSet.next()){ | ||||
|                     returnedIDs.add(positionSet.getInt("structID")); | ||||
|                 } | ||||
|             } catch (SQLException ex) { | ||||
|                 LoggerInterface.loggerEngine.ERROR("Error looping through positions returned in StructureManager.getStructuresInChunk", ex); | ||||
|         if(result.success() && result.hasResult()){ | ||||
|             for(DatabaseResultRow row : result){ | ||||
|                 returnedIDs.add(row.getAsInteger("structID")); | ||||
|             } | ||||
|         } | ||||
|         if(returnedIDs.size() > 0){ | ||||
| @ -55,18 +51,12 @@ public class StructureManager { | ||||
|                 ids = ids + ID + ","; | ||||
|             } | ||||
|             ids = ids.substring(0, ids.length() - 1); | ||||
|             result = Globals.dbController.executeStatement("SELECT * FROM structData WHERE structID IN (" + ids + ");"); | ||||
|             if(result.success() && result.hasResultSet()){ | ||||
|                 ResultSet rs = result.getResultSet(); | ||||
|                 try { | ||||
|                     while(rs.next()){ | ||||
|                         String rawData = rs.getString("dataVal"); | ||||
|                         Structure newStruct = serializer.fromJson(rawData, Structure.class); | ||||
|             result = Globals.dbController.executePreparedQuery("SELECT * FROM structData WHERE structID IN (?);",ids); | ||||
|             if(result.success() && result.hasResult()){ | ||||
|                 for(DatabaseResultRow row : result){ | ||||
|                     Structure newStruct = serializer.fromJson(row.getAsString("dataVal"), Structure.class); | ||||
|                     rVal.add(newStruct); | ||||
|                 } | ||||
|                 } catch (SQLException ex) { | ||||
|                     LoggerInterface.loggerEngine.ERROR("Error looping through structures returned in StructureManager.getStructuresInChunk", ex); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return rVal; | ||||
|  | ||||
| @ -40,6 +40,7 @@ public class Logger { | ||||
|     public void ERROR(String message, Exception e){ | ||||
|         if(level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING || level == LogLevel.ERROR){ | ||||
|             System.out.println(message); | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -16,6 +16,7 @@ public class LoggerInterface { | ||||
|     public static Logger loggerRenderer; | ||||
|     public static Logger loggerEngine; | ||||
|     public static Logger loggerStartup; | ||||
|     public static Logger loggerAuth; | ||||
|      | ||||
|     public static void initLoggers(){ | ||||
|         loggerStartup = new Logger(LogLevel.WARNING); | ||||
| @ -24,6 +25,7 @@ public class LoggerInterface { | ||||
|         loggerGameLogic = new Logger(LogLevel.WARNING); | ||||
|         loggerRenderer = new Logger(LogLevel.WARNING); | ||||
|         loggerEngine = new Logger(LogLevel.WARNING); | ||||
|         loggerAuth = new Logger(LogLevel.INFO); | ||||
|         loggerStartup.INFO("Initialized loggers"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -176,6 +176,8 @@ public class Globals { | ||||
|     // | ||||
|     public static PlayerManager playerManager; | ||||
|     public static Player clientPlayer; | ||||
|     public static String clientUsername; | ||||
|     public static String clientPassword; | ||||
|      | ||||
|     // | ||||
|     //Generic OpenGL Statements | ||||
|  | ||||
| @ -4,6 +4,7 @@ import com.google.gson.Gson; | ||||
| import electrosphere.audio.AudioEngine; | ||||
| import electrosphere.audio.AudioSource; | ||||
| import electrosphere.audio.AudioUtils; | ||||
| import electrosphere.auth.AuthenticationManager; | ||||
| import electrosphere.controls.ControlHandler; | ||||
| import electrosphere.entity.types.creature.CreatureUtils; | ||||
| import electrosphere.renderer.Material; | ||||
| @ -48,9 +49,14 @@ import java.io.IOException; | ||||
| import java.nio.charset.Charset; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.StandardOpenOption; | ||||
| import java.security.Provider; | ||||
| import java.security.Security; | ||||
| import java.util.Scanner; | ||||
| import java.util.logging.Level; | ||||
| import java.util.logging.Logger; | ||||
| 
 | ||||
| import javax.crypto.Cipher; | ||||
| 
 | ||||
| import org.joml.Vector3d; | ||||
| 
 | ||||
| 
 | ||||
| @ -108,6 +114,16 @@ public class Main { | ||||
|         //init global variables | ||||
|         Globals.initGlobals(); | ||||
| 
 | ||||
|         // if(1==1){ | ||||
|         //     SaveUtils.loadSave("arena"); | ||||
|         //     Globals.authenticationManager = new AuthenticationManager(); | ||||
|         //     String rawPass = "testpassword"; | ||||
|         //     String hashedPassword = AuthenticationManager.getHashedString(rawPass); | ||||
|         //     boolean authed = Globals.authenticationManager.authenticate("testuser", hashedPassword); | ||||
|         //     System.out.println("Authenticated: " + authed); | ||||
|         //     System.exit(0); | ||||
|         // } | ||||
|          | ||||
|         //world gen testing | ||||
|         //gen terrain | ||||
| //        Globals.serverTerrainManager = new ServerTerrainManager(2000,50,100,0.0f,0); | ||||
|  | ||||
| @ -102,14 +102,12 @@ public class MenuGenerators { | ||||
|         arenaButton.addChild(arenaLabel); | ||||
|         rVal.addChild(arenaButton); | ||||
|         arenaButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ | ||||
|             LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER); | ||||
|             Globals.loadingThreadsList.add(clientThread); | ||||
|             LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_ARENA); | ||||
|             Globals.loadingThreadsList.add(serverThread); | ||||
|             Globals.RUN_CLIENT = true; | ||||
|             Globals.RUN_SERVER = true; | ||||
|             clientThread.start(); | ||||
|             serverThread.start(); | ||||
|             WindowUtils.replaceMainMenuContents(MenuGeneratorsArena.createArenaHostLoginMenu()); | ||||
|             return false; | ||||
|         }}); | ||||
| 
 | ||||
| @ -455,7 +453,7 @@ public class MenuGenerators { | ||||
|                     //clear ui | ||||
|                     WindowUtils.cleanItemDraggingWindow(); | ||||
|                     String sourceWindowId = WindowStrings.WINDOW_CHARACTER; | ||||
|                     WindowUtils.replaceWindow(sourceWindowId,MenuGenerators.createCharacterMenu(inventory)); | ||||
|                     WindowUtils.replaceWindow(sourceWindowId,MenuGenerators.createCharacterInventoryMenu(inventory)); | ||||
|                     //null globals | ||||
|                     Globals.dragSourceInventory = null; | ||||
|                     Globals.draggedItem = null; | ||||
| @ -924,7 +922,7 @@ public class MenuGenerators { | ||||
|                         WindowUtils.cleanItemDraggingWindow(); | ||||
|                         //rerender both inventories | ||||
|                         //re-render inventory | ||||
|                         WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGenerators.createCharacterMenu(sourceInventory)); | ||||
|                         WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGenerators.createCharacterInventoryMenu(sourceInventory)); | ||||
|                         //re-render inventory | ||||
|                         WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(inventory.getId()), MenuGenerators.createNaturalInventoryMenu(inventory)); | ||||
|                     } | ||||
| @ -953,7 +951,7 @@ public class MenuGenerators { | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public static Window createCharacterMenu(RelationalInventoryState inventory){ | ||||
|     public static Window createCharacterInventoryMenu(RelationalInventoryState inventory){ | ||||
|         // int screenTop = Globals.WINDOW_HEIGHT - 150; | ||||
|         int width = 500; | ||||
|         int height = 500; | ||||
| @ -987,7 +985,7 @@ public class MenuGenerators { | ||||
|                     WindowUtils.cleanItemDraggingWindow(); | ||||
|                     //rerender both inventories | ||||
|                     //re-render inventory | ||||
|                     WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGenerators.createCharacterMenu(inventory)); | ||||
|                     WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGenerators.createCharacterInventoryMenu(inventory)); | ||||
|                     //re-render inventory | ||||
|                     WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(sourceInventory.getId()), MenuGenerators.createNaturalInventoryMenu(sourceInventory)); | ||||
|                 } | ||||
| @ -1088,7 +1086,7 @@ public class MenuGenerators { | ||||
|                         WindowUtils.cleanItemDraggingWindow(); | ||||
|                         //rerender both inventories | ||||
|                         //re-render inventory | ||||
|                         WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGenerators.createCharacterMenu(inventory)); | ||||
|                         WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGenerators.createCharacterInventoryMenu(inventory)); | ||||
|                         //re-render inventory | ||||
|                         WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(sourceInventory.getId()), MenuGenerators.createNaturalInventoryMenu(sourceInventory)); | ||||
|                     } | ||||
|  | ||||
							
								
								
									
										70
									
								
								src/main/java/electrosphere/menu/MenuGeneratorsArena.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/main/java/electrosphere/menu/MenuGeneratorsArena.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| package electrosphere.menu; | ||||
| 
 | ||||
| import electrosphere.auth.AuthenticationManager; | ||||
| import electrosphere.engine.LoadingThread; | ||||
| import electrosphere.main.Globals; | ||||
| import electrosphere.net.NetUtils; | ||||
| import electrosphere.renderer.ui.ClickableElement; | ||||
| import electrosphere.renderer.ui.Element; | ||||
| import electrosphere.renderer.ui.elements.Button; | ||||
| import electrosphere.renderer.ui.elements.Label; | ||||
| import electrosphere.renderer.ui.elements.TextInput; | ||||
| import electrosphere.renderer.ui.events.ClickEvent; | ||||
| import electrosphere.renderer.ui.form.FormElement; | ||||
| 
 | ||||
| public class MenuGeneratorsArena { | ||||
|      | ||||
|     public static Element createArenaHostLoginMenu(){ | ||||
|         FormElement rVal = new FormElement(); | ||||
|         int screenTop = 150; | ||||
|          | ||||
|         //label (address) | ||||
|         Label usernameLabel = new Label(100,screenTop + 50,1.0f); | ||||
|         usernameLabel.setText("Username"); | ||||
|         rVal.addChild(usernameLabel); | ||||
| 
 | ||||
|         //text entry (address) | ||||
|         TextInput usernameInput = new TextInput(100,screenTop + 125,1.0f); | ||||
|         usernameInput.setText(""); | ||||
|         rVal.addChild(usernameInput); | ||||
| 
 | ||||
|         //label (port) | ||||
|         Label passwordLabel = new Label(100,screenTop + 200,1.0f); | ||||
|         passwordLabel.setText("Password"); | ||||
|         rVal.addChild(passwordLabel); | ||||
| 
 | ||||
|         //text entry (port) | ||||
|         TextInput passwordInput = new TextInput(100,screenTop + 275,1.0f); | ||||
|         passwordInput.setText(""); | ||||
|         rVal.addChild(passwordInput); | ||||
| 
 | ||||
|         //button (connect) | ||||
|         Button connectButton = new Button(); | ||||
|         Label connectLabel = new Label(100,screenTop + 350,1.0f); | ||||
|         connectLabel.setText("Login"); | ||||
|         connectButton.addChild(connectLabel); | ||||
|         rVal.addChild(connectButton); | ||||
|         connectButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ | ||||
|             Globals.clientUsername = usernameInput.getText(); | ||||
|             Globals.clientPassword = AuthenticationManager.getHashedString(passwordInput.getText()); | ||||
|             LoadingThread clientThread = new LoadingThread(LoadingThread.LOAD_CHARACTER_SERVER); | ||||
|             Globals.loadingThreadsList.add(clientThread); | ||||
|             clientThread.start(); | ||||
|             return false; | ||||
|         }}); | ||||
| 
 | ||||
|         //button (back) | ||||
|         // Button backButton = new Button(); | ||||
|         // Label backLabel = new Label(100,screenTop + 425,1.0f); | ||||
|         // backLabel.setText("Back"); | ||||
|         // backButton.addChild(backLabel); | ||||
|         // rVal.addChild(backButton); | ||||
|         // backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ | ||||
|         //     WindowUtils.replaceMainMenuContents(MenuGenerators.createMultiplayerMenu()); | ||||
|         //     return false; | ||||
|         // }}); | ||||
| 
 | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -26,8 +26,6 @@ import java.util.concurrent.TimeUnit; | ||||
| import java.util.logging.Level; | ||||
| import java.util.logging.Logger; | ||||
| import javax.crypto.spec.SecretKeySpec; | ||||
| import org.apache.commons.crypto.stream.CryptoInputStream; | ||||
| import org.apache.commons.crypto.stream.CryptoOutputStream; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
| @ -94,7 +92,7 @@ public class ClientNetworking implements Runnable{ | ||||
|             } | ||||
|             if(connectionAttempts > MAX_CONNECTION_ATTEMPTS){ | ||||
|                 LoggerInterface.loggerNetworking.ERROR("Max client connection attempts!", new Exception()); | ||||
|                 System.exit(1); | ||||
|                 // System.exit(1); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -14,15 +14,19 @@ public class AuthProtocol { | ||||
|             case AUTHREQUEST: | ||||
|                 //Try login | ||||
|                 //TODO: actually get user/pass | ||||
|                 Globals.clientConnection.queueOutgoingMessage(AuthMessage.constructAuthDetailsMessage("myuser","mypass")); | ||||
|                 Globals.clientConnection.queueOutgoingMessage(AuthMessage.constructAuthDetailsMessage(Globals.clientUsername,Globals.clientPassword)); | ||||
|                 break; | ||||
|             case AUTHSUCCESS: | ||||
|                 //clean password hash from memory | ||||
|                 Globals.clientPassword = ""; | ||||
|                 //request playable races | ||||
|                 Globals.clientConnection.queueOutgoingMessage(LoreMessage.constructRequestRacesMessage()); | ||||
|                 //log that we succeeded | ||||
|                 LoggerInterface.loggerAuth.INFO("Successfully logged in"); | ||||
|                 break; | ||||
|             case AUTHFAILURE: | ||||
|                 //TODO: handle better | ||||
|                 LoggerInterface.loggerEngine.ERROR("Auth failure",new Exception("Auth failure")); | ||||
|                 LoggerInterface.loggerAuth.ERROR("Auth failure",new Exception("Auth failure")); | ||||
|                 break; | ||||
|             //ignore stack | ||||
|             case AUTHDETAILS: | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| package electrosphere.net.server; | ||||
| 
 | ||||
| import electrosphere.game.server.saves.SaveUtils; | ||||
| import electrosphere.main.Globals; | ||||
| import electrosphere.main.Main; | ||||
| import electrosphere.net.NetUtils; | ||||
|  | ||||
| @ -35,8 +35,6 @@ import java.util.concurrent.TimeUnit; | ||||
| import java.util.logging.Level; | ||||
| import java.util.logging.Logger; | ||||
| import javax.crypto.spec.SecretKeySpec; | ||||
| import org.apache.commons.crypto.stream.CryptoInputStream; | ||||
| import org.apache.commons.crypto.stream.CryptoOutputStream; | ||||
| import org.joml.Vector3f; | ||||
| 
 | ||||
| /** | ||||
|  | ||||
| @ -222,7 +222,7 @@ public class FileUtils { | ||||
|      * @return true if directory was created, false if it was not | ||||
|      */ | ||||
|     public static boolean createDirectory(String directoryName){ | ||||
|         String sanitizedPath = "." + sanitizeFilePath(directoryName); | ||||
|         String sanitizedPath = sanitizeFilePath(directoryName); | ||||
|         File targetDir = new File(sanitizedPath); | ||||
|         if(targetDir.exists()){ | ||||
|             return false; | ||||
| @ -243,6 +243,21 @@ public class FileUtils { | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     public static void recursivelyDelete(String path){ | ||||
|         File file = new File(path); | ||||
|         if(file.isDirectory()){ | ||||
|             for(File child : file.listFiles()){ | ||||
|                 recursivelyDelete(child.getAbsolutePath()); | ||||
|             } | ||||
|         } | ||||
|         try { | ||||
|             Files.delete(file.toPath()); | ||||
|         } catch (IOException e) { | ||||
|             // TODO Auto-generated catch block | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|      | ||||
|      | ||||
|      | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user