From 0fedef77a344aa448da41e867426ae530f63d4ff Mon Sep 17 00:00:00 2001 From: Obique PSWG Date: Fri, 25 Mar 2016 23:21:16 -0500 Subject: [PATCH] Fixed several object structures and drastically sped up object creation --- src/resources/SkillMod.java | 8 ++ .../client_info/visitors/ObjectData.java | 63 ++++++++++ .../encodables/player/Equipment.java | 96 +++++++-------- src/resources/network/NetBuffer.java | 36 +++--- src/resources/objects/SWGObject.java | 32 ++--- src/resources/objects/creature/Buff.java | 99 +++++++++++++++ .../objects/creature/CreatureObject.java | 18 +-- src/resources/objects/guild/GuildObject.java | 90 ++++++++++++-- .../installation/InstallationObject.java | 8 ++ .../ManufactureSchematicObject.java | 2 +- .../objects/mission/MissionObject.java | 116 ++++++++++++++++++ .../objects/tangible/TangibleObject.java | 8 +- .../objects/weapon/WeaponObject.java | 17 ++- src/services/objects/ObjectCreator.java | 72 +++++++++-- 14 files changed, 550 insertions(+), 115 deletions(-) create mode 100644 src/resources/objects/creature/Buff.java create mode 100644 src/resources/objects/mission/MissionObject.java diff --git a/src/resources/SkillMod.java b/src/resources/SkillMod.java index f9bf50920..c8f6fe01f 100644 --- a/src/resources/SkillMod.java +++ b/src/resources/SkillMod.java @@ -39,6 +39,10 @@ public class SkillMod implements Encodable, Serializable { private int base, modifier; + public SkillMod() { + this(0, 0); + } + public SkillMod(int base, int modifier) { this.base = base; this.modifier = modifier; @@ -71,5 +75,9 @@ public class SkillMod implements Encodable, Serializable { public int getValue() { return base + modifier; } + + public String toString() { + return "SkillMod[Base="+base+", Modifier="+modifier+"]"; + } } diff --git a/src/resources/client_info/visitors/ObjectData.java b/src/resources/client_info/visitors/ObjectData.java index d2fd053c9..713108899 100644 --- a/src/resources/client_info/visitors/ObjectData.java +++ b/src/resources/client_info/visitors/ObjectData.java @@ -192,25 +192,81 @@ public class ObjectData extends ClientData { System.err.println("Unknown attribute: " + str); return; } + parseObjectAttribute(chunk, attr); + parseBuildingAttribute(chunk, attr); + parseVehicleAttribute(chunk, attr); + parseWeaponAttribute(chunk, attr); + parseShipAttribute(chunk, attr); + } + + private void parseObjectAttribute(IffNode chunk, ObjectDataAttribute attr) { switch (attr) { case APPEARANCE_FILENAME: putString(chunk, attr); break; case ARRANGEMENT_DESCRIPTOR_FILENAME: putString(chunk,attr); break; + case CLEAR_FLORA_RADIUS: putFloat(chunk, attr); break; + case CLIENT_DATA_FILE: putString(chunk, attr); break; case CLIENT_VISIBILITY_FLAG: putBoolean(chunk, attr); break; case CONTAINER_TYPE: putInt(chunk, attr); break; case CONTAINER_VOLUME_LIMIT: putInt(chunk, attr);break; case DETAILED_DESCRIPTION: putStfString(chunk, attr); break; case FORCE_NO_COLLISION: putBoolean(chunk, attr); break; + case GAME_OBJECT_TYPE: putInt(chunk, attr); break; case GENDER: putInt(chunk, attr); break; + case LOCATION_RESERVATION_RADIUS: putFloat(chunk, attr); break; + case LOOK_AT_TEXT: putString(chunk, attr); break; + case NO_BUILD_RADIUS: putFloat(chunk, attr); break; case OBJECT_NAME: putStfString(chunk, attr); break; + case ONLY_VISIBLE_IN_TOOLS: putBoolean(chunk, attr); break; case PORTAL_LAYOUT_FILENAME: putString(chunk, attr); break; + case SCALE: putFloat(chunk, attr); break; + case SCALE_THRESHOLD_BEFORE_EXTENT_TEST: putFloat(chunk, attr); break; + case SEND_TO_CLIENT: putBoolean(chunk, attr); break; case SLOT_DESCRIPTOR_FILENAME: putString(chunk, attr); break; + case SNAP_TO_TERRAIN: putBoolean(chunk, attr); break; case STRUCTURE_FOOTPRINT_FILENAME: putString(chunk, attr); break; + case SURFACE_TYPE: putInt(chunk, attr); break; case TARGETABLE: putBoolean(chunk, attr); break; + case TINT_PALETTE: putString(chunk, attr); break; case USE_STRUCTURE_FOOTPRINT_OUTLINE: putBoolean(chunk, attr); break; default: break; } } + private void parseBuildingAttribute(IffNode chunk, ObjectDataAttribute attr) { + switch (attr) { + case INTERIOR_LAYOUT_FILENAME: putString(chunk, attr); break; + case TERRAIN_MODIFICATION_FILENAME: putString(chunk, attr); break; + default: break; + } + } + + private void parseWeaponAttribute(IffNode chunk, ObjectDataAttribute attr) { + switch (attr) { + case WEAPON_EFFECT: putString(chunk, attr); break; + case WEAPON_EFFECT_INDEX: putInt(chunk, attr); break; + case ATTACK_TYPE: putInt(chunk, attr); break; + default: break; + } + } + + private void parseVehicleAttribute(IffNode chunk, ObjectDataAttribute attr) { + switch (attr) { + case SPEED: putFloat(chunk, attr); break; + case TURN_RADIUS: putFloat(chunk, attr); break; + case ACCELERATION: putFloat(chunk, attr); break; + default: break; + } + } + + private void parseShipAttribute(IffNode chunk, ObjectDataAttribute attr) { + switch (attr) { + case COCKPIT_FILENAME: putString(chunk, attr); break; + case HAS_WINGS: putBoolean(chunk, attr); break; + case PLAYER_CONTROLLED: putBoolean(chunk, attr); break; + default: break; + } + } + private void putStfString(IffNode chunk, ObjectDataAttribute attr) { if (chunk.readByte() == 0) return; @@ -243,6 +299,13 @@ public class ObjectData extends ClientData { attributes.put(attr, chunk.readInt()); } + private void putFloat(IffNode chunk, ObjectDataAttribute attr) { + if (chunk.readByte() == 0) + return; // This should always be 1 if there is an int (note that 0x20 follows after this even if it's 0) + chunk.readByte(); // 0x20 byte for all it seems, unsure what it means + attributes.put(attr, chunk.readFloat()); + } + private void putBoolean(IffNode chunk, ObjectDataAttribute attr) { attributes.put(attr, (chunk.readByte() == 1)); } diff --git a/src/resources/encodables/player/Equipment.java b/src/resources/encodables/player/Equipment.java index 941f01fc3..62a728436 100644 --- a/src/resources/encodables/player/Equipment.java +++ b/src/resources/encodables/player/Equipment.java @@ -27,26 +27,27 @@ ***********************************************************************************/ package resources.encodables.player; -import network.packets.Packet; import network.packets.swg.zone.baselines.Baseline; import resources.common.CRC; import resources.encodables.Encodable; +import resources.network.NetBuffer; import resources.objects.SWGObject; +import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import resources.player.Player; +import services.objects.ObjectCreator; import java.io.Serializable; import java.nio.ByteBuffer; -import java.nio.ByteOrder; public class Equipment implements Encodable, Serializable { private static final long serialVersionUID = 1L; - private WeaponObject weapon; - private byte[] customizationString; - private int arrangementId = 4; - private long objectId; - private String template; + private TangibleObject weapon; + private byte [] customizationString; + private int arrangementId; + private long objectId; + private CRC template; public Equipment() { this(0, null); @@ -54,7 +55,11 @@ public class Equipment implements Encodable, Serializable { public Equipment(long objectId, String template) { this.objectId = objectId; - this.template = template; + this.template = new CRC(template); + this.customizationString = new byte[0]; + this.arrangementId = 4; + this.objectId = 0; + this.weapon = null; } public Equipment(WeaponObject weapon) { @@ -63,45 +68,31 @@ public class Equipment implements Encodable, Serializable { } @Override - public byte[] encode() { - ByteBuffer buffer; - byte[] weaponData = null; - - if (weapon != null) { + public byte [] encode() { + byte [] weaponData = new byte[0]; + if (weapon != null) weaponData = getWeaponData(); - - buffer = ByteBuffer.allocate(19 + weaponData.length).order(ByteOrder.LITTLE_ENDIAN); - } else { - buffer = ByteBuffer.allocate(19).order(ByteOrder.LITTLE_ENDIAN); - } - - if (customizationString == null) buffer.putShort((short) 0); // TODO: Create encodable class for customization string - else buffer.put(customizationString); - buffer.putInt(arrangementId); - buffer.putLong(objectId); - buffer.putInt(CRC.getCrc(template)); + NetBuffer buffer = NetBuffer.allocate(19 + weaponData.length); - if (weapon != null) { - buffer.put((byte) 0x01); - buffer.put(weaponData); - } else { - buffer.put((byte) 0x00); - } + buffer.addArray(customizationString); // TODO: Create encodable class for customization string + buffer.addInt(arrangementId); + buffer.addLong(objectId); + buffer.addEncodable(template); + buffer.addBoolean(weapon != null); + buffer.addRawArray(weaponData); return buffer.array(); } @Override - public void decode(ByteBuffer data) { - customizationString = Packet.getArray(data); // TODO: Create encodable class for customization string - arrangementId = Packet.getInt(data); - objectId = Packet.getLong(data); - /*template =*/Packet.getInt(data); - - // TODO: Re-do when weapon encode for Equipment is fixed - boolean weapon = Packet.getBoolean(data); - if (weapon) + public void decode(ByteBuffer bb) { + NetBuffer data = NetBuffer.wrap(bb); + customizationString = data.getArray(); // TODO: Create encodable class for customization string + arrangementId = data.getInt(); + objectId = data.getLong(); + template = data.getEncodable(CRC.class); + if (data.getBoolean()) this.weapon = createWeaponFromData(data); } @@ -114,8 +105,8 @@ public class Equipment implements Encodable, Serializable { public long getObjectId() { return objectId; } public void setObjectId(long objectId) { this.objectId = objectId; } - public String getTemplate() { return template; } - public void setTemplate(String template) { this.template = template; } + public String getTemplate() { return template.getString(); } + public void setTemplate(String template) { this.template = new CRC(template); } private byte[] getWeaponData() { Player target = weapon.getOwner(); @@ -131,23 +122,26 @@ public class Equipment implements Encodable, Serializable { return ret.array(); } - private WeaponObject createWeaponFromData(ByteBuffer data) { - ByteBuffer tmp = ByteBuffer.allocate(data.remaining()); - int pos = data.position(); - tmp.get(data.array(), pos, data.array().length - pos); + private TangibleObject createWeaponFromData(NetBuffer data) { + SWGObject weapon = ObjectCreator.createObjectFromTemplate(objectId, template.getString()); + Baseline b3 = new Baseline(); - b3.decode(tmp); - pos += tmp.position(); - tmp.position(0); - tmp.get(data.array(), pos, data.array().length - pos); + b3.decode(data.getBuffer()); Baseline b6 = new Baseline(); - b6.decode(tmp); - data.position(tmp.position()+pos); + b6.decode(data.getBuffer()); + + weapon.parseBaseline(b3); + weapon.parseBaseline(b6); + if (weapon instanceof TangibleObject) + return (TangibleObject) weapon; + System.err.println("Unknown Equipment Type: " + weapon.getClass().getSimpleName()); return null; } @Override public String toString() { + if (weapon != null) + return "Equipment: " + weapon; return "Equipment: " + template; } diff --git a/src/resources/network/NetBuffer.java b/src/resources/network/NetBuffer.java index ccd3e30aa..2b1e61de0 100644 --- a/src/resources/network/NetBuffer.java +++ b/src/resources/network/NetBuffer.java @@ -49,6 +49,14 @@ public class NetBuffer { data.position(position); } + public void seek(int relative) { + data.position(data.position()+relative); + } + + public ByteBuffer getBuffer() { + return data; + } + public void addBoolean(boolean b) { data.put(b ? (byte)1 : (byte)0); } @@ -111,6 +119,14 @@ public class NetBuffer { data.put(b); } + public void addRawArray(byte [] b) { + data.put(b); + } + + public void addEncodable(Encodable e) { + data.put(e.encode()); + } + public boolean getBoolean() { return getByte() == 1 ? true : false; } @@ -246,32 +262,20 @@ public class NetBuffer { } public SWGMap getSwgMap(int num, int var, StringType key, StringType val) { - return getSwgMap(num, var, key, val, false); - } - - public SWGMap getSwgMap(int num, int var, StringType key, StringType val, boolean addByte) { SWGMap map = new SWGMap<>(num, var); - map.decode(data, key, val, addByte); + map.decode(data, key, val, true); return map; } public SWGMap getSwgMap(int num, int var, StringType key, Class val) { - return getSwgMap(num, var, key, val, false); - } - - public SWGMap getSwgMap(int num, int var, StringType key, Class val, boolean addByte) { SWGMap map = new SWGMap<>(num, var); - map.decode(data, key, val, addByte); + map.decode(data, key, val, true); return map; } public SWGMap getSwgMap(int num, int var, Class key, Class val) { - return getSwgMap(num, var, key, val, false); - } - - public SWGMap getSwgMap(int num, int var, Class key, Class val, boolean addByte) { SWGMap map = new SWGMap<>(num, var); - map.decode(data, key, val, addByte); + map.decode(data, key, val, true); return map; } @@ -293,7 +297,7 @@ public class NetBuffer { if (offset+length > size) throw new IllegalArgumentException("Length extends past the end of the array!"); byte [] ret = new byte[length]; - System.arraycopy(array(), 0, ret, offset, length); + System.arraycopy(array(), offset, ret, 0, length); return ret; } diff --git a/src/resources/objects/SWGObject.java b/src/resources/objects/SWGObject.java index 51bf32193..903a968fd 100644 --- a/src/resources/objects/SWGObject.java +++ b/src/resources/objects/SWGObject.java @@ -85,6 +85,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable> arrangement; private ObjectClassification classification = ObjectClassification.GENERATED; + private GameObjectType gameObjectType = GameObjectType.GOT_NONE; private SWGObject parent = null; private StringId stringId = new StringId("", ""); private StringId detailStringId = new StringId("", ""); @@ -524,6 +525,8 @@ public abstract class SWGObject extends BaselineObject implements Comparable missionCriticalObjs = new SWGSet<>(4, 13); + private SWGList baseAttributes = new SWGList(1, 2); private SWGList skills = new SWGList(1, 3, StringType.ASCII); // SWGSet private SWGList hamEncumbList = new SWGList(4, 2); @@ -116,9 +120,8 @@ public class CreatureObject extends TangibleObject { private SWGList appearanceList = new SWGList(6, 33); private SWGMap skillMods = new SWGMap<>(4, 3, StringType.ASCII); // TODO: SkillMod structure - private SWGMap missionCriticalObjs = new SWGMap<>(4, 13); - private SWGMap abilities = new SWGMap<>(4, 14, StringType.ASCII); - private SWGMap buffs = new SWGMap<>(6, 26); // TODO: Buff structure + private SWGMap abilities = new SWGMap<>(4, 14, StringType.ASCII); + private SWGMap buffs = new SWGMap<>(6, 26); public CreatureObject(long objectId) { super(objectId, BaselineType.CREO); @@ -710,7 +713,7 @@ public class CreatureObject extends TangibleObject { return attributes.get(2); } - public void addAbility(String abilityName){ abilities.put(abilityName, 1L); }//TODO: Figure out what the integer value should be for each ability + public void addAbility(String abilityName){ abilities.put(abilityName, 1); }//TODO: Figure out what the integer value should be for each ability public void removeAbility(String abilityName) { abilities.remove(abilityName); } @@ -950,6 +953,7 @@ public class CreatureObject extends TangibleObject { if (getStringId().toString().equals("@obj_n:unknown_object")) return; accelPercent = buffer.getFloat(); + accelScale = buffer.getFloat(); hamEncumbList = buffer.getSwgList(4, 2, Integer.class); skillMods = buffer.getSwgMap(4, 3, StringType.ASCII, SkillMod.class); movementPercent = buffer.getFloat(); @@ -961,8 +965,8 @@ public class CreatureObject extends TangibleObject { turnScale = buffer.getFloat(); walkSpeed = buffer.getFloat(); waterModPercent = buffer.getFloat(); - missionCriticalObjs = buffer.getSwgMap(4, 13, Long.class, Long.class); - abilities = buffer.getSwgMap(4, 14, StringType.ASCII, Long.class); + missionCriticalObjs = buffer.getSwgSet(4, 13, StringType.ASCII); + abilities = buffer.getSwgMap(4, 14, StringType.ASCII, Integer.class); totalLevelXp = buffer.getInt(); } @@ -988,7 +992,7 @@ public class CreatureObject extends TangibleObject { equipmentList = buffer.getSwgList(6, 23, Equipment.class); costume = buffer.getAscii(); visible = buffer.getBoolean(); - buffs = buffer.getSwgMap(6, 26, Integer.class, Integer.class); + buffs = buffer.getSwgMap(6, 26, CRC.class, Buff.class); performing = buffer.getBoolean(); difficulty = CreatureDifficulty.getForDifficulty(buffer.getByte()); hologramColour = HologramColour.getForValue(buffer.getInt()); diff --git a/src/resources/objects/guild/GuildObject.java b/src/resources/objects/guild/GuildObject.java index 129bcb737..1b23027da 100644 --- a/src/resources/objects/guild/GuildObject.java +++ b/src/resources/objects/guild/GuildObject.java @@ -1,8 +1,11 @@ package resources.objects.guild; +import java.nio.ByteBuffer; + import network.packets.swg.zone.baselines.Baseline.BaselineType; import resources.collections.SWGMap; import resources.collections.SWGSet; +import resources.encodables.Encodable; import resources.network.BaselineBuilder; import resources.network.NetBuffer; import resources.objects.SWGObject; @@ -14,10 +17,12 @@ public class GuildObject extends SWGObject { private static final long serialVersionUID = 1L; private SWGSet abbreviations = new SWGSet(3, 4, StringType.ASCII); - private SWGMap gcwImperialScorePercentileThisGalaxy = new SWGMap<>(6, 2); - private SWGMap gcwGroupImperialScorePercentileThisGalaxy = new SWGMap<>(6, 3); - private SWGMap gcwImperialScorePercentileHistoryThisGalaxy = new SWGMap<>(6, 4); - private SWGMap gcwGroupImperialScorePercentileHistoryThisGalaxy = new SWGMap<>(6, 5); + private SWGMap gcwImperialScorePercentileThisGalaxy = new SWGMap<>(6, 2); + private SWGMap gcwGroupImperialScorePercentileThisGalaxy = new SWGMap<>(6, 3); + private SWGMap gcwImperialScorePercentileHistoryThisGalaxy = new SWGMap<>(6, 4); + private SWGMap gcwGroupImperialScorePercentileHistoryThisGalaxy = new SWGMap<>(6, 5); + private SWGMap gcwImperialScorePercentileOtherGalaxies = new SWGMap<>(6, 6); + private SWGMap gcwGroupImperialScorePercentileOtherGalaxies = new SWGMap<>(6, 7); public GuildObject(long objectId) { super(objectId, BaselineType.GILD); @@ -36,6 +41,8 @@ public class GuildObject extends SWGObject { bb.addObject(gcwGroupImperialScorePercentileThisGalaxy); bb.addObject(gcwImperialScorePercentileHistoryThisGalaxy); bb.addObject(gcwGroupImperialScorePercentileHistoryThisGalaxy); + bb.addObject(gcwImperialScorePercentileOtherGalaxies); + bb.addObject(gcwGroupImperialScorePercentileOtherGalaxies); } @Override @@ -47,10 +54,77 @@ public class GuildObject extends SWGObject { @Override protected void parseBaseline6(NetBuffer buffer) { super.parseBaseline6(buffer); - gcwImperialScorePercentileThisGalaxy = buffer.getSwgMap(6, 2, StringType.ASCII, Integer.class, true); - gcwGroupImperialScorePercentileThisGalaxy = buffer.getSwgMap(6, 3, StringType.ASCII, Integer.class, true); - gcwImperialScorePercentileHistoryThisGalaxy = buffer.getSwgMap(6, 4, StringType.ASCII, Long.class, true); - gcwGroupImperialScorePercentileHistoryThisGalaxy = buffer.getSwgMap(6, 5, StringType.ASCII, Long.class, true); + gcwImperialScorePercentileThisGalaxy = buffer.getSwgMap(6, 2, StringType.ASCII, CurrentServerGCWZonePercent.class); + gcwGroupImperialScorePercentileThisGalaxy = buffer.getSwgMap(6, 3, StringType.ASCII, CurrentServerGCWZonePercent.class); + gcwImperialScorePercentileHistoryThisGalaxy = buffer.getSwgMap(6, 4, StringType.ASCII, CurrentServerGCWZoneHistory.class); + gcwGroupImperialScorePercentileHistoryThisGalaxy = buffer.getSwgMap(6, 5, StringType.ASCII, CurrentServerGCWZoneHistory.class); + gcwImperialScorePercentileOtherGalaxies = buffer.getSwgMap(6, 6, StringType.ASCII, OtherServerGCWZonePercent.class); + gcwGroupImperialScorePercentileOtherGalaxies = buffer.getSwgMap(6, 7, StringType.ASCII, OtherServerGCWZonePercent.class); + } + + public static class CurrentServerGCWZonePercent implements Encodable { + + private int percentage = 0; + + public byte [] encode() { + NetBuffer data = NetBuffer.allocate(4); + data.addInt(percentage); + return data.array(); + } + + public void decode(ByteBuffer data) { + percentage = data.getInt(); + } + + public String toString() { + return percentage + "%"; + } + } + + public static class CurrentServerGCWZoneHistory implements Encodable { + + private int lastUpdateTime = 0; + private int percentage = 0; + + public byte [] encode() { + NetBuffer data = NetBuffer.allocate(8); + data.addInt(lastUpdateTime); + data.addInt(percentage); + return data.array(); + } + + public void decode(ByteBuffer bb) { + NetBuffer data = NetBuffer.wrap(bb); + lastUpdateTime = data.getInt(); + percentage = data.getInt(); + } + + public String toString() { + return lastUpdateTime + ":" + percentage + "%"; + } + } + + public static class OtherServerGCWZonePercent implements Encodable { + + private String zone = ""; + private int percentage = 0; + + public byte [] encode() { + NetBuffer data = NetBuffer.allocate(6 + zone.length()); + data.addAscii(zone); + data.addInt(percentage); + return data.array(); + } + + public void decode(ByteBuffer bb) { + NetBuffer data = NetBuffer.wrap(bb); + zone = data.getAscii(); + percentage = data.getInt(); + } + + public String toString() { + return zone + ":" + percentage + "%"; + } } } diff --git a/src/resources/objects/installation/InstallationObject.java b/src/resources/objects/installation/InstallationObject.java index b336e4495..3a2589b7d 100644 --- a/src/resources/objects/installation/InstallationObject.java +++ b/src/resources/objects/installation/InstallationObject.java @@ -29,6 +29,7 @@ package resources.objects.installation; import network.packets.swg.zone.baselines.Baseline.BaselineType; import resources.network.BaselineBuilder; +import resources.network.NetBuffer; import resources.objects.tangible.TangibleObject; import resources.player.Player; @@ -78,6 +79,13 @@ public class InstallationObject extends TangibleObject { bb.incrementOperandCount(3); } + public void parseBaseline3(NetBuffer data) { + super.parseBaseline3(data); + activated = data.getBoolean(); + power = data.getFloat(); + powerRate = data.getFloat(); + } + @Override public boolean equals(Object o) { if (!(o instanceof InstallationObject)) diff --git a/src/resources/objects/manufacture/ManufactureSchematicObject.java b/src/resources/objects/manufacture/ManufactureSchematicObject.java index 6157eecf6..7cce47635 100644 --- a/src/resources/objects/manufacture/ManufactureSchematicObject.java +++ b/src/resources/objects/manufacture/ManufactureSchematicObject.java @@ -114,7 +114,7 @@ public class ManufactureSchematicObject extends IntangibleObject { @Override public void parseBaseline3(NetBuffer buffer) { super.parseBaseline3(buffer); - attributes = buffer.getSwgMap(3, 5, StringId.class, Float.class, true); + attributes = buffer.getSwgMap(3, 5, StringId.class, Float.class); itemsPerContainer = buffer.getInt(); manufactureTime = buffer.getFloat(); } diff --git a/src/resources/objects/mission/MissionObject.java b/src/resources/objects/mission/MissionObject.java new file mode 100644 index 000000000..eb3b3a66c --- /dev/null +++ b/src/resources/objects/mission/MissionObject.java @@ -0,0 +1,116 @@ +package resources.objects.mission; + +import java.nio.ByteBuffer; + +import network.packets.swg.zone.baselines.Baseline.BaselineType; +import resources.Point3D; +import resources.Terrain; +import resources.common.CRC; +import resources.encodables.Encodable; +import resources.encodables.StringId; +import resources.network.BaselineBuilder; +import resources.network.NetBuffer; +import resources.objects.intangible.IntangibleObject; +import resources.objects.waypoint.WaypointObject; +import resources.player.Player; + +public class MissionObject extends IntangibleObject { + + private static final long serialVersionUID = 1L; + + private int difficulty = 0; + private MissionLocation location = new MissionLocation(); + private String missionCreator = ""; + private int reward = 0; + private MissionLocation startLocation = new MissionLocation(); + private CRC targetAppearance = new CRC(); + private StringId description = new StringId(); + private StringId title = new StringId(); + private int status = 0; + private CRC missionType = new CRC(); + private String targetName = ""; + private WaypointObject waypoint = new WaypointObject(0); + + public MissionObject(long objectId) { + super(objectId, BaselineType.MISO); + } + + public void createBaseline3(Player target, BaselineBuilder bb) { + super.createBaseline3(target, bb); + bb.addInt(difficulty); + bb.addObject(location); + bb.addUnicode(missionCreator); + bb.addInt(reward); + bb.addObject(startLocation); + bb.addObject(targetAppearance); + bb.addObject(description); + bb.addObject(title); + bb.addInt(status); + bb.addObject(missionType); + bb.addAscii(targetName); + bb.addObject(waypoint); + } + + public void createBaseline6(Player target, BaselineBuilder bb) { + super.createBaseline6(target, bb); + bb.addInt(-1); + } + + public void parseBaseline3(NetBuffer buffer) { + super.parseBaseline3(buffer); + difficulty = buffer.getInt(); + location = buffer.getEncodable(MissionLocation.class); + missionCreator = buffer.getUnicode(); + reward = buffer.getInt(); + startLocation = buffer.getEncodable(MissionLocation.class); + targetAppearance = buffer.getEncodable(CRC.class); + description = buffer.getEncodable(StringId.class); + title = buffer.getEncodable(StringId.class); + status = buffer.getInt(); + missionType = buffer.getEncodable(CRC.class); + targetName = buffer.getAscii(); + int pos = buffer.position(); + buffer.seek(24); + buffer.getUnicode(); + waypoint = new WaypointObject(buffer.getLong()); + buffer.position(pos); + waypoint.decode(buffer.getBuffer()); + } + + public void parseBaseline6(NetBuffer buffer) { + super.parseBaseline6(buffer); + buffer.getInt(); + } + + public static class MissionLocation implements Encodable { + + private Point3D location; + private long objectId; + private Terrain terrain; + + public MissionLocation() { + location = new Point3D(); + objectId = 0; + terrain = Terrain.TATOOINE; + } + + @Override + public byte[] encode() { + NetBuffer data = NetBuffer.allocate(24); + data.addEncodable(location); + data.addLong(objectId); + data.addInt(terrain.getCrc()); + return data.array(); + } + + @Override + public void decode(ByteBuffer bb) { + NetBuffer data = NetBuffer.wrap(bb); + location = data.getEncodable(Point3D.class); + objectId = data.getLong(); + terrain = Terrain.getTerrainFromCrc(data.getInt()); + } + + } + +} diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java index 07fcb96dd..b4020034e 100644 --- a/src/resources/objects/tangible/TangibleObject.java +++ b/src/resources/objects/tangible/TangibleObject.java @@ -273,7 +273,7 @@ public class TangibleObject extends SWGObject { pvpFaction = PvpFaction.getFactionForCrc(buffer.getInt()); pvpStatus = PvpStatus.getStatusForValue(buffer.getInt()); appearanceData = buffer.getArray(); - buffer.getSwgSet(3, 7, Integer.TYPE); + buffer.getSwgSet(3, 7, Integer.class); optionFlags = buffer.getInt(); buffer.getInt(); condition = buffer.getInt(); @@ -288,9 +288,9 @@ public class TangibleObject extends SWGObject { inCombat = buffer.getBoolean(); buffer.getSwgSet(6, 3, Long.TYPE); buffer.getInt(); - buffer.getSwgSet(6, 5, StringType.ASCII.getClass()); - buffer.getSwgSet(6, 6, StringType.ASCII.getClass()); - buffer.getSwgMap(6, 7, StringType.ASCII.getClass(), StringType.ASCII.getClass()); + buffer.getSwgSet(6, 5, StringType.ASCII); + buffer.getSwgSet(6, 6, StringType.ASCII); + buffer.getSwgMap(6, 7, StringType.ASCII, StringType.ASCII); } @Override diff --git a/src/resources/objects/weapon/WeaponObject.java b/src/resources/objects/weapon/WeaponObject.java index 20dedd923..c131d497a 100644 --- a/src/resources/objects/weapon/WeaponObject.java +++ b/src/resources/objects/weapon/WeaponObject.java @@ -29,6 +29,7 @@ package resources.objects.weapon; import network.packets.swg.zone.baselines.Baseline.BaselineType; import resources.network.BaselineBuilder; +import resources.network.NetBuffer; import resources.objects.tangible.TangibleObject; import resources.player.Player; @@ -107,12 +108,20 @@ public class WeaponObject extends TangibleObject { bb.incrementOperandCount(1); } - public void createBaseline8(Player target, BaselineBuilder bb) { - super.createBaseline8(target, bb); + public void parseBaseline3(NetBuffer buffer) { + super.parseBaseline3(buffer); + attackSpeed = buffer.getFloat(); + buffer.getInt(); // accuracy + buffer.getFloat(); // minRange + maxRange = buffer.getFloat(); + buffer.getInt(); // damageType + buffer.getInt(); // elementalType + buffer.getInt(); // elementalValue } - public void createBaseline9(Player target, BaselineBuilder bb) { - super.createBaseline9(target, bb); + public void parseBaseline6(NetBuffer buffer) { + super.parseBaseline6(buffer); + type = buffer.getInt(); } } diff --git a/src/services/objects/ObjectCreator.java b/src/services/objects/ObjectCreator.java index db914cf14..5f079e144 100644 --- a/src/services/objects/ObjectCreator.java +++ b/src/services/objects/ObjectCreator.java @@ -35,6 +35,8 @@ import resources.client_info.visitors.ObjectData; import resources.client_info.visitors.ObjectData.ObjectDataAttribute; import resources.client_info.visitors.SlotArrangementData; import resources.client_info.visitors.SlotDescriptorData; +import resources.objects.GameObjectType; +import resources.objects.GameObjectTypeMask; import resources.objects.SWGObject; import resources.objects.building.BuildingObject; import resources.objects.cell.CellObject; @@ -45,6 +47,7 @@ import resources.objects.guild.GuildObject; import resources.objects.installation.InstallationObject; import resources.objects.intangible.IntangibleObject; import resources.objects.manufacture.ManufactureSchematicObject; +import resources.objects.mission.MissionObject; import resources.objects.player.PlayerObject; import resources.objects.resource.ResourceContainerObject; import resources.objects.ship.ShipObject; @@ -71,12 +74,14 @@ public final class ObjectCreator { return null; if (!template.endsWith(".iff")) return null; - SWGObject obj = createObjectFromType(objectId, getTemplatePart(template, 1)); + ObjectData attributes = (ObjectData) ClientFactory.getInfoFromFile(ClientFactory.formatToSharedFile(template), true); + GameObjectType type = GameObjectType.getTypeFromId((Integer) attributes.getAttribute(ObjectDataAttribute.GAME_OBJECT_TYPE)); + SWGObject obj = createObjectFromType(objectId, template, type); if (obj == null) return null; obj.setTemplate(template); - handlePostCreation(obj); + handlePostCreation(obj, attributes); updateMaxObjectId(objectId); return obj; } @@ -93,7 +98,8 @@ public final class ObjectCreator { return null; obj.setTemplate(template); - handlePostCreation(obj); + ObjectData attributes = (ObjectData) ClientFactory.getInfoFromFile(ClientFactory.formatToSharedFile(template), true); + handlePostCreation(obj, attributes); updateMaxObjectId(objectId); return obj; } @@ -114,7 +120,53 @@ public final class ObjectCreator { return createObjectFromTemplate(id, template, c); } - private static SWGObject createObjectFromType(long objectId, String type) { + private static SWGObject createObjectFromType(long objectId, String template, GameObjectType got) { + SWGObject obj; + obj = createFastFromMask(objectId, got.getMask()); + if (obj != null) + return obj; + obj = createFastFromType(objectId, got); + if (obj != null) + return obj; + return createSlowFromType(objectId, getTemplatePart(template, 1)); + } + + private static SWGObject createFastFromType(long objectId, GameObjectType type) { + switch (type) { + case GOT_DATA_MANUFACTURING_SCHEMATIC: return new ManufactureSchematicObject(objectId); + case GOT_MISC_ITEM: + case GOT_MISC_SIGN: + case GOT_MISC_CONTAINER: + case GOT_MISC_CONTAINER_PUBLIC: + case GOT_MISC_CONTAINER_SHIP_LOOT: + case GOT_MISC_CONTAINER_WEARABLE: return new TangibleObject(objectId); + default: return null; + } + } + + private static SWGObject createFastFromMask(long objectId, GameObjectTypeMask mask) { + switch (mask) { + case GOTM_BUILDING: return new BuildingObject(objectId); + case GOTM_INSTALLATION: return new InstallationObject(objectId); + case GOTM_RESOURCE_CONTAINER: return new ResourceContainerObject(objectId); + case GOTM_SHIP: return new ShipObject(objectId); + case GOTM_WEAPON: return new WeaponObject(objectId); + case GOTM_ARMOR: + case GOTM_CLOTHING: + case GOTM_COMPONENT: + case GOTM_SHIP_COMPONENT: + case GOTM_TOOL: + case GOTM_JEWELRY: + case GOTM_CHRONICLES: + case GOTM_CYBERNETIC: + case GOTM_TERMINAL: + case GOTM_POWERUP_WEAPON: + case GOTM_VEHICLE: return new TangibleObject(objectId); + default: return null; + } + } + + private static SWGObject createSlowFromType(long objectId, String type) { switch (type) { case "building": return new BuildingObject(objectId); case "cell": return new CellObject(objectId); @@ -125,6 +177,7 @@ public final class ObjectCreator { case "installation": return new InstallationObject(objectId); case "intangible": return new IntangibleObject(objectId); case "manufacture_schematic": return new ManufactureSchematicObject(objectId); + case "mission": return new MissionObject(objectId); case "mobile": return new CreatureObject(objectId); case "player": return new PlayerObject(objectId); case "resource_container": return new ResourceContainerObject(objectId); @@ -137,15 +190,14 @@ public final class ObjectCreator { default: System.err.println("Unknown type: " + type); return null; } } - - private static void handlePostCreation(SWGObject object) { - addObjectAttributes(object, object.getTemplate()); + + private static void handlePostCreation(SWGObject object, ObjectData attributes) { + addObjectAttributes(object, attributes); createObjectSlots(object); + object.setGameObjectType(GameObjectType.getTypeFromId((Integer) object.getDataAttribute(ObjectDataAttribute.GAME_OBJECT_TYPE))); } - private static void addObjectAttributes(SWGObject obj, String template) { - ObjectData attributes = (ObjectData) ClientFactory.getInfoFromFile(ClientFactory.formatToSharedFile(template), true); - + private static void addObjectAttributes(SWGObject obj, ObjectData attributes) { if (attributes == null) return;