diff --git a/src/resources/client_info/ClientFactory.java b/src/resources/client_info/ClientFactory.java index 364c4ed18..607f7f8cb 100644 --- a/src/resources/client_info/ClientFactory.java +++ b/src/resources/client_info/ClientFactory.java @@ -30,6 +30,7 @@ package resources.client_info; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.HashMap; @@ -122,7 +123,7 @@ public class ClientFactory { // readFile only called if dataMap doesn't contain the file as a key or it's value is null private ClientData readFile(String file) { - FileInputStream stream = null; + InputStream stream = null; try { File f = new File("./clientdata/" + file); if (!f.exists()) { @@ -158,7 +159,7 @@ public class ClientFactory { return null; } - private ByteBuffer readIntoBuffer(FileInputStream stream) throws IOException { + private ByteBuffer readIntoBuffer(InputStream stream) throws IOException { ByteBuffer bb = ByteBuffer.allocate(stream.available()).order(ByteOrder.LITTLE_ENDIAN); stream.read(bb.array()); return bb; diff --git a/src/resources/objects/buildouts/SnapshotLoader.java b/src/resources/objects/buildouts/SnapshotLoader.java new file mode 100644 index 000000000..7d43e2127 --- /dev/null +++ b/src/resources/objects/buildouts/SnapshotLoader.java @@ -0,0 +1,35 @@ +package resources.objects.buildouts; + +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import resources.Terrain; +import resources.objects.SWGObject; + +public class SnapshotLoader { + + private static final Set TERRAINS = EnumSet.of( + Terrain.CORELLIA, Terrain.DANTOOINE, Terrain.DATHOMIR, + Terrain.DUNGEON1, Terrain.ENDOR, Terrain.LOK, + Terrain.NABOO, Terrain.RORI, Terrain.TALUS, + Terrain.TATOOINE, Terrain.YAVIN4 + ); + + public static List loadAllSnapshots() { + List objects = new LinkedList<>(); + for (Terrain t : TERRAINS) { + List terrain = loadSnapshotsForTerrain(t); + objects.addAll(terrain); + } + return objects; + } + + public static List loadSnapshotsForTerrain(Terrain t) { + TerrainSnapshotLoader loader = new TerrainSnapshotLoader(t); + loader.load(); + return loader.getObjects(); + } + +} diff --git a/src/resources/objects/buildouts/SnapshotRow.java b/src/resources/objects/buildouts/SnapshotRow.java new file mode 100644 index 000000000..17e2b5285 --- /dev/null +++ b/src/resources/objects/buildouts/SnapshotRow.java @@ -0,0 +1,13 @@ +package resources.objects.buildouts; + +import resources.client_info.visitors.WorldSnapshotData.Chunk; + +public class SnapshotRow { + + + + public void load(Chunk chunk) { + + } + +} diff --git a/src/resources/objects/buildouts/TerrainSnapshotLoader.java b/src/resources/objects/buildouts/TerrainSnapshotLoader.java new file mode 100644 index 000000000..0b3c55b42 --- /dev/null +++ b/src/resources/objects/buildouts/TerrainSnapshotLoader.java @@ -0,0 +1,85 @@ +package resources.objects.buildouts; + +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import resources.Location; +import resources.Terrain; +import resources.client_info.ClientFactory; +import resources.client_info.visitors.WorldSnapshotData; +import resources.client_info.visitors.WorldSnapshotData.Chunk; +import resources.containers.ContainerPermissions; +import resources.objects.SWGObject; +import resources.objects.cell.CellObject; +import resources.server_info.Log; +import services.objects.ObjectCreator; + +public class TerrainSnapshotLoader { + + private static final String BASE_PATH = "snapshot/"; + + private final Terrain terrain; + private final Map objectTable; + private final List objects; + + public TerrainSnapshotLoader(Terrain terrain) { + this.terrain = terrain; + this.objectTable = new Hashtable(12*1024); + this.objects = new LinkedList<>(); + } + + public List getObjects() { + return objects; + } + + public void load() { + objects.clear(); + String path = BASE_PATH + terrain.getName() + ".ws"; + WorldSnapshotData data = (WorldSnapshotData) ClientFactory.getInfoFromFile(path); + Map templates = data.getObjectTemplateNames(); + for (Chunk chunk : data.getChunks()) { + SWGObject object = createObject(templates, chunk); + object.setLoadRange(chunk.getRadius()); + addObject(object, chunk.getContainerId()); + setCellInformation(object, chunk.getCellIndex()); + updatePermissions(object); + } + System.out.println("TerrainSnapshotLoader: " + path); + } + + private SWGObject createObject(Map templateMap, Chunk row) { + SWGObject object = ObjectCreator.createObjectFromTemplate(row.getId(), templateMap.get(row.getObjectTemplateNameIndex())); + Location l = row.getLocation(); + l.setTerrain(terrain); + object.setLocation(l); + return object; + } + + private void addObject(SWGObject object, long containerId) { + objectTable.put(object.getObjectId(), object); + if (containerId != 0) { + SWGObject container = objectTable.get(containerId); + if (container != null) + container.addObject(object); + else { + Log.e("TerrainBuildoutLoader", "Failed to load object: " + object.getTemplate()); + } + } else { + objects.add(object); + } + } + + private void setCellInformation(SWGObject object, int cellIndex) { + if (!(object instanceof CellObject)) + return; + CellObject cell = (CellObject) object; + cell.setNumber(cellIndex); + } + + private void updatePermissions(SWGObject object) { + object.setContainerPermissions(ContainerPermissions.WORLD); + } + +} diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java index 9a13430c4..2877a27e4 100644 --- a/src/services/objects/ObjectManager.java +++ b/src/services/objects/ObjectManager.java @@ -42,15 +42,14 @@ import network.packets.swg.zone.insertion.SelectCharacter; import network.packets.swg.zone.object_controller.DataTransform; import network.packets.swg.zone.object_controller.DataTransformWithParent; import network.packets.swg.zone.object_controller.ObjectController; -import network.packets.swg.zone.object_controller.PostureUpdate; import resources.Location; -import resources.Posture; import resources.Terrain; import resources.config.ConfigFile; import resources.control.Intent; import resources.control.Manager; import resources.objects.SWGObject; import resources.objects.buildouts.BuildoutLoader; +import resources.objects.buildouts.SnapshotLoader; import resources.objects.creature.CreatureObject; import resources.objects.tangible.TangibleObject; import resources.player.Player; @@ -67,14 +66,12 @@ public class ObjectManager extends Manager { private final MapService mapService; - private final Map > buildoutObjects; private final ObjectDatabase objects; private final ObjectAwareness objectAwareness; private long maxObjectId; public ObjectManager() { mapService = new MapService(); - buildoutObjects = new HashMap>(); objects = new CachedObjectDatabase("odb/objects.db"); objectAwareness = new ObjectAwareness(); maxObjectId = 1; @@ -89,6 +86,7 @@ public class ObjectManager extends Manager { objectAwareness.initialize(); loadObjects(); loadBuildouts(); + loadSnapshots(); return super.initialize(); } @@ -132,7 +130,7 @@ public class ObjectManager extends Manager { loadBuildout(obj); } double loadTime = (System.nanoTime() - startLoad) / 1E6; - System.out.printf("ObjectManager: Finished loading buildouts. Time: %fms%n", loadTime); + System.out.printf("ObjectManager: Finished loading %d buildouts. Time: %fms%n", buildouts.size(), loadTime); Log.i("ObjectManager", "Finished loading buildouts. Time: %fms", loadTime); } else { Log.w("ObjectManager", "Did not load buildouts. Reason: Disabled."); @@ -140,25 +138,46 @@ public class ObjectManager extends Manager { } } + private void loadSnapshots() { + Config c = getConfig(ConfigFile.PRIMARY); + if (c.getBoolean("LOAD-SNAPSHOTS", false)) { + long startLoad = System.nanoTime(); + System.out.println("ObjectManager: Loading snapshots..."); + Log.i("ObjectManager", "Loading snapshots..."); + List snapshots = null; + String terrain = c.getString("LOAD-SNAPSHOTS-FOR", ""); + if (Terrain.doesTerrainExistForName(terrain)) + snapshots = SnapshotLoader.loadSnapshotsForTerrain(Terrain.getTerrainFromName(terrain)); + else { + if (!terrain.isEmpty()) { + System.err.println("ObjectManager: Unknown terrain '" + terrain + "'"); + Log.e("ObjectManager", "Unknown terrain: %s", terrain); + } + snapshots = SnapshotLoader.loadAllSnapshots(); + } + for (SWGObject obj : snapshots) { + loadSnapshot(obj); + } + double loadTime = (System.nanoTime() - startLoad) / 1E6; + System.out.printf("ObjectManager: Finished loading %d snapshots. Time: %fms%n", snapshots.size(), loadTime); + Log.i("ObjectManager", "Finished loading snapshots. Time: %fms", loadTime); + } else { + Log.w("ObjectManager", "Did not load snapshots. Reason: Disabled."); + System.out.println("ObjectManager: Snapshots not loaded. Reason: Disabled!"); + } + } + private void loadBuildout(SWGObject obj) { - loadObject(obj); - List idCollisions = buildoutObjects.get(obj.getObjectId()); - if (idCollisions == null) - buildoutObjects.put(obj.getObjectId(), idCollisions = new LinkedList()); - boolean duplicate = false; - for (SWGObject dup : idCollisions) { - if (dup.getLocation().equals(obj.getLocation()) && dup.getTemplate().equals(obj.getTemplate())) { - duplicate = true; - break; - } + if (obj instanceof TangibleObject) { + objectAwareness.add(obj); } - if (!duplicate) { - idCollisions.add(obj); - if (obj instanceof TangibleObject) { - objectAwareness.add(obj); - } + mapService.addMapLocation(obj, MapService.MapType.STATIC); + } + + private void loadSnapshot(SWGObject obj) { + if (obj instanceof TangibleObject) { + objectAwareness.add(obj); } - mapService.addMapLocation(obj, MapService.MapType.STATIC); }