diff --git a/.gitignore b/.gitignore index de39aaf3..b9cbf8fe 100644 --- a/.gitignore +++ b/.gitignore @@ -78,7 +78,8 @@ odb/cities/je.info.* .buildpath # Log files -debuglogs/ +debuglogs/ +logs/ ################# ## Visual Studio diff --git a/ngengine_public.jar b/ngengine_public.jar index cb601e73..2a5cd790 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/commands/credits.py b/scripts/commands/credits.py index 2ba1d840..6355c894 100644 --- a/scripts/commands/credits.py +++ b/scripts/commands/credits.py @@ -9,7 +9,7 @@ def run(core, actor, target, commandString): if actor: actor.setCashCredits(actor.getCashCredits() + int(arg1)) - actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF Credits: Command completed successfully. You have given yourself ' + arg1 + 'credits.', 0) + actor.sendSystemMessage(' \\#FE2EF7 [GM] \\#FFFFFF Credits: Command completed successfully. You have given yourself ' + arg1 + ' credits.', 0) if actor and target: target.setCashCredits(target.getCashCredits() + int(arg1)) diff --git a/scripts/object/tangible/npe/npe_uniform_box.py b/scripts/object/tangible/npe/npe_uniform_box.py index 959298b9..a4957986 100644 --- a/scripts/object/tangible/npe/npe_uniform_box.py +++ b/scripts/object/tangible/npe/npe_uniform_box.py @@ -88,7 +88,7 @@ def use(core, actor, object): shoes = core.objectService.createObject('object/tangible/wearables/shoes/shared_shoes_s01.iff', actor.getPlanet(), 'item_trader_shoes_02_01') pants = core.objectService.createObject('object/tangible/wearables/pants/shared_pants_s15.iff', actor.getPlanet(), 'item_trader_pants_02_01') shirt = core.objectService.createObject('object/tangible/wearables/shirt/shared_shirt_s05.iff', actor.getPlanet(), 'item_trader_shirt_02_01') - belt = core.objectService.createObject('object/tangible/wearables/armor/zam/shared_armor_zam_wesell_belt.iff', actor.getPlanet()) + belt = core.objectService.createObject('object/tangible/wearables/armor/zam/shared_armor_zam_wesell_belt.iff', actor.getPlanet(), 'item_trader_belt_02_01') items.add(shoes) items.add(pants) items.add(shirt) diff --git a/scripts/object/tangible/wearables/belt/item_bounty_hunter_boots_02_01.py b/scripts/object/tangible/wearables/belt/item_officer_belt_02_01.py similarity index 100% rename from scripts/object/tangible/wearables/belt/item_bounty_hunter_boots_02_01.py rename to scripts/object/tangible/wearables/belt/item_officer_belt_02_01.py diff --git a/scripts/object/tangible/wearables/belt/item_trader_belt_02_01.py b/scripts/object/tangible/wearables/belt/item_trader_belt_02_01.py new file mode 100644 index 00000000..39bb745e --- /dev/null +++ b/scripts/object/tangible/wearables/belt/item_trader_belt_02_01.py @@ -0,0 +1,10 @@ +import sys + +def setup(core, object): + object.setStfFilename('static_item_n') + object.setStfName('item_trader_belt_02_01') + object.setDetailFilename('static_item_d') + object.setDetailName('item_trader_belt_02_01') + object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) + object.setStringAttribute('class_required', 'Trader') + return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py b/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py index e2c47968..7d9fc542 100644 --- a/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py +++ b/scripts/object/tangible/wearables/shirt/item_entertainer_shirt_02_01.py @@ -2,9 +2,9 @@ import sys def setup(core, object): object.setStfFilename('static_item_n') - object.setStfName('item_officer_shirt_02_01') + object.setStfName('item_entertainer_shirt_02_01') object.setDetailFilename('static_item_d') - object.setDetailName('item_officer_shirt_02_01') + object.setDetailName('item_entertainer_shirt_02_01') object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) - object.setStringAttribute('class_required', 'Officer') + object.setStringAttribute('class_required', 'Entertainer') return \ No newline at end of file diff --git a/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py b/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py index 7d9fc542..e2c47968 100644 --- a/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py +++ b/scripts/object/tangible/wearables/shirt/item_officer_shirt_02_01.py @@ -2,9 +2,9 @@ import sys def setup(core, object): object.setStfFilename('static_item_n') - object.setStfName('item_entertainer_shirt_02_01') + object.setStfName('item_officer_shirt_02_01') object.setDetailFilename('static_item_d') - object.setDetailName('item_entertainer_shirt_02_01') + object.setDetailName('item_officer_shirt_02_01') object.setIntAttribute('cat_stat_mod_bonus.@stat_n:agility_modified', 3) - object.setStringAttribute('class_required', 'Entertainer') + object.setStringAttribute('class_required', 'Officer') return \ No newline at end of file diff --git a/scripts/object/weapon/ranged/carbine/weapon_npe_commando_carbine_03_01.py b/scripts/object/weapon/ranged/carbine/weapon_npe_commando_carbine_03_01.py index ffeb530b..019a20c2 100644 --- a/scripts/object/weapon/ranged/carbine/weapon_npe_commando_carbine_03_01.py +++ b/scripts/object/weapon/ranged/carbine/weapon_npe_commando_carbine_03_01.py @@ -13,5 +13,5 @@ def setup(core, object): object.setDamageType("energy"); object.setMinDamage(20); object.setMaxDamage(40); - object.setWeaponType(Weapon.Type.CARBINE); + object.setWeaponType(WeaponType.CARBINE); return \ No newline at end of file diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 2ff36549..7ead765a 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -138,6 +138,7 @@ import engine.resources.scene.Point3D; import engine.resources.scene.Quaternion; import engine.resources.service.InteractiveJythonAcceptor; import engine.resources.service.NetworkDispatch; +import engine.resources.service.UncaughtExceptionLogger; import engine.servers.InteractiveJythonServer; import engine.servers.MINAServer; import engine.servers.PingServer; @@ -146,6 +147,8 @@ import engine.servers.PingServer; public class NGECore { + private static boolean logUnhandledExceptions = false; + public static boolean didServerCrash = false; private static NGECore instance; @@ -242,12 +245,14 @@ public class NGECore { public static boolean PACKET_DEBUG = false; public NGECore() { - + + instance = this; } public void start() { instance = this; + final ThreadMonitor deadlockDetector = new ThreadMonitor(); Thread deadlockMonitor = new Thread(new Runnable() { @Override @@ -515,7 +520,7 @@ public class NGECore { terrainService.loadSnapShotObjects(); objectService.loadServerTemplates(); - objectService.loadBuildings(); + objectService.loadObjects(); harvesterService.loadHarvesters(); simulationService.insertSnapShotObjects(); @@ -623,7 +628,9 @@ public class NGECore { } public static void main(String[] args) { - + //With this class, we are overwriting the JVM's way of handling exceptions that are never caught. Very handy so no try/catch spam for every method. + if (logUnhandledExceptions) Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionLogger("./logs/uncaught")); + NGECore core = new NGECore(); core.start(); @@ -833,7 +840,7 @@ public class NGECore { public long getGalacticTime() { return System.currentTimeMillis() - galacticTime; } - + public void closeODBs() { swgObjectODB.close(); mailODB.close(); diff --git a/src/resources/objects/SWGSet.java b/src/resources/objects/SWGSet.java index fae6145c..b60a9950 100644 --- a/src/resources/objects/SWGSet.java +++ b/src/resources/objects/SWGSet.java @@ -83,159 +83,130 @@ public class SWGSet implements Set, Serializable { } } - public boolean add(E e) { - synchronized(objectMutex) { - if (valid(e)) { - if (set.add(e)) { - queue(item(1, e, null, true, false)); - return true; - } + public synchronized boolean add(E e) { + if (valid(e)) { + if (set.add(e)) { + queue(item(1, e, null, true, false)); + return true; } - + } + + return false; + } + + public synchronized boolean addAll(Collection c) { + List buffer = new ArrayList(); + + for (E e : c) { + if (valid(e) && set.add(e)) { + buffer.add(item(1, e, null, true, false)); + } + } + + if (buffer.size() > 0) { + queue(buffer); + return true; + } else { return false; } } - public boolean addAll(Collection c) { - synchronized(objectMutex) { - List buffer = new ArrayList(); - - for (E e : c) { - if (valid(e) && set.add(e)) { - buffer.add(item(1, e, null, true, false)); - } - } - - if (buffer.size() > 0) { - queue(buffer); - return true; - } else { - return false; + public synchronized void clear() { + set.clear(); + queue(item(2, null, null, false, false)); + } + + public synchronized boolean contains(Object o) { + return set.contains(o); + } + + public synchronized boolean containsAll(Collection c) { + return set.containsAll(c); + } + + public synchronized boolean isEmpty() { + return set.isEmpty(); + } + + public synchronized Iterator iterator() { + return set.iterator(); + } + + public synchronized boolean remove(Object e) { + if (valid(e) && set.remove(e)) { + queue(item(0, e, null, true, false)); + return true; + } + return false; + } + + public synchronized boolean removeAll(Collection c) { + List buffer = new ArrayList(); + + for (Object o : c) { + if (valid(o) && set.remove(o)) { + buffer.add(item(0, o, null, true, false)); } } - } - - public void clear() { - synchronized(objectMutex) { - set.clear(); - queue(item(2, null, null, false, false)); - } - } - - public boolean contains(Object o) { - synchronized(objectMutex) { - return set.contains(o); - } - } - - public boolean containsAll(Collection c) { - synchronized(objectMutex) { - return set.containsAll(c); - } - } - - public boolean isEmpty() { - synchronized(objectMutex) { - return set.isEmpty(); - } - } - - public Iterator iterator() { - synchronized(objectMutex) { - return set.iterator(); - } - } - - public boolean remove(Object e) { - synchronized(objectMutex) { - if (valid(e) && set.remove(e)) { - queue(item(0, e, null, true, false)); - return true; - } - + + if (buffer.size() > 0) { + queue(buffer); + return true; + } else { return false; } } - public boolean removeAll(Collection c) { - synchronized(objectMutex) { - List buffer = new ArrayList(); - - for (Object o : c) { - if (valid(o) && set.remove(o)) { - buffer.add(item(0, o, null, true, false)); - } - } - - if (buffer.size() > 0) { - queue(buffer); - return true; - } else { - return false; - } - } - } - - public boolean retainAll(Collection c) { + public synchronized boolean retainAll(Collection c) { synchronized(objectMutex) { return set.retainAll(c); } } - public int size() { - synchronized(objectMutex) { - return set.size(); - } + public synchronized int size() { + return set.size(); } - public Object[] toArray() { - synchronized(objectMutex) { - return set.toArray(); - } + public synchronized Object[] toArray() { + return set.toArray(); } - public T[] toArray(T[] a) { - synchronized(objectMutex) { - return set.toArray(a); - } + public synchronized T[] toArray(T[] a) { + return set.toArray(a); } - public int getUpdateCounter() { - synchronized(objectMutex) { - return updateCounter; - } + public synchronized int getUpdateCounter() { + return updateCounter; } public Object getMutex() { return objectMutex; } - public byte[] getBytes() { - synchronized(objectMutex) { - byte[] objects = { }; - int size = 0; + public synchronized byte[] getBytes() { + byte[] objects = { }; + int size = 0; + + for (Object o : set) { + byte[] object = Baseline.toBytes(o); + size += object.length; - for (Object o : set) { - byte[] object = Baseline.toBytes(o); - size += object.length; - - IoBuffer buffer = Delta.createBuffer(size); - buffer.put(objects); - if (addByte) buffer.put((byte) 0); - buffer.put(object); - buffer.flip(); - - objects = buffer.array(); - } - - IoBuffer buffer = Delta.createBuffer(8 + size); - buffer.putInt(set.size()); - buffer.putInt(updateCounter); + IoBuffer buffer = Delta.createBuffer(size); buffer.put(objects); + if (addByte) buffer.put((byte) 0); + buffer.put(object); buffer.flip(); - return buffer.array(); + objects = buffer.array(); } + + IoBuffer buffer = Delta.createBuffer(8 + size); + buffer.putInt(set.size()); + buffer.putInt(updateCounter); + buffer.put(objects); + buffer.flip(); + + return buffer.array(); } private boolean valid(Object o) { diff --git a/src/resources/objects/cell/CellObject.java b/src/resources/objects/cell/CellObject.java index 9c25167b..07665658 100644 --- a/src/resources/objects/cell/CellObject.java +++ b/src/resources/objects/cell/CellObject.java @@ -78,7 +78,7 @@ public class CellObject extends SWGObject implements Serializable { public void sendBaselines(Client destination) { if(destination == null || destination.getSession() == null) { - System.out.println("NULL session"); + System.out.println("NULL session [baseline]"); return; } @@ -91,7 +91,7 @@ public class CellObject extends SWGObject implements Serializable { public void sendPermissionMessage(Client destination) { if(destination == null || destination.getSession() == null) { - System.out.println("NULL session"); + System.out.println("NULL session [permission]"); return; } diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 35d77884..91dd3446 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -207,6 +207,9 @@ public class CreatureObject extends TangibleObject implements Serializable { public CreatureObject() { super(); messageBuilder = new CreatureMessageBuilder(this); + System.out.println("Name: " + getCustomName()); + System.out.println(" Cash Credits: " + cashCredits); + System.out.println(" Bank Credits: " + bankCredits); } @Override @@ -224,6 +227,7 @@ public class CreatureObject extends TangibleObject implements Serializable { missionCriticalObjects.init(this); abilities.init(this); skillMods.init(this); + skills.init(this); } private void loadTemplateData() { diff --git a/src/resources/objects/waypoint/WaypointObject.java b/src/resources/objects/waypoint/WaypointObject.java index 189a310e..fa04db07 100644 --- a/src/resources/objects/waypoint/WaypointObject.java +++ b/src/resources/objects/waypoint/WaypointObject.java @@ -67,87 +67,63 @@ public class WaypointObject extends IntangibleObject implements Serializable, ID super.init(); } - public int getCellId() { - synchronized(objectMutex) { - return cellId; - } + public synchronized int getCellId() { + return cellId; } - public void setCellId(int cellId) { - synchronized(objectMutex) { - this.cellId = cellId; - } + public synchronized void setCellId(int cellId) { + this.cellId = cellId; } - public long getLocationNetworkId() { - synchronized(objectMutex) { - return locationNetworkId; - } + public synchronized long getLocationNetworkId() { + return locationNetworkId; } - public void setLocationNetworkId(long locationNetworkId) { - synchronized(objectMutex) { - this.locationNetworkId = locationNetworkId; - } + public synchronized void setLocationNetworkId(long locationNetworkId) { + this.locationNetworkId = locationNetworkId; } - public int getPlanetCRC() { - synchronized(objectMutex) { - return planetCRC; - } + public synchronized int getPlanetCRC() { + return planetCRC; } - public void setPlanetCRC(int planetCRC) { - synchronized(objectMutex) { - this.planetCRC = planetCRC; - } + public synchronized void setPlanetCRC(int planetCRC) { + this.planetCRC = planetCRC; } - public String getName() { - synchronized(objectMutex) { - return name; - } + public synchronized String getName() { + return name; } - public void setName(String name) { - synchronized(objectMutex) { - this.name = name; - } + public synchronized void setName(String name) { + this.name = name; } - public byte getColor() { - synchronized(objectMutex) { - return color; - } + public synchronized byte getColor() { + return color; } - public void setColor(byte color) { - synchronized(objectMutex) { - this.color = color; - } + public synchronized void setColor(byte color) { + this.color = color; } - public boolean isActive() { - synchronized(objectMutex) { - return isActive; - } + public synchronized boolean isActive() { + return isActive; } public void setActive(boolean isActive) { - synchronized(objectMutex) { - this.isActive = isActive; - } + this.isActive = isActive; } @Override diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 9755562a..873b3fa7 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -354,6 +354,7 @@ public class CharacterService implements INetworkDispatch { createStarterClothing(object, sharedRaceTemplate, clientCreateCharacter.getStarterProfession()); //core.scriptService.callScript("scripts/", "demo", "CreateStartingCharacter", core, object); + System.out.println("Saving character with name: " + object.getCustomName()); core.getSWGObjectODB().put(object.getObjectID(), object); PreparedStatement ps = databaseConnection.preparedStatement("INSERT INTO characters (id, \"firstName\", \"lastName\", \"accountId\", \"galaxyId\", \"statusId\", appearance, gmflag) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); diff --git a/src/services/command/CommandService.java b/src/services/command/CommandService.java index 55322af8..7ae337d2 100644 --- a/src/services/command/CommandService.java +++ b/src/services/command/CommandService.java @@ -724,7 +724,7 @@ public class CommandService implements INetworkDispatch { } else { if (FileUtilities.doesFileExist("scripts/commands/" + command.getCommandName().toLowerCase() + ".py")) { System.err.print("Command " + command.getCommandName() + " is considered a combat command by the client but has a regular command script!"); - core.scriptService.callScript("scripts/commands/combat/", command.getCommandName().toLowerCase(), "run", core, attacker, target, ""); + core.scriptService.callScript("scripts/commands/", command.getCommandName().toLowerCase(), "run", core, attacker, target, ""); } } diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index b15df3b3..08ff36fa 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -55,6 +55,7 @@ import resources.harvest.SurveyTool; import org.apache.commons.lang3.text.WordUtils; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; +import org.python.antlr.PythonParser.list_for_return; import org.python.core.Py; import org.python.core.PyObject; @@ -173,6 +174,7 @@ public class ObjectService implements INetworkDispatch { core.harvesterService.saveHarvesters(); core.playerCityService.saveAllCities(); core.closeODBs(); + System.out.println("Databases closed."); } }); @@ -190,7 +192,21 @@ public class ObjectService implements INetworkDispatch { } } - public void loadBuildings() { + public void loadObjects() { + System.out.println("Loading objects..."); + ODBCursor cursor = core.getSWGObjectODB().getCursor(); + + while (cursor.hasNext()) { + SWGObject object = (SWGObject) cursor.next(); + if (object != null && !(object instanceof BuildingObject) && !objectList.containsKey(object.getObjectID())) + objectList.put(object.getObjectID(), object); + } + + loadBuildings(); + System.out.println("Finished loading objects."); + } + + private void loadBuildings() { ODBCursor cursor = core.getSWGObjectODB().getCursor(); while(cursor.hasNext()) { @@ -254,15 +270,17 @@ public class ObjectService implements INetworkDispatch { } } - synchronized(objectMutex) { - if(objectID == 0) - objectID = generateObjectID(); - else - isSnapshot = !overrideSnapshot; - - if(!core.getObjectIdODB().contains(objectID)) - core.getObjectIdODB().put(objectID, new ObjectId(objectID)); - } + if (objectID == 0) { + synchronized(objectMutex) { + if(objectID == 0) + objectID = generateObjectID(); + + if(!core.getObjectIdODB().contains(objectID)) + core.getObjectIdODB().put(objectID, new ObjectId(objectID)); + } + } else + isSnapshot = !overrideSnapshot; + if (planet == null) { System.err.println("Planet is null in createObject for some reason."); @@ -475,10 +493,10 @@ public class ObjectService implements INetworkDispatch { SWGObject ret = objectList.put(objectID, object); //if (ret != null && !ret.getTemplate().equals(object.getTemplate())) { - if (ret == null) { - //System.err.println("ObjectService: Detected duplicate Id. Assigning new one.") - object = createObject(Template, objectID, planet, position, orientation, customServerTemplate, overrideSnapshot, loadServerTemplate); - } +// if (ret == null) { +// //System.err.println("ObjectService: Detected duplicate Id. Assigning new one.") +// object = createObject(Template, objectID, planet, position, orientation, customServerTemplate, overrideSnapshot, loadServerTemplate); +// } return object; } @@ -540,7 +558,7 @@ 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"); } } @@ -717,10 +735,8 @@ public class ObjectService implements INetworkDispatch { } public CreatureObject getCreatureFromDB(long objectId) { - SWGObject object = (SWGObject) core.getSWGObjectODB().get(objectId); - if(!(object instanceof CreatureObject)) - return null; - if (object != null && getObject(object.getObjectID()) == null) { + CreatureObject object = (CreatureObject) core.getSWGObjectODB().get(objectId); + if (object != null) { loadServerTemplate(object); object.viewChildren(object, true, true, (child) -> loadServerTemplate(child)); } @@ -1028,14 +1044,16 @@ public class ObjectService implements INetworkDispatch { } CreatureObject creature = null; if(getObject(objectId) == null) { - System.out.println("SelectCharacter: not in object list"); creature = getCreatureFromDB(objectId); if(creature == null) { System.out.println("Cant get creature from db"); } else { - if (creature.getCustomName() == null || creature.getCustomName() == "") { + if (creature.getCustomName() == null || creature.getCustomName().isEmpty()) { + System.err.println("Name: " + creature.getCustomName()); System.out.println("Player with ObjID of " + creature.getObjectID() + " tried logging in but has a null/empty name!"); return; + } else { + System.out.println("SelectCharacter: not in object list"); } } @@ -1045,6 +1063,9 @@ public class ObjectService implements INetworkDispatch { return; creature = (CreatureObject) getObject(objectId); + if (creature.getCustomName() == null || creature.getCustomName().isEmpty()) { + System.err.println("Creature's custom name was null/empty! Name: " + creature.getCustomName()); + } if(creature.getAttachment("disconnectTask") != null && creature.getClient() != null && !creature.getClient().getSession().isClosing()) return; @@ -1200,6 +1221,13 @@ public class ObjectService implements INetworkDispatch { }); } + // New players that skip tutorial + if (creature.getLevel() <= (short) 1) { + core.playerService.grantLevel(creature, 5); + TangibleObject inventory = (TangibleObject) creature.getSlottedObject("inventory"); + if (inventory != null) inventory.add(core.objectService.createObject("object/tangible/npe/shared_npe_uniform_box.iff", creature.getPlanet())); + } + core.playerService.postZoneIn(creature); }