From 1f8c41932794e9a61f2c0c1cf8a07a986eb35618 Mon Sep 17 00:00:00 2001 From: Waverunner Date: Thu, 21 May 2015 17:32:21 -0400 Subject: [PATCH 1/2] Updated readme to include information on running holocore --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26702e096..fee7f4707 100644 --- a/README.md +++ b/README.md @@ -31,4 +31,25 @@ 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 . \ No newline at end of file +along with Holocore. If not, see . + +### Running Holocore ### +In order to successfully build and run Holocore, you must: + +1. Have a valid Star Wars Galaxies installation that is updated from the final patch. +2. Setup a postgresql server, preferably on localhost, with a database and user named nge with read/write permissions. + * Note: You will need to restore the database that you created using nge.backup in order to create the proper tables. +3. Extract the following contents of the sku's to a new clientdata folder in the holocore directory: + * abstract + * appearance + * creation + * customization + * datatables + * footprint + * interiorlayout + * misc + * object + * quest + * snapshot + * string + * terrain \ No newline at end of file From d541624dc7c4495eb729fb3343147f7380258edb Mon Sep 17 00:00:00 2001 From: Waverunner Date: Thu, 21 May 2015 23:10:02 -0400 Subject: [PATCH 2/2] Added the capability to destroy objects --- .../generic/setWaypointActiveStatus.py | 2 +- .../packets/swg/zone/SceneDestroyObject.java | 2 +- .../callbacks/RequestWaypointCmdCallback.java | 2 +- .../ServerDestroyObjectCmdCallback.java | 57 +++++++++++++++++++ src/resources/objects/SWGObject.java | 33 ++++++----- .../objects/creature/CreatureObject.java | 9 ++- src/services/commands/CommandService.java | 4 +- src/services/objects/ObjectCreator.java | 2 +- src/services/objects/ObjectManager.java | 37 +++++++++++- src/services/player/LoginService.java | 2 +- 10 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 src/resources/commands/callbacks/ServerDestroyObjectCmdCallback.java diff --git a/scripts/commands/generic/setWaypointActiveStatus.py b/scripts/commands/generic/setWaypointActiveStatus.py index b25d0d2b0..d79f89439 100644 --- a/scripts/commands/generic/setWaypointActiveStatus.py +++ b/scripts/commands/generic/setWaypointActiveStatus.py @@ -2,7 +2,7 @@ import sys def execute(objManager, player, target, args): ghost = player.getPlayerObject() - if ghost is None: + if ghost is None or target is None: return waypoint = ghost.getWaypoint(target.getObjectId()) diff --git a/src/network/packets/swg/zone/SceneDestroyObject.java b/src/network/packets/swg/zone/SceneDestroyObject.java index eecfdfe31..e3ec45195 100644 --- a/src/network/packets/swg/zone/SceneDestroyObject.java +++ b/src/network/packets/swg/zone/SceneDestroyObject.java @@ -42,7 +42,7 @@ public class SceneDestroyObject extends SWGPacket { } public SceneDestroyObject(long objId) { - + this.objId = objId; } public SceneDestroyObject(ByteBuffer data) { diff --git a/src/resources/commands/callbacks/RequestWaypointCmdCallback.java b/src/resources/commands/callbacks/RequestWaypointCmdCallback.java index 1ac0744b1..3c7364c9a 100644 --- a/src/resources/commands/callbacks/RequestWaypointCmdCallback.java +++ b/src/resources/commands/callbacks/RequestWaypointCmdCallback.java @@ -39,7 +39,7 @@ public class RequestWaypointCmdCallback implements ICmdCallback { @Override public void execute(GalacticManager galacticManager, Player player, SWGObject target, String args) { // Args: (^-,=+_)color_1(,+-=_^)=1 planet x 0.0 z - PlayerObject ghost = (PlayerObject) player.getPlayerObject(); + PlayerObject ghost = player.getPlayerObject(); if (ghost == null) return; diff --git a/src/resources/commands/callbacks/ServerDestroyObjectCmdCallback.java b/src/resources/commands/callbacks/ServerDestroyObjectCmdCallback.java new file mode 100644 index 000000000..0aec3e83e --- /dev/null +++ b/src/resources/commands/callbacks/ServerDestroyObjectCmdCallback.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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 resources.commands.callbacks; + +import resources.commands.ICmdCallback; +import resources.objects.SWGObject; +import resources.objects.player.PlayerObject; +import resources.objects.waypoint.WaypointObject; +import resources.player.Player; +import services.galaxy.GalacticManager; +import services.objects.ObjectManager; + +public class ServerDestroyObjectCmdCallback implements ICmdCallback { + @Override + public void execute(GalacticManager galacticManager, Player player, SWGObject target, String args) { + + if (target == null) + return; + + ObjectManager objectManager = galacticManager.getObjectManager(); + + // TODO Take into account container permissions + + if (target instanceof WaypointObject) { + PlayerObject ghost = player.getPlayerObject(); + ghost.removeWaypoint(target.getObjectId()); + objectManager.deleteObject(target.getObjectId()); + } else { + objectManager.destroyObject(target); + } + } +} diff --git a/src/resources/objects/SWGObject.java b/src/resources/objects/SWGObject.java index 5521bcac6..3aee4ed4d 100644 --- a/src/resources/objects/SWGObject.java +++ b/src/resources/objects/SWGObject.java @@ -60,7 +60,7 @@ public class SWGObject implements Serializable, Comparable { private static final long serialVersionUID = 1L; - private final List children; + private final List children; // TODO Move this into slot-type system as only containers can have multiple children in 1 slot private final Location location; private final long objectId; private final Map slots; // Can only be occupied one time, containers are slots who have children @@ -111,13 +111,13 @@ public class SWGObject implements Serializable, Comparable { private void updateContainment(SWGObject child) { if (child.parent != null) - child.parent.removeChild(child); + child.parent.removeChild(child); // Is this necessary? child.parent = this; Integer containmentType = (Integer)child.getTemplateAttribute("containerType"); if (containmentType == null) child.containmentType = 4; else - child.containmentType = containmentType.intValue(); + child.containmentType = containmentType; // TODO: Set containmentType based on if object is in a slot (4) or a container (-1) } @@ -143,7 +143,9 @@ public class SWGObject implements Serializable, Comparable { public boolean hasSlot(String slot) { return slots.containsKey(slot); } - + + // TODO Refactor slots to just be used in addChild and removeChild as the proper slots can be set by using arrangement descriptors + public boolean setSlot(String slot, SWGObject obj) { if (!slots.containsKey(slot)) { System.err.println("Could not set " + obj.getTemplate() + " to " + getTemplate() + " as it doesn't contain slot " + slot + "!"); @@ -160,7 +162,7 @@ public class SWGObject implements Serializable, Comparable { } if (occupiedAvailSlots.size() != arrangement.size()) { - System.err.println("Doesn't have all the slots."); + System.err.println("Needed slots are not available for " + obj); return false; } @@ -171,8 +173,8 @@ public class SWGObject implements Serializable, Comparable { return true; } - - public void clearSlot(String slot) { + + private void clearSlot(String slot) { if (!slots.containsKey(slot)) { System.err.println("Could not clear " + slot + " as it doesn't contain that slot!"); return; @@ -188,6 +190,11 @@ public class SWGObject implements Serializable, Comparable { synchronized (children) { children.remove(object); } + + for (String slot : object.getArrangement().get(0)) { + clearSlot(slot); + } + object.parent = null; } @@ -305,8 +312,8 @@ public class SWGObject implements Serializable, Comparable { public List> getArrangement() { return arrangement; } - - public void setArrangment(List> arrangement) { + + public void setArrangement(List> arrangement) { this.arrangement = arrangement; } @@ -341,11 +348,7 @@ public class SWGObject implements Serializable, Comparable { createChildrenObjects(target); target.sendPacket(new SceneEndBaselines(getObjectId())); } - - protected void destroyObject(Player target) { - sendSceneDestroyObject(target); - } - + public void clearAware() { SWGObject [] objects; synchronized (objectsAware) { @@ -399,7 +402,7 @@ public class SWGObject implements Serializable, Comparable { synchronized (objectsAware) { if (objectsAware.remove(o)) { if (o.getOwner() != null) { - destroyObject(o.getOwner()); + sendSceneDestroyObject(o.getOwner()); } if (getOwner() != null) o.awarenessOutOfRange(this); diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 29f225b51..a6b5a224d 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -127,7 +127,14 @@ public class CreatureObject extends TangibleObject { for(String slotName : slotNameList) super.setSlot(slotName, item); } - + + public void removeEquipment(SWGObject obj) { + synchronized (equipmentList) { + if (equipmentList.remove(obj)) + equipmentList.sendDeltaMessage(this); + } + } + public void addEquipment(SWGObject obj) { synchronized(equipmentList) { if (obj instanceof WeaponObject) diff --git a/src/services/commands/CommandService.java b/src/services/commands/CommandService.java index 6eb8984e9..b8b06faa3 100644 --- a/src/services/commands/CommandService.java +++ b/src/services/commands/CommandService.java @@ -86,7 +86,8 @@ public class CommandService extends Service { private void handleCommandRequest(Player player, GalacticManager galacticManager, CommandQueueEnqueue request) { if (!commands.containsKey(request.getCommandCrc())) return; -// System.out.println(commands.get(request.getCrc()).toString()); +// System.out.println(commands.get(request.getCommandCrc()).toString()); + SWGObject target = null; if (request.getTargetId() != 0) { target = galacticManager.getObjectManager().getObjectById(request.getTargetId()); } @@ -159,5 +160,6 @@ public class CommandService extends Service { registerCallback("kneel", new KneelCmdCallback()); registerCallback("toggleAwayFromKeyBoard", new AfkCmdCallback()); registerCallback("jumpServer", new JumpCmdCallback()); + registerCallback("serverDestroyObject", new ServerDestroyObjectCmdCallback()); } } diff --git a/src/services/objects/ObjectCreator.java b/src/services/objects/ObjectCreator.java index cb3a8e169..bbc130a2a 100644 --- a/src/services/objects/ObjectCreator.java +++ b/src/services/objects/ObjectCreator.java @@ -118,7 +118,7 @@ public final class ObjectCreator { if (attributes.getAttribute(ObjectData.ARRANGEMENT_FILE) != null) { // This is what slots the object *USES* SlotArrangementData arrangementData = (SlotArrangementData) clientFac.getInfoFromFile((String) attributes.getAttribute(ObjectData.ARRANGEMENT_FILE)); - obj.setArrangment(arrangementData.getArrangement()); + obj.setArrangement(arrangementData.getArrangement()); } } diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java index 21f534470..ee04b2baa 100644 --- a/src/services/objects/ObjectManager.java +++ b/src/services/objects/ObjectManager.java @@ -40,6 +40,7 @@ import main.ProjectSWG; import network.packets.Packet; import network.packets.swg.zone.HeartBeatMessage; import network.packets.swg.zone.ParametersMessage; +import network.packets.swg.zone.SceneDestroyObject; import network.packets.swg.zone.UpdatePvpStatusMessage; import network.packets.swg.zone.chat.ChatOnConnectAvatar; import network.packets.swg.zone.chat.VoiceChatStatus; @@ -228,7 +229,41 @@ public class ObjectManager extends Manager { return obj; } } - + + public SWGObject destroyObject(long objectId) { + SWGObject object = objects.get(objectId); + + return (object != null ? destroyObject(object) : null); + } + + public SWGObject destroyObject(SWGObject object) { + + long objId = object.getObjectId(); + + List children = object.getChildren(); + synchronized (children) { + for (SWGObject child : children) { + destroyObject(child.getObjectId()); + } + } + + // Remove object from the parent + SWGObject parent = object.getParent(); + if (parent != null) { + if (parent instanceof CreatureObject) { + ((CreatureObject) parent).removeEquipment(object); + } + parent.removeChild(object); + } + + object.sendObservers(new SceneDestroyObject(objId)); + + // Finally, remove from the awareness tree + deleteObject(object.getObjectId()); + + return object; + } + public SWGObject createObject(String template) { return createObject(template, null); } diff --git a/src/services/player/LoginService.java b/src/services/player/LoginService.java index c5bcdcb24..f93034514 100644 --- a/src/services/player/LoginService.java +++ b/src/services/player/LoginService.java @@ -127,7 +127,7 @@ public class LoginService extends Service { } private void handleCharDeletion(GalacticIntent intent, Player player, DeleteCharacterRequest request) { - SWGObject obj = intent.getObjectManager().deleteObject(request.getPlayerId()); + SWGObject obj = intent.getObjectManager().destroyObject(request.getPlayerId()); if (obj != null && obj instanceof CreatureObject) System.out.println("[" + player.getUsername() + "] Delete Character: " + ((CreatureObject)obj).getName() + ". IP: " + request.getAddress() + ":" + request.getPort()); sendPacket(player, new DeleteCharacterResponse(deleteCharacter(request.getPlayerId())));