diff --git a/src/intents/object/ObjectIdRequestIntent.java b/src/intents/object/ObjectIdRequestIntent.java
deleted file mode 100644
index 784b64c4..00000000
--- a/src/intents/object/ObjectIdRequestIntent.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * 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 intents.object;
-
-import resources.control.Intent;
-
-/**
- * Created by Waverunner on 8/19/2015
- */
-public class ObjectIdRequestIntent extends Intent {
- public static final String TYPE = "ObjectIdRequestIntent";
-
- private String identifier;
- private int amount;
-
- public ObjectIdRequestIntent(String identifier, int amount) {
- super(TYPE);
- this.identifier = identifier;
- this.amount = amount;
- }
-
- public String getIdentifier() {
- return identifier;
- }
-
- public int getAmount() {
- return amount;
- }
-}
\ No newline at end of file
diff --git a/src/intents/object/ObjectIdResponseIntent.java b/src/intents/object/ObjectIdResponseIntent.java
deleted file mode 100644
index 6799adec..00000000
--- a/src/intents/object/ObjectIdResponseIntent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
- * 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 intents.object;
-
-import resources.control.Intent;
-
-import java.util.List;
-
-/**
- * Created by Waverunner on 8/19/2015
- */
-public class ObjectIdResponseIntent extends Intent {
- public static final String TYPE = "ObjectIdResponseIntent";
-
- private String identifier;
- private List reservedIds;
-
- public ObjectIdResponseIntent(String identifier, List reservedIds) {
- super(TYPE);
- this.identifier = identifier;
- this.reservedIds = reservedIds;
- }
-
- public String getIdentifier() {
- return identifier;
- }
-
- public List getReservedIds() {
- return reservedIds;
- }
-}
\ No newline at end of file
diff --git a/src/services/group/GroupService.java b/src/services/group/GroupService.java
index e8a76a4c..bbd45131 100644
--- a/src/services/group/GroupService.java
+++ b/src/services/group/GroupService.java
@@ -32,8 +32,6 @@ import intents.NotifyPlayersPacketIntent;
import intents.PlayerEventIntent;
import intents.chat.ChatRoomUpdateIntent;
import intents.object.ObjectCreatedIntent;
-import intents.object.ObjectIdRequestIntent;
-import intents.object.ObjectIdResponseIntent;
import network.packets.swg.zone.chat.ChatSystemMessage;
import resources.chat.ChatAvatar;
import resources.control.Intent;
@@ -58,19 +56,16 @@ import java.util.Map;
* Created by Waverunner on 10/4/2015
*/
public class GroupService extends Service {
-
- private final List reservedIds = new ArrayList<>();
+
private final Map groups = new HashMap<>();
public GroupService() {
registerForIntent(GroupEventIntent.TYPE);
registerForIntent(PlayerEventIntent.TYPE);
- registerForIntent(ObjectIdResponseIntent.TYPE);
}
@Override
public boolean start() {
- new ObjectIdRequestIntent("GroupService", 50).broadcast();
return super.start();
}
@@ -82,11 +77,6 @@ public class GroupService extends Service {
if (i instanceof GroupEventIntent)
handleGroupEventIntent((GroupEventIntent) i);
break;
- case ObjectIdResponseIntent.TYPE:
- if (!(i instanceof ObjectIdResponseIntent) || !((ObjectIdResponseIntent) i).getIdentifier().equals("GroupService"))
- break;
- reservedIds.addAll(((ObjectIdResponseIntent)i).getReservedIds());
- break;
case PlayerEventIntent.TYPE:
if (i instanceof PlayerEventIntent)
handlePlayerEventIntent((PlayerEventIntent) i);
@@ -289,7 +279,7 @@ public class GroupService extends Service {
}
private GroupObject createGroup(Player player) {
- GroupObject group = (GroupObject) ObjectCreator.createObjectFromTemplate(getNextObjectId(), "object/group/shared_group_object.iff");
+ GroupObject group = (GroupObject) ObjectCreator.createObjectFromTemplate("object/group/shared_group_object.iff");
if (group == null)
return null;
@@ -306,15 +296,6 @@ public class GroupService extends Service {
return group;
}
- private long getNextObjectId() {
- synchronized (reservedIds) {
- if (reservedIds.size() <= 5)
- new ObjectIdRequestIntent("GroupService", 50).broadcast();
-
- return reservedIds.remove(0);
- }
- }
-
private void sendGroupSystemMessage(GroupObject group, String id) {
Map members = group.getGroupMembers();
diff --git a/src/services/objects/ObjectCreator.java b/src/services/objects/ObjectCreator.java
index acaae9e7..c1d6c708 100644
--- a/src/services/objects/ObjectCreator.java
+++ b/src/services/objects/ObjectCreator.java
@@ -52,21 +52,40 @@ import resources.objects.waypoint.WaypointObject;
import resources.objects.weapon.WeaponObject;
public final class ObjectCreator {
-
+
+ private static final Object OBJECT_ID_MUTEX = new Object();
+ private static long maxObjectId = 1;
+
+ public static void updateMaxObjectId(long objectId) {
+ synchronized (OBJECT_ID_MUTEX) {
+ if (objectId > maxObjectId)
+ maxObjectId = objectId;
+ }
+ }
+
public static SWGObject createObjectFromTemplate(long objectId, String template) {
if (!template.startsWith("object/"))
return null;
if (!template.endsWith(".iff"))
return null;
- SWGObject obj = createObjectFromType(objectId, getFirstTemplatePart(template.substring(7, template.length())));
+ SWGObject obj = createObjectFromType(objectId, getTemplatePart(template, 1));
if (obj == null)
return null;
obj.setTemplate(template);
handlePostCreation(obj);
+ updateMaxObjectId(objectId);
return obj;
}
+ public static SWGObject createObjectFromTemplate(String template) {
+ long id = 0;
+ synchronized (OBJECT_ID_MUTEX) {
+ id = maxObjectId++;
+ }
+ return createObjectFromTemplate(id, template);
+ }
+
private static SWGObject createObjectFromType(long objectId, String type) {
switch (type) {
case "building": return new BuildingObject(objectId);
@@ -146,11 +165,21 @@ public final class ObjectCreator {
/*
Misc helper methods
*/
- private static String getFirstTemplatePart(String template) {
- int ind = template.indexOf('/');
- if (ind == -1)
- return "";
- return template.substring(0, ind);
+ private static String getTemplatePart(String template, int index) {
+ int start = 0;
+ int end = 0;
+ for (int i = 0; i < template.length(); i++) {
+ if (template.charAt(i) != '/')
+ continue;
+ index--;
+ if (index == 0)
+ start = i+1;
+ else if (index == -1) {
+ end = i;
+ break;
+ }
+ }
+ return template.substring(start, end);
}
}
diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java
index af812307..5c38ddc1 100644
--- a/src/services/objects/ObjectManager.java
+++ b/src/services/objects/ObjectManager.java
@@ -37,8 +37,6 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import intents.object.ObjectCreatedIntent;
-import intents.object.ObjectIdRequestIntent;
-import intents.object.ObjectIdResponseIntent;
import intents.object.ObjectTeleportIntent;
import intents.player.DeleteCharacterIntent;
import intents.RequestZoneInIntent;
@@ -48,7 +46,6 @@ import network.packets.swg.ErrorMessage;
import network.packets.swg.zone.SceneDestroyObject;
import network.packets.swg.zone.insertion.SelectCharacter;
import resources.Location;
-import resources.containers.ContainerPermissions;
import resources.control.Intent;
import resources.control.Manager;
import resources.objects.SWGObject;
@@ -74,7 +71,6 @@ public class ObjectManager extends Manager {
private final ObjectDatabase database;
private final Map objectMap;
- private long maxObjectId;
public ObjectManager() {
objectAwareness = new ObjectAwareness();
@@ -86,7 +82,6 @@ public class ObjectManager extends Manager {
database = new CachedObjectDatabase("odb/objects.db");
objectMap = new Hashtable<>(16*1024);
- maxObjectId = 1;
addChildService(objectAwareness);
addChildService(mapManager);
@@ -97,7 +92,6 @@ public class ObjectManager extends Manager {
registerForIntent(GalacticPacketIntent.TYPE);
registerForIntent(ObjectTeleportIntent.TYPE);
- registerForIntent(ObjectIdRequestIntent.TYPE);
registerForIntent(ObjectCreatedIntent.TYPE);
registerForIntent(DeleteCharacterIntent.TYPE);
}
@@ -113,16 +107,15 @@ public class ObjectManager extends Manager {
long startLoad = System.nanoTime();
Log.i("ObjectManager", "Loading objects from ObjectDatabase...");
System.out.println("ObjectManager: Loading objects from ObjectDatabase...");
- database.load();
- database.traverse(new Traverser() {
- @Override
- public void process(SWGObject obj) {
- loadObject(obj);
- if (obj.getObjectId() >= maxObjectId) {
- maxObjectId = obj.getObjectId() + 1;
+ synchronized (database) {
+ database.load();
+ database.traverse(new Traverser() {
+ @Override
+ public void process(SWGObject obj) {
+ loadObject(obj);
}
- }
- });
+ });
+ }
double loadTime = (System.nanoTime() - startLoad) / 1E6;
Log.i("ObjectManager", "Finished loading %d objects. Time: %fms", database.size(), loadTime);
System.out.printf("ObjectManager: Finished loading %d objects. Time: %fms%n", database.size(), loadTime);
@@ -137,23 +130,7 @@ public class ObjectManager extends Manager {
// if creature is not a player
if (!(obj instanceof CreatureObject && ((CreatureObject) obj).isLoggedOutPlayer()))
objectAwareness.add(obj);
- if (obj instanceof CreatureObject && ((CreatureObject) obj).getPlayerObject() != null) {
- if (!obj.hasSlot("bank")) {
- SWGObject missing = createObject(obj, "object/tangible/bank/shared_character_bank.iff", false);
- missing.setContainerPermissions(ContainerPermissions.INVENTORY);
- }
-
- if (!obj.hasSlot("mission_bag")) {
- SWGObject missing = createObject(obj, "object/tangible/mission_bag/shared_mission_bag.iff", false);
- missing.setContainerPermissions(ContainerPermissions.INVENTORY);
- }
-
- if (!obj.hasSlot("appearance_inventory")) {
- SWGObject missing = createObject(obj, "object/tangible/inventory/shared_appearance_inventory.iff", false);
- missing.setContainerPermissions(ContainerPermissions.INVENTORY);
- }
- }
- objectMap.put(obj.getObjectId(), obj);
+ putObject(obj);
updateBuildoutParent(obj);
addChildrenObjects(obj);
}
@@ -163,7 +140,7 @@ public class ObjectManager extends Manager {
if (obj.getParent().isBuildout()) {
long id = obj.getParent().getObjectId();
obj.getParent().removeObject(obj);
- SWGObject parent = objectMap.get(id);
+ SWGObject parent = getObjectById(id);
if (parent != null)
parent.addObject(obj);
else {
@@ -178,15 +155,17 @@ public class ObjectManager extends Manager {
private void addChildrenObjects(SWGObject obj) {
for (SWGObject child : obj.getContainedObjects()) {
- objectMap.put(child.getObjectId(), child);
+ putObject(child);
addChildrenObjects(child);
}
}
@Override
public boolean terminate() {
- database.traverse((obj) -> obj.setOwner(null));
- database.close();
+ synchronized (database) {
+ database.traverse((obj) -> obj.setOwner(null));
+ database.close();
+ }
return super.terminate();
}
@@ -194,8 +173,6 @@ public class ObjectManager extends Manager {
public void onIntentReceived(Intent i) {
if (i instanceof GalacticPacketIntent) {
processGalacticPacketIntent((GalacticPacketIntent) i);
- } else if (i instanceof ObjectIdRequestIntent) {
- processObjectIdRequestIntent((ObjectIdRequestIntent) i);
} else if (i instanceof ObjectCreatedIntent) {
processObjectCreatedIntent((ObjectCreatedIntent) i);
} else if (i instanceof DeleteCharacterIntent) {
@@ -204,24 +181,9 @@ public class ObjectManager extends Manager {
}
private void processObjectCreatedIntent(ObjectCreatedIntent intent) {
- SWGObject object = intent.getObject();
- synchronized (objectMap) {
- if (object.getObjectId() >= maxObjectId) {
- maxObjectId = object.getObjectId() + 1;
- }
- objectMap.put(object.getObjectId(), object);
- }
+ putObject(intent.getObject());
}
-
- private void processObjectIdRequestIntent(ObjectIdRequestIntent intent) {
- List reservedIds = new ArrayList<>();
- for (int i = 0; i < intent.getAmount(); i++) {
- reservedIds.add(getNextObjectId());
- }
-
- new ObjectIdResponseIntent(intent.getIdentifier(), reservedIds).broadcast();
- }
-
+
private void processGalacticPacketIntent(GalacticPacketIntent gpi) {
Packet packet = gpi.getPacket();
if (packet instanceof SelectCharacter) {
@@ -238,9 +200,11 @@ public class ObjectManager extends Manager {
}
public SWGObject deleteObject(long objId) {
+ synchronized (database) {
+ database.remove(objId);
+ }
synchronized (objectMap) {
SWGObject obj = objectMap.remove(objId);
- database.remove(objId);
if (obj == null)
return null;
obj.clearAware();
@@ -249,9 +213,16 @@ public class ObjectManager extends Manager {
return obj;
}
}
-
+
+ private void putObject(SWGObject object) {
+ ObjectCreator.updateMaxObjectId(object.getObjectId());
+ synchronized (objectMap) {
+ objectMap.put(object.getObjectId(), object);
+ }
+ }
+
public SWGObject destroyObject(long objectId) {
- SWGObject object = objectMap.get(objectId);
+ SWGObject object = getObjectById(objectId);
return (object != null ? destroyObject(object) : null);
}
@@ -316,25 +287,22 @@ public class ObjectManager extends Manager {
}
public SWGObject createObject(SWGObject parent, String template, Location l, boolean addToDatabase) {
- synchronized (objectMap) {
- long objectId = getNextObjectId();
- SWGObject obj = ObjectCreator.createObjectFromTemplate(objectId, template);
- if (obj == null) {
- System.err.println("ObjectManager: Unable to create object with template " + template);
- return null;
- }
- obj.setLocation(l);
- objectMap.put(objectId, obj);
- if (parent != null) {
- parent.addObject(obj);
- }
- if (addToDatabase) {
- database.put(objectId, obj);
- }
- Log.v("ObjectManager", "Created object %d [%s]", obj.getObjectId(), obj.getTemplate());
- new ObjectCreatedIntent(obj).broadcast();
- return obj;
+ SWGObject obj = ObjectCreator.createObjectFromTemplate(template);
+ if (obj == null) {
+ System.err.println("ObjectManager: Unable to create object with template " + template);
+ return null;
}
+ obj.setLocation(l);
+ if (parent != null) {
+ parent.addObject(obj);
+ }
+ synchronized (database) {
+ if (addToDatabase)
+ database.put(obj.getObjectId(), obj);
+ }
+ Log.v("ObjectManager", "Created object %d [%s]", obj.getObjectId(), obj.getTemplate());
+ new ObjectCreatedIntent(obj).broadcast();
+ return obj;
}
private void zoneInCharacter(PlayerManager playerManager, long netId, long characterId) {
@@ -343,7 +311,7 @@ public class ObjectManager extends Manager {
Log.e("ObjectManager", "Unable to zone in null player '%d'", netId);
return;
}
- SWGObject creatureObj = objectMap.get(characterId);
+ SWGObject creatureObj = getObjectById(characterId);
if (creatureObj == null) {
System.err.println("ObjectManager: Failed to start zone - CreatureObject could not be fetched from database [Character: " + characterId + " User: " + player.getUsername() + "]");
Log.e("ObjectManager", "Failed to start zone - CreatureObject could not be fetched from database [Character: %d User: %s]", characterId, player.getUsername());
@@ -377,10 +345,4 @@ public class ObjectManager extends Manager {
}, timeToRead, time);
}
- private long getNextObjectId() {
- synchronized (objectMap) {
- return maxObjectId++;
- }
- }
-
}