diff --git a/.classpath b/.classpath
index 9cd6c1d4e..414580b20 100644
--- a/.classpath
+++ b/.classpath
@@ -9,5 +9,6 @@
+
diff --git a/lib/sqlite-jdbc-3.8.10.1.jar b/lib/sqlite-jdbc-3.8.10.1.jar
new file mode 100644
index 000000000..971a81f3e
Binary files /dev/null and b/lib/sqlite-jdbc-3.8.10.1.jar differ
diff --git a/serverdata/static_spawns.db b/serverdata/static_spawns.db
new file mode 100644
index 000000000..34a32946f
Binary files /dev/null and b/serverdata/static_spawns.db differ
diff --git a/src/resources/server_info/PostgresqlDatabase.java b/src/resources/server_info/PostgresqlDatabase.java
index 974dc5a33..ec7f08552 100644
--- a/src/resources/server_info/PostgresqlDatabase.java
+++ b/src/resources/server_info/PostgresqlDatabase.java
@@ -30,7 +30,7 @@ package resources.server_info;
public class PostgresqlDatabase extends RelationalDatabase {
public PostgresqlDatabase(String host, String db, String user, String pass) {
- super("postgresql", host, db, user, pass, "");
+ super("org.postgresql.Driver", "postgresql", host, db, user, pass, "");
}
}
diff --git a/src/resources/server_info/RelationalDatabase.java b/src/resources/server_info/RelationalDatabase.java
index 247039243..368a6a3e6 100644
--- a/src/resources/server_info/RelationalDatabase.java
+++ b/src/resources/server_info/RelationalDatabase.java
@@ -41,11 +41,64 @@ public abstract class RelationalDatabase {
private Connection connection;
private boolean online;
- public RelationalDatabase(String type, String host, String db, String user, String pass, String params) {
+ protected RelationalDatabase(String jdbcClass, String url) {
try {
+ Class.forName(jdbcClass);
+ initialize(url);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ online = false;
+ }
+ }
+
+ protected RelationalDatabase(String jdbcClass, String url, String user, String pass) {
+ try {
+ Class.forName(jdbcClass);
+ initialize(url, user, pass);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ online = false;
+ }
+ }
+
+ public RelationalDatabase(String jdbcClass, String url, String user, String pass, String params) {
+ try {
+ Class.forName(jdbcClass);
+ if (params != null && params.length() > 0)
+ url += "?" + params;
+ initialize(url, user, pass);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ online = false;
+ }
+ }
+
+ public RelationalDatabase(String jdbcClass, String type, String host, String db, String user, String pass, String params) {
+ try {
+ Class.forName(jdbcClass);
String url = "jdbc:" + type + "://" + host + "/" + db;
if (params != null && params.length() > 0)
url += "?" + params;
+ initialize(url, user, pass);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ online = false;
+ }
+ }
+
+ private void initialize(String url) {
+ try {
+ connection = DriverManager.getConnection(url);
+ metaData = connection.getMetaData();
+ online = true;
+ } catch (SQLException e) {
+ System.err.println("Failed to initialize relational database! " + e.getClass().getSimpleName() + " - " + e.getMessage());
+ online = false;
+ }
+ }
+
+ private void initialize(String url, String user, String pass) {
+ try {
connection = DriverManager.getConnection(url, user, pass);
metaData = connection.getMetaData();
online = true;
@@ -76,8 +129,10 @@ public abstract class RelationalDatabase {
}
public PreparedStatement prepareStatement(String sql) {
- if (connection == null)
+ if (connection == null) {
+ System.err.println("Cannot prepare statement! Connection is null");
return null;
+ }
try {
return connection.prepareStatement(sql);
} catch (SQLException e) {
diff --git a/src/resources/server_info/RelationalServerData.java b/src/resources/server_info/RelationalServerData.java
new file mode 100644
index 000000000..c4435cad2
--- /dev/null
+++ b/src/resources/server_info/RelationalServerData.java
@@ -0,0 +1,36 @@
+/***********************************************************************************
+* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+* *
+* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+* Our goal is to create an emulator which will provide a server for players to *
+* continue playing a game similar to the one they used to play. We are basing *
+* it on the final publish of the game prior to end-game events. *
+* *
+* This file is part of Holocore. *
+* *
+* -------------------------------------------------------------------------------- *
+* *
+* Holocore is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Affero General Public License as *
+* published by the Free Software Foundation, either version 3 of the *
+* License, or (at your option) any later version. *
+* *
+* Holocore is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Affero General Public License for more details. *
+* *
+* You should have received a copy of the GNU Affero General Public License *
+* along with Holocore. If not, see . *
+* *
+***********************************************************************************/
+package resources.server_info;
+
+public class RelationalServerData extends RelationalDatabase {
+
+ public RelationalServerData(String file) {
+ super("org.sqlite.JDBC", "jdbc:sqlite:" + file);
+ }
+
+}
diff --git a/src/services/spawn/StaticService.java b/src/services/spawn/StaticService.java
index ec3302408..2d4370d16 100644
--- a/src/services/spawn/StaticService.java
+++ b/src/services/spawn/StaticService.java
@@ -27,87 +27,60 @@
***********************************************************************************/
package services.spawn;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
import resources.Location;
import resources.control.Service;
import resources.objects.SWGObject;
import resources.objects.building.BuildingObject;
-import resources.objects.cell.CellObject;
+import resources.server_info.RelationalServerData;
import services.objects.ObjectManager;
public class StaticService extends Service {
-
- private static final String TICKET_TERMINAL_IFF = "object/tangible/terminal/shared_terminal_travel.iff";
- private static final String BANK_TERMINAL_IFF = "object/tangible/terminal/shared_terminal_bank.iff";
- private static final String PLAYER_TRANSPORT_IFF = "object/creature/npc/theme_park/shared_player_transport.iff";
- private static final String PLAYER_SHUTTLE_IFF = "object/creature/npc/theme_park/shared_player_shuttle.iff";
- private static final String TICKET_COLLECTOR_IFF = "object/tangible/travel/ticket_collector/shared_ticket_collector.iff";
+ private static final String GET_SUPPORTING_SQL = "SELECT spawn.* FROM static_spawns spawn, static_types types WHERE types.iff = ? AND spawn.iff_type = types.iff_type";
+
+ private final Object databaseMutex;
private final ObjectManager objectManager;
+ private RelationalServerData spawnDatabase;
+ private PreparedStatement getSupportingStatement;
public StaticService(ObjectManager objectManager) {
+ this.databaseMutex = new Object();
this.objectManager = objectManager;
- }
-
- @Override
- public boolean initialize() {
- return super.initialize();
+
+ spawnDatabase = new RelationalServerData("serverdata/static_spawns.db");
+ getSupportingStatement = spawnDatabase.prepareStatement(GET_SUPPORTING_SQL);
}
public void createSupportingObjects(SWGObject object) {
- switch (object.getTemplate()) {
- case "object/building/tatooine/shared_bank_tatooine.iff":
- case "object/building/naboo/shared_bank_naboo.iff":
- case "object/building/corellia/shared_bank_corellia.iff":
- createBankSetup(object);
- break;
- case "object/building/tatooine/shared_starport_tatooine.iff":
- case "object/building/naboo/shared_starport_naboo.iff":
- case "object/building/corellia/shared_starport_corellia.iff":
- if (!(object instanceof BuildingObject)) {
- System.err.println(object.getTemplate() + " is not a building!");
- break;
+ synchronized (databaseMutex) {
+ try {
+ getSupportingStatement.setString(1, object.getTemplate());
+ ResultSet set = getSupportingStatement.executeQuery();
+ Location world = object.getWorldLocation();
+ while (set.next()) {
+ String iff = set.getString("child_iff");
+ String cell = set.getString("cell");
+ double x = set.getDouble("x");
+ double y = set.getDouble("y");
+ double z = set.getDouble("z");
+ double heading = set.getDouble("heading");
+ if (cell.isEmpty()) {
+ createObject(iff, world, x, y, z, heading);
+ } else {
+ BuildingObject buio = (BuildingObject) object;
+ createObject(iff, buio.getCellByName(cell), x, y, z, heading);
+ }
}
- createGeneralStarportSetup((BuildingObject) object);
- break;
- case "object/building/tatooine/shared_shuttleport_tatooine.iff":
- case "object/building/naboo/shared_shuttleport_naboo.iff":
- case "object/building/corellia/shared_shuttleport_corellia.iff":
- case "object/building/naboo/rori_restuss_shuttleport.iff":
- if (!(object instanceof BuildingObject)) {
- System.err.println(object.getTemplate() + " is not a building!");
- break;
- }
- createShuttleport((BuildingObject) object);
- break;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
}
}
- private void createBankSetup(SWGObject bank) {
- Location bankLoc = bank.getWorldLocation();
- createObject(BANK_TERMINAL_IFF, bankLoc, 0, 0.52, 4.3, 0);
- createObject(BANK_TERMINAL_IFF, bankLoc, 0, 0.52, -4.3, 180);
- createObject(BANK_TERMINAL_IFF, bankLoc, 4.3, 0.52, 0, 90);
- createObject(BANK_TERMINAL_IFF, bankLoc, -4.3, 0.52, 0, -90);
- }
-
- private void createGeneralStarportSetup(BuildingObject starport) {
- CellObject foyer4 = starport.getCellByName("foyer4");
- Location starportLoc = starport.getWorldLocation();
- createObject(TICKET_TERMINAL_IFF, foyer4, 11.255, 0.64, 51.64, -35);
- createObject(TICKET_TERMINAL_IFF, foyer4, 2.52, 0.64, 50.02, 0);
- createObject(TICKET_TERMINAL_IFF, foyer4, -3.23, 0.64, 50.05, 0);
- createObject(TICKET_TERMINAL_IFF, foyer4, -12.71, 0.64, 52.04, 35);
- createObject(PLAYER_TRANSPORT_IFF, starportLoc, 1.72, 0, -5.06, 180);
- createObject(TICKET_COLLECTOR_IFF, starportLoc, -7.92, 0, 4.75, 90);
- }
-
- private void createShuttleport(BuildingObject shuttleport) {
- Location shuttleportLoc = shuttleport.getWorldLocation();
- createObject(TICKET_TERMINAL_IFF, shuttleportLoc, 13.3, -0.6, 9.4, 270);
- createObject(PLAYER_SHUTTLE_IFF, shuttleportLoc, 0, -1.6, -5, 180);
- createObject(TICKET_COLLECTOR_IFF, shuttleportLoc, 13.3, -0.6, -9.4, 270);
- }
-
private SWGObject createObject(String iff, SWGObject parent, double x, double y, double z, double heading) {
Location loc = new Location(x, y, z, parent.getTerrain());
loc.setHeading(heading);