diff --git a/src/resources/equipment/Equipment.java b/src/resources/equipment/Equipment.java index 4a1418ab..3175f6d4 100644 --- a/src/resources/equipment/Equipment.java +++ b/src/resources/equipment/Equipment.java @@ -58,15 +58,14 @@ public class Equipment extends Delta { } public byte[] getBytes() { - if (!(getObject() instanceof TangibleObject)) { - if (getObject() == null) { - System.err.println("Serious error: Equipment object is null in objectList."); - } else { - System.err.println("Serious error: Equipment object isn't a TangibleObject"); - } + SWGObject sobject = getObject(); + + if (sobject == null) { + System.err.println("Serious error: Equipment object is null in objectList. OID: " + getObjectId()); + return null; } - TangibleObject object = (TangibleObject) getObject(); + TangibleObject object = (TangibleObject) sobject; synchronized(objectMutex) { int size = 19 + object.getCustomization ().length; diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 0eaaa13d..09a74693 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -21,6 +21,9 @@ ******************************************************************************/ package resources.objects.creature; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -1431,6 +1434,9 @@ public class CreatureObject extends TangibleObject implements IPersistent { public void sendBaselines(Client destination) { if (destination != null && destination.getSession() != null) { + + //objectFieldDiagnosis(); + destination.getSession().write(getBaseline(3).getBaseline()); destination.getSession().write(getBaseline(6).getBaseline()); if (destination == getClient()) { @@ -1451,6 +1457,45 @@ public class CreatureObject extends TangibleObject implements IPersistent { } } + // Utility method to check which fields are null + public void objectFieldDiagnosis(){ + System.out.println("Object being diagnosed: " + this.getTemplate() + " Id: " + this.getObjectID()); + + ArrayList list = new ArrayList(); + Method[] methods = this.getClass().getDeclaredMethods(); + for (Method method : methods) + if (isGetter(method)){ + try { + Object valueObject = method.invoke(this, (Object[]) null); + if (valueObject==null){ + System.err.println("method " + method.getName() + " delivers null object"); + } + } catch (IllegalAccessException e) { + System.err.println("IllegalAccessException during reflection"); + e.printStackTrace(); + } catch (IllegalArgumentException e) { + System.err.println("IllegalArgumentException during reflection"); + e.printStackTrace(); + } catch (InvocationTargetException e) { + System.err.println("InvocationTargetException during reflection"); + e.printStackTrace(); + } + } + } + + public static boolean isGetter(Method method) { + if (Modifier.isPublic(method.getModifiers()) && + method.getParameterTypes().length == 0) { + if (method.getName().matches("^get[A-Z].*") && + !method.getReturnType().equals(void.class)) + return true; + if (method.getName().matches("^is[A-Z].*") && + method.getReturnType().equals(boolean.class)) + return true; + } + return false; + } + public void sendListDelta(byte viewType, short updateType, IoBuffer buffer) { switch (viewType) { case 1: diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index e8dc0bc0..e2bdfeb4 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -192,6 +192,7 @@ public class SimulationService implements INetworkDispatch { if(notifyObservers) { Point3D pos = new Point3D(x, 0, z); Collection newAwareObjects = get(object.getPlanet(), x, z, 512); + cleanAwareObjects(newAwareObjects); // Only objects that are in objectList are considered!!! for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { SWGObject obj = it.next(); if((obj.getAttachment("bigSpawnRange") == null && obj.getWorldPosition().getDistance2D(pos) > 200) || obj == object) @@ -211,6 +212,17 @@ public class SimulationService implements INetworkDispatch { return success; } + public void cleanAwareObjects(Collection newAwareObjects){ + Collection cleanUpObjects = new ArrayList(); + for(Iterator it = newAwareObjects.iterator(); it.hasNext();) { + SWGObject obj = it.next(); + SWGObject objInList = NGECore.getInstance().objectService.getObject(obj.getObjectID()); + if (objInList==null) + cleanUpObjects.add(obj); + } + newAwareObjects.removeAll(cleanUpObjects); + } + public void addChildObjects(SWGObject object, Vector childObjects) { for(SWGObject childObject : childObjects) { diff --git a/src/services/StaticService.java b/src/services/StaticService.java index e09c2288..0af320d3 100644 --- a/src/services/StaticService.java +++ b/src/services/StaticService.java @@ -127,9 +127,11 @@ public class StaticService implements INetworkDispatch { long buildingId = 0; int cellNumber = 0; - SWGObject cell = core.objectService.getObject(cellId); + SWGObject cell = null; - if (cellId != 0 && cell == null) { + if (cellId != 0L && cellId != 0) { + cell = core.objectService.getObject(cellId); + } else { System.err.println("CellId invalid for template " + template); return null; } diff --git a/src/services/command/CommandService.java b/src/services/command/CommandService.java index 32c7fe68..2b7b218f 100644 --- a/src/services/command/CommandService.java +++ b/src/services/command/CommandService.java @@ -997,6 +997,11 @@ public class CommandService implements INetworkDispatch { @Override public void handlePacket(IoSession session, IoBuffer data) throws Exception { + if (data == null){ + System.out.println("NULL data passed to insertOpcodes, ignoring."); + return; + } + data.order(ByteOrder.LITTLE_ENDIAN); Client client = core.getClient(session); @@ -1017,7 +1022,7 @@ public class CommandService implements INetworkDispatch { BaseSWGCommand command = getCommandByCRC(commandCRC); if (command == null) { - //System.out.println("Unknown Command CRC: " + commandEnqueue.getCommandCRC()); + System.out.println("Unknown Command CRC: " + commandEnqueue.getCommandCRC()); return; } diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 158c8f9a..0106b1e3 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -50,6 +50,7 @@ import resources.common.*; import resources.datatables.DisplayType; import resources.datatables.Options; import resources.datatables.PlayerFlags; +import resources.equipment.Equipment; import resources.guild.Guild; import resources.harvest.SurveyTool; @@ -107,6 +108,7 @@ import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import main.NGECore; import resources.objectives.BountyMissionObjective; +import resources.objects.SWGList; import resources.objects.building.BuildingObject; import resources.objects.cell.CellObject; import resources.objects.craft.DraftSchematic; @@ -575,13 +577,23 @@ public class ObjectService implements INetworkDispatch { if (objectList.containsKey(objectID)) { System.err.println("getObject(): object is null but objectList contains objectID key"); } else { -// System.err.println("getObject(): object is null"); + //System.err.println("getObject(): object is null"); + //Thread.currentThread().dumpStack(); } } return object; } + public boolean checkIfObjectAlreadyInList(long objectID){ + SWGObject object = objectList.get(objectID); + + if (object == null) + return false; + else + return true; + } + public Map getObjectList() { return objectList; } @@ -761,12 +773,50 @@ public class ObjectService implements INetworkDispatch { CreatureObject object = (CreatureObject) core.getSWGObjectODB().get(objectId); if (object != null) { loadServerTemplate(object); + if(! checkIfObjectAlreadyInList(object.getObjectID())) + objectList.put(object.getObjectID(), object); + object.viewChildren(object, true, true, (child) -> loadServerTemplate(child)); + object.viewChildren(object, true, true, (child) -> instantiateChild(child)); } + /* Diagnostic part */ +// System.out.println("Creo : " + object.getCustomName()); +// System.out.println("Creo ID : " + object.getObjectID()); +// System.out.println("Equipment List : " + object.getEquipmentList().size()); + /* Diagnostic part */ + + SWGList eqList = object.getEquipmentList(); + List delList = new ArrayList(); + for (Equipment eq :eqList){ +// System.out.println("Equipment getObjectID() " + eq.getObjectId()); +// System.out.println("Equipment Class " + eq.getObject().getClass()); -> NPE +// System.out.println("Equipment Name " + eq.getObject().getCustomName()); -> NPE +// System.out.println("Equipment Template " + eq.getObject().getTemplate()); -> NPE + + if(! checkIfObjectAlreadyInList(eq.getObjectId())) + delList.add(eq); + } + + + eqList.removeAll(delList); // The persisted equipment list contains objects that do not exist anymore, merely a hotfix really + object.getEquipmentList().clear(); + object.getEquipmentList().addAll(eqList); + return (CreatureObject) object; } + public void instantiateChild(SWGObject child) { +// SWGObject object = (SWGObject) core.getSWGObjectODB().get(child); +// createObject(String Template, long objectID, Planet planet, Point3D position, Quaternion orientation, String customServerTemplate) +// System.out.println("childname : " + child.getCustomName()); +// System.out.println("Child Class " + child.getClass()); + if(! checkIfObjectAlreadyInList(child.getObjectID())) + objectList.put(child.getObjectID(), child); +// System.out.println("Child getObjectID() " + child.getObjectID()); +// System.out.println("Child class " + child.getClass().getName()); + } + public long generateObjectID() { /*Random random = new Random(); @@ -1147,8 +1197,10 @@ public class ObjectService implements INetworkDispatch { System.err.println("NULL Client"); return; } + CreatureObject creature = null; - if(getObject(objectId) == null) { + + if(objectId != 0L && getObject(objectId) == null) { creature = getCreatureFromDB(objectId); if(creature == null) { System.err.println("Cant get creature from db"); @@ -1158,14 +1210,14 @@ public class ObjectService implements INetworkDispatch { System.err.println("Player with ObjID of " + creature.getObjectID() + " tried logging in but has a null/empty name!"); return; } else { - System.err.println("SelectCharacter: not in object list"); + //System.err.println("SelectCharacter: not in object list"); Because it wasnt added still at this point } } } else { if (!(getObject(objectId) instanceof CreatureObject)) { - System.out.println("Character is not an instance of CreatureObject!"); + System.out.println("Character is not an instance of CreatureObject or is null!"); return; } @@ -1222,14 +1274,20 @@ public class ObjectService implements INetworkDispatch { }); creature.viewChildren(creature, true, true, (object) -> { - if(object.getMutex() == null) - object.initializeBaselines(); - object.initAfterDBLoad(); - if(object.getParentId() != 0 && object.getContainer() == null) - object.setParent(getObject(object.getParentId())); - object.getContainerInfo(object.getTemplate()); - if(getObject(object.getObjectID()) == null) - objectList.put(object.getObjectID(), object); + if (object != null) { + if(object.getMutex() == null) + object.initializeBaselines(); + object.initAfterDBLoad(); + if(object.getParentId() != 0 && object.getContainer() == null) + object.setParent(getObject(object.getParentId())); + object.getContainerInfo(object.getTemplate()); +// if(getObject(object.getObjectID()) != null) +// objectList.put(object.getObjectID(), object); + if(! checkIfObjectAlreadyInList(object.getObjectID())) + objectList.put(object.getObjectID(), object); + } else { + Thread.currentThread().dumpStack(); + } }); if(creature.getParentId() != 0) { @@ -1525,7 +1583,8 @@ public class ObjectService implements INetworkDispatch { // Treeku - Refactored to work around duplicate objectIds // Required for instances/heroics which are duplicated ie. 10 times - if(!template.equals("object/cell/shared_cell.iff") && objectId != 0 && getObject(objectId) != null) { + //if(!template.equals("object/cell/shared_cell.iff") && objectId != 0 && getObject(objectId) != null) { + if(!template.equals("object/cell/shared_cell.iff") && objectId != 0 && checkIfObjectAlreadyInList(objectId)) { SWGObject object = getObject(objectId); // Same coordinates is a true duplicate @@ -1544,7 +1603,8 @@ public class ObjectService implements INetworkDispatch { String planetName = planet.getName(); // TODO needs to a way to work for mustafar and kashyyyk which both have instances - if (objectId != 0 && getObject(objectId) != null && (planetName.contains("dungeon") || planetName.contains("adventure"))) { + //if (objectId != 0 && getObject(objectId) != null && (planetName.contains("dungeon") || planetName.contains("adventure"))) { + if (objectId != 0 && checkIfObjectAlreadyInList(objectId) && (planetName.contains("dungeon") || planetName.contains("adventure"))) { SWGObject container = getObject(containerId); float x = (px + ((container == null) ? x1 : container.getPosition().x)); float z = (pz + ((container == null) ? z1 : container.getPosition().z)); @@ -1734,7 +1794,8 @@ public class ObjectService implements INetworkDispatch { // Treeku - Refactored to work around duplicate objectIds // Required for instances/heroics which are duplicated ie. 10 times - if(!template.equals("object/cell/shared_cell.iff") && objectId != 0 && getObject(objectId) != null) { + //if(!template.equals("object/cell/shared_cell.iff") && objectId != 0 && getObject(objectId) != null) { + if(!template.equals("object/cell/shared_cell.iff") && objectId != 0 && (checkIfObjectAlreadyInList(objectId))) { SWGObject object = getObject(objectId); // Same coordinates is a true duplicate @@ -1753,7 +1814,8 @@ public class ObjectService implements INetworkDispatch { String planetName = planet.getName(); // TODO needs to a way to work for mustafar and kashyyyk which both have instances - if (objectId != 0 && getObject(objectId) != null && (planetName.contains("dungeon") || planetName.contains("adventure"))) { + //if (objectId != 0 && getObject(objectId) != null && (planetName.contains("dungeon") || planetName.contains("adventure"))) { + if (objectId != 0 && checkIfObjectAlreadyInList(objectId) && (planetName.contains("dungeon") || planetName.contains("adventure"))) { SWGObject container = getObject(containerId); float x = (px + ((container == null) ? x1 : container.getPosition().x)); float z = (pz + ((container == null) ? z1 : container.getPosition().z));