Cloning works now, changed object list to hash map (significant performance increase)

This commit is contained in:
Light2
2013-09-21 19:02:35 +02:00
parent b676dffdec
commit c7bfc890bd
13 changed files with 145 additions and 59 deletions
+7
View File
@@ -84,6 +84,8 @@ import engine.servers.PingServer;
public class NGECore {
public static boolean didServerCrash = false;
private static NGECore instance;
private Config config = null;
@@ -135,6 +137,8 @@ public class NGECore {
}
public void start() {
instance = this;
config = new Config();
config.setFilePath("nge.cfg");
if (!(config.loadConfigFile())) {
@@ -375,5 +379,8 @@ public class NGECore {
return Thread.currentThread();
}
public static NGECore getInstance() {
return instance;
}
}
@@ -48,16 +48,20 @@ public class StartTask extends ObjControllerObject {
@Override
public IoBuffer serialize() {
IoBuffer result = IoBuffer.allocate(33).order(ByteOrder.LITTLE_ENDIAN);
IoBuffer result = IoBuffer.allocate(37).order(ByteOrder.LITTLE_ENDIAN);
result.putInt(ObjControllerMessage.START_TASK);
result.putLong(objectId);
result.putInt(0);
result.put((byte) 0);
result.put((byte) 4); // 0 for no cooldown, 0x26 adds execute time (usually 0.25)
result.putInt(actionCounter);
result.putLong(0);
result.putInt(0);
result.putInt(0);
result.putInt(commandCRC);
result.putInt(0); // second unknown crc
result.putInt(0); // unk
result.putFloat(0); // cooldown
return result.flip();
+47 -2
View File
@@ -22,10 +22,17 @@
package resources.objects;
import java.nio.ByteOrder;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import main.NGECore;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.buffer.SimpleBufferAllocator;
import resources.objects.creature.CreatureObject;
import com.sleepycat.persist.model.NotPersistent;
import com.sleepycat.persist.model.Persistent;
@@ -56,7 +63,9 @@ public class Buff implements IListObject {
private boolean decayOnPvPDeath;
private long startTime;
private int totalPlayTime;
private byte decayCounter;
private byte decayCounter = 0;
@NotPersistent
private ScheduledFuture<?> removalTask;
public Buff(String buffName, long ownerId) {
@@ -355,8 +364,44 @@ public class Buff implements IListObject {
return decayCounter;
}
public void incDecayCounter(byte decayCounter) {
public void incDecayCounter() {
this.decayCounter++;
}
public ScheduledFuture<?> getRemovalTask() {
return removalTask;
}
public void setRemovalTask(ScheduledFuture<?> removalTask) {
this.removalTask = removalTask;
}
public void updateRemovalTask() {
if(removalTask == null)
return;
removalTask.cancel(true);
final NGECore core = NGECore.getInstance();
final CreatureObject owner = (CreatureObject) core.objectService.getObject(getOwnerId());
if(owner == null)
return;
ScheduledFuture<?> task = Executors.newScheduledThreadPool(1).schedule(new Runnable() {
@Override
public void run() {
core.buffService.removeBuffFromCreature(owner, Buff.this);
}
}, (long) getRemainingDuration(), TimeUnit.SECONDS);
setRemovalTask(task);
}
}
@@ -1042,7 +1042,23 @@ public class CreatureObject extends TangibleObject implements IPersistent {
}
notifyObservers(messageBuilder.buildRemoveBuffDelta(buff), true);
}
public void updateBuff(Buff buff) {
buff.updateRemovalTask();
synchronized(objectMutex) {
setBuffListCounter(getBuffListCounter() + 1);
notifyObservers(messageBuilder.buildUpdateBuffDelta(buff), true);
}
}
public void updateAllBuffs() {
synchronized(objectMutex) {
for(Buff buff : buffList.get()) {
updateBuff(buff);
}
}
}
public int getBuffListCounter() {
synchronized(objectMutex) {
return buffListUpdateCounter;
+7 -2
View File
@@ -24,6 +24,7 @@ package services;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -92,7 +93,7 @@ public class BuffService implements INetworkDispatch {
if(buff.getDuration() > 0) {
scheduler.schedule(new Runnable() {
ScheduledFuture<?> task = scheduler.schedule(new Runnable() {
@Override
public void run() {
@@ -103,6 +104,9 @@ public class BuffService implements INetworkDispatch {
}
}, (long) buff.getDuration(), TimeUnit.SECONDS);
buff.setRemovalTask(task);
}
}
@@ -124,7 +128,7 @@ public class BuffService implements INetworkDispatch {
for(final Buff buff : creature.getBuffList().get().toArray(new Buff[] { })) {
if(buff.getRemainingDuration() > 0 && buff.getDuration() > 0) {
scheduler.schedule(new Runnable() {
ScheduledFuture<?> task = scheduler.schedule(new Runnable() {
@Override
public void run() {
@@ -134,6 +138,7 @@ public class BuffService implements INetworkDispatch {
}
}, (long) buff.getRemainingDuration(), TimeUnit.SECONDS);
buff.setRemovalTask(task);
continue;
} else {
removeBuffFromCreature(creature, buff);
+1 -3
View File
@@ -264,10 +264,8 @@ public class CharacterService implements INetworkDispatch {
object._add(weapon);
object.setWeaponId(weapon.getObjectID());
core.scriptService.callScript("scripts/", "demo", "CreateStartingCharacter", core, object);
core.scriptService.callScript("scripts/", "CreateStartingCharacter", "demo", core, object);
core.getCreatureODB().put(object, Long.class, CreatureObject.class, object.getTransaction());
// might not need to commit transaction but better safe than sorry
object.getTransaction().commitSync();
+33 -3
View File
@@ -22,6 +22,7 @@
package services;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -40,7 +41,9 @@ import protocol.swg.ServerTimeMessage;
import resources.common.FileUtilities;
import resources.common.Opcodes;
import resources.common.SpawnPoint;
import resources.objects.Buff;
import resources.objects.building.BuildingObject;
import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
import resources.objects.player.PlayerObject;
import services.sui.SUIService.ListBoxType;
@@ -193,7 +196,7 @@ public class PlayerService implements INetworkDispatch {
}
public void sendCloningWindow(CreatureObject creature) {
public void sendCloningWindow(CreatureObject creature, final boolean pvpDeath) {
//if(creature.getPosture() != 14)
// return;
@@ -236,7 +239,7 @@ public class PlayerService implements INetworkDispatch {
SpawnPoint spawnPoint = spawnPoints.get(new Random().nextInt(spawnPoints.size()));
handleCloneRequest((CreatureObject) owner, (BuildingObject) cloner, spawnPoint);
handleCloneRequest((CreatureObject) owner, (BuildingObject) cloner, spawnPoint, pvpDeath);
}
@@ -246,8 +249,35 @@ public class PlayerService implements INetworkDispatch {
}
public void handleCloneRequest(CreatureObject creature, BuildingObject cloner, SpawnPoint spawnPoint) {
public void handleCloneRequest(CreatureObject creature, BuildingObject cloner, SpawnPoint spawnPoint, boolean pvpDeath) {
CellObject cell = cloner.getCellByCellNumber(spawnPoint.getCellNumber());
if(cell == null)
return;
core.simulationService.transferToPlanet(creature, cloner.getPlanet(), spawnPoint.getPosition(), spawnPoint.getOrientation(), cell);
creature.setHealth(creature.getMaxHealth());
creature.setAction(creature.getMaxAction());
creature.setPosture((byte) 0);
creature.setSpeedMultiplierBase(1);
creature.setTurnRadius(1);
if(pvpDeath) {
List<Buff> buffs = new ArrayList<Buff>(creature.getBuffList().get());
for(Buff buff : buffs) {
if(buff.isDecayOnPvPDeath())
buff.incDecayCounter();
}
creature.updateAllBuffs();
}
creature.setFactionStatus(0);
core.buffService.addBuffToCreature(creature, "cloning_sickness");
}
+8 -9
View File
@@ -103,7 +103,7 @@ public class SimulationService implements INetworkDispatch {
quadTrees.put(terrainService.getPlanetList().get(i).getName(), new QuadTree<SWGObject>(-8192, -8192, 8192, 8192));
}
List<SWGObject> objectList = new ArrayList<SWGObject>(core.objectService.getObjectList());
List<SWGObject> objectList = new ArrayList<SWGObject>(core.objectService.getObjectList().values());
for(SWGObject obj : objectList) {
if(obj.getParentId() == 0 && obj.isInSnapshot()) {
core.objectService.loadServerTemplate(obj);
@@ -550,8 +550,8 @@ public class SimulationService implements INetworkDispatch {
}
}
public void transferToPlanet(SWGObject object, Planet planet, Point3D newPos, Quaternion newOrientation) {
public void transferToPlanet(SWGObject object, Planet planet, Point3D newPos, Quaternion newOrientation, SWGObject newParent) {
Client client = object.getClient();
@@ -582,12 +582,8 @@ public class SimulationService implements INetworkDispatch {
synchronized(object.getMutex()) {
Iterator<SWGObject> it = object.getAwareObjects().iterator();
object.getAwareObjects().removeAll(object.getAwareObjects());
while(it.hasNext()) {
it.remove();
}
}
object.setPlanet(planet);
@@ -595,6 +591,9 @@ public class SimulationService implements INetworkDispatch {
object.setPosition(newPos);
object.setOrientation(newOrientation);
if(newParent != null && newParent instanceof CellObject)
newParent._add(object);
HeartBeatMessage heartBeat = new HeartBeatMessage();
session.write(heartBeat.serialize());
@@ -604,8 +603,8 @@ public class SimulationService implements INetworkDispatch {
handleZoneIn(client);
object.makeAware(object);
}
public void openContainer(SWGObject requester, SWGObject container) {
+1 -1
View File
@@ -795,7 +795,7 @@ public class CombatService implements INetworkDispatch {
attacker.removeDefender(target);
target.removeDefender(attacker);
// TODO: Create Clone SUI Window
core.playerService.sendCloningWindow(target, attacker.getSlottedObject("ghost") != null);
}
+1 -1
View File
@@ -41,7 +41,7 @@ public class GuildService implements INetworkDispatch {
public GuildService(NGECore core) {
this.core = core;
for (SWGObject swgObject : core.objectService.getObjectList()) {
for (SWGObject swgObject : core.objectService.getObjectList().values()) {
if (swgObject.getTemplate().equals("object/guild/shared_guild_object.iff") && swgObject instanceof GuildObject) {
object = (GuildObject) swgObject;
}
+1
View File
@@ -112,6 +112,7 @@ public class MapService implements INetworkDispatch {
MapLocation location = new MapLocation(planet, nextId.incrementAndGet(), name, x, y, category, subcategory, active);
locationMap.get(planet).add(location);
}
public String getClosestCityName(SWGObject object) {
+14 -34
View File
@@ -82,7 +82,7 @@ import resources.objects.weapon.WeaponObject;
public class ObjectService implements INetworkDispatch {
private List<SWGObject> objectList = Collections.synchronizedList(new ArrayList<SWGObject>());
private Map<Long, SWGObject> objectList = new ConcurrentHashMap<Long, SWGObject>();
private NGECore core;
@@ -101,7 +101,7 @@ public class ObjectService implements INetworkDispatch {
@Override
public void run() {
synchronized(objectList) {
for(SWGObject obj : objectList) {
for(SWGObject obj : objectList.values()) {
if(obj.getSlottedObject("ghost") != null) {
((CreatureObject) obj).createTransaction(core.getCreatureODB().getEnvironment());
@@ -192,7 +192,7 @@ public class ObjectService implements INetworkDispatch {
loadServerTemplate(object);
objectList.add(object);
objectList.put(objectID, object);
return object;
}
@@ -238,38 +238,20 @@ public class ObjectService implements INetworkDispatch {
}
public SWGObject getObject(long objectID) {
SWGObject object = null;
synchronized(objectList) {
Iterator<SWGObject> it = objectList.iterator();
while(it.hasNext()) {
SWGObject swgObject = it.next();
if(swgObject.getObjectID() == objectID) {
object = swgObject;
break;
}
}
}
return object;
return objectList.get(objectID);
}
public List<SWGObject> getObjectList() { return objectList; }
public Map<Long, SWGObject> getObjectList() { return objectList; }
public void destroyObject(SWGObject object) {
object.viewChildren(object, true, true, new Traverser() {
@Override
public void process(SWGObject obj) {
objectList.remove(obj);
objectList.remove(obj.getObjectID());
}
});
objectList.remove(object);
objectList.remove(object.getObjectID());
//core.simulationService.remove(object, object.getPosition().x, object.getPosition().y);
}
@@ -280,20 +262,18 @@ public class ObjectService implements INetworkDispatch {
if(object != null) {
destroyObject(object);
}
}
public SWGObject getObjectByCustomName(String customName) {
synchronized(objectList) {
Iterator<SWGObject> it = objectList.iterator();
while(it.hasNext()) {
SWGObject obj = it.next();
for(SWGObject obj : objectList.values()) {
if(obj.getCustomName() == null)
continue;
if(obj.getCustomName().equals(customName))
return it.next();
return obj;
}
}
@@ -387,13 +367,13 @@ public class ObjectService implements INetworkDispatch {
creature.setPlanet(planet);
client.setParent(creature);
objectList.add(creature);
objectList.put(creature.getObjectID(), creature);
creature.viewChildren(creature, true, true, new Traverser() {
@Override
public void process(SWGObject object) {
objectList.add(object);
objectList.put(object.getObjectID(), object);
}
});
@@ -406,7 +386,7 @@ public class ObjectService implements INetworkDispatch {
object.setParent(getObject(object.getParentId()));
object.getContainerInfo(object.getTemplate());
if(getObject(object.getObjectID()) == null)
objectList.add(object);
objectList.put(object.getObjectID(), object);
}
});
@@ -479,7 +459,7 @@ public class ObjectService implements INetworkDispatch {
}
visitor.dispose();
synchronized(objectList) {
for(SWGObject obj : objectList) {
for(SWGObject obj : objectList.values()) {
if(obj.getParentId() != 0 && getObject(obj.getParentId()) != null) {
SWGObject parent = getObject(obj.getParentId());
parent.add(obj);
@@ -21,6 +21,7 @@
******************************************************************************/
package services.object;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -60,7 +61,7 @@ public class ObjectTransactionManager implements Runnable {
Thread.sleep(cycleTime);
List<SWGObject> swgObjects = objService.getObjectList();
Collection<SWGObject> swgObjects = objService.getObjectList().values();
synchronized(swgObjects) {