diff --git a/src/resources/client_info/ChunkReader.java b/src/resources/client_info/ChunkReader.java
new file mode 100644
index 00000000..e36ec06a
--- /dev/null
+++ b/src/resources/client_info/ChunkReader.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.client_info;
+
+/**
+ * @author Waverunner
+ */
+public interface ChunkReader {
+ void handleReadChunk(IffNode chunk);
+}
diff --git a/src/resources/client_info/IffNode.java b/src/resources/client_info/IffNode.java
index 83e66b4f..c32323f5 100644
--- a/src/resources/client_info/IffNode.java
+++ b/src/resources/client_info/IffNode.java
@@ -112,10 +112,18 @@ public class IffNode {
public String readString() {
initBuffer();
String string = ByteUtilities.nextString(bb);
- bb.get();
+ if (!string.isEmpty())
+ bb.get();
return string;
}
+ public void readChunk(ChunkReader reader) {
+ initBuffer();
+ while(bb.hasRemaining()) {
+ reader.handleReadChunk(this);
+ }
+ }
+
public byte[] getBytes() {
return isForm ? createForm() : createChunk();
}
@@ -174,7 +182,7 @@ public class IffNode {
return parent;
}
- public int readBuffer(ByteBuffer bb) {
+ public int populateFromBuffer(ByteBuffer bb) {
String nodeTag = getTag(bb);
if (!nodeTag.equals("FORM")) {
tag = nodeTag;
@@ -212,7 +220,7 @@ public class IffNode {
IffNode child = new IffNode();
child.parent = this;
- read += child.readBuffer(bb);
+ read += child.populateFromBuffer(bb);
addChild(child);
}
return 4 + size;
diff --git a/src/resources/client_info/SWGFile.java b/src/resources/client_info/SWGFile.java
index 02c9decf..fc86c14b 100644
--- a/src/resources/client_info/SWGFile.java
+++ b/src/resources/client_info/SWGFile.java
@@ -72,7 +72,7 @@ public class SWGFile {
master = new IffNode("", true);
currentForm = master;
- master.readBuffer(bb);
+ master.populateFromBuffer(bb);
type = master.getTag();
fileName = file.getAbsolutePath();
}
diff --git a/src/resources/client_info/visitors/ProfTemplateData.java b/src/resources/client_info/visitors/ProfTemplateData.java
index 171ad911..ed966abd 100644
--- a/src/resources/client_info/visitors/ProfTemplateData.java
+++ b/src/resources/client_info/visitors/ProfTemplateData.java
@@ -32,6 +32,8 @@ import java.util.ArrayList;
import java.util.List;
import resources.client_info.ClientData;
+import resources.client_info.IffNode;
+import resources.client_info.SWGFile;
import utilities.ByteUtilities;
public class ProfTemplateData extends ClientData {
@@ -57,19 +59,35 @@ public class ProfTemplateData extends ClientData {
}
}
- public void handleChunkData(String form, String node, ByteBuffer data) {
- switch(node) {
-
- case "NAME":
- templates.add(new Template(ByteUtilities.nextString(data)));
- break;
-
- case "ITEM":
- int index = templates.size() - 1;
- data.getInt(); // empty int it seems for all items
- templates.get(index).getItems().add(ByteUtilities.nextString(data));
- break;
-
+ @Override
+ public void readIff(SWGFile iff) {
+ iff.enterNextForm(); // Version
+
+ IffNode form;
+ while((form = iff.enterNextForm()) != null) {
+ if (!form.getTag().equals("PTMP")) {
+ iff.exitForm();
+ continue;
+ }
+
+ IffNode chunk;
+ while((chunk = iff.enterNextChunk()) != null) {
+ String tag = chunk.getTag();
+ switch(tag) {
+ case "NAME":
+ templates.add(new Template(chunk.readString()));
+ break;
+
+ case "ITEM":
+ int index = templates.size() - 1;
+ chunk.readInt(); // empty int it seems for all items
+ templates.get(index).getItems().add(chunk.readString());
+ break;
+
+ default: break;
+ }
+ }
+ iff.exitForm();
}
}
diff --git a/src/resources/client_info/visitors/SlotArrangementData.java b/src/resources/client_info/visitors/SlotArrangementData.java
index a31bbb7e..771470ab 100644
--- a/src/resources/client_info/visitors/SlotArrangementData.java
+++ b/src/resources/client_info/visitors/SlotArrangementData.java
@@ -32,16 +32,31 @@ import java.util.ArrayList;
import java.util.List;
import resources.client_info.ClientData;
+import resources.client_info.IffNode;
+import resources.client_info.SWGFile;
import utilities.ByteUtilities;
public class SlotArrangementData extends ClientData {
private List > occupiedSlots = new ArrayList<>();
- public void handleChunkData(String form, String chunk, ByteBuffer data) {
-
+ @Override
+ public void readIff(SWGFile iff) {
+ iff.enterNextForm(); // Version
+
ArrayList slots = new ArrayList<>();
-
+ IffNode chunk;
+ while((chunk = iff.enterNextChunk()) != null) {
+ slots.add(chunk.readString());
+ }
+
+ occupiedSlots.add(slots);
+ }
+
+ public void handleChunkData(String form, String chunk, ByteBuffer data) {
+
+ ArrayList slots = new ArrayList<>();
+
while(data.hasRemaining()) {
slots.add(ByteUtilities.nextString(data));
data.get();
@@ -49,7 +64,7 @@ public class SlotArrangementData extends ClientData {
occupiedSlots.add(slots);
}
-
+
public List > getArrangement() {
return occupiedSlots;
}
diff --git a/src/resources/client_info/visitors/SlotDefinitionData.java b/src/resources/client_info/visitors/SlotDefinitionData.java
index d5d6d5e1..dfc4666b 100644
--- a/src/resources/client_info/visitors/SlotDefinitionData.java
+++ b/src/resources/client_info/visitors/SlotDefinitionData.java
@@ -27,11 +27,11 @@
***********************************************************************************/
package resources.client_info.visitors;
-import java.nio.ByteBuffer;
import java.util.HashMap;
import resources.client_info.ClientData;
-import utilities.ByteUtilities;
+import resources.client_info.IffNode;
+import resources.client_info.SWGFile;
public class SlotDefinitionData extends ClientData {
@@ -47,33 +47,32 @@ public class SlotDefinitionData extends ClientData {
public int unk1;
}
- public void handleChunkData(String form, String node, ByteBuffer data) {
- while (data.hasRemaining()) {
+ @Override
+ public void readIff(SWGFile iff) {
+
+ IffNode data = iff.enterChunk("DATA");
+ data.readChunk((chunk) -> {
SlotDefinition def = new SlotDefinition();
- def.name = ByteUtilities.nextString(data);
- def.isGlobal = (data.get() == (byte) 1);
- def.isModdable = (data.get() == (byte) 1);
- def.isExclusive = (data.get() == (byte) 1);
- def.hasHardpoint = (data.get() == (byte) 1);
+ def.name = chunk.readString();
+ def.isGlobal = chunk.readBoolean();
+ def.isModdable = chunk.readBoolean();
+ def.isExclusive = chunk.readBoolean();
+ def.hasHardpoint = chunk.readBoolean();
if (def.hasHardpoint) {
- data.mark();
- if (data.get() != (byte) 0) {
- data.reset();
- def.hardpointName = ByteUtilities.nextString(data);
- data.get();
+ if (chunk.readByte() != 0) {
+ chunk.skip(-1);
+ def.hardpointName = chunk.readString();
}
} else {
- data.get();
+ chunk.readByte();
}
- def.unk1 = data.getInt(); // This seems to be a couple more booleans together, not sure what they would represent.
+ def.unk1 = chunk.readInt(); // This seems to be a couple more booleans together, not sure what they would represent.
definitions.put(def.name, def);
-
- //System.out.println("Added slot definition: " + def.name + (def.hardpointName != null ? " - Hardpoint name: " + def.hardpointName : ""));
- }
+ });
}
public SlotDefinition getDefinition(String name) {
diff --git a/src/resources/client_info/visitors/SlotDescriptorData.java b/src/resources/client_info/visitors/SlotDescriptorData.java
index f31f193b..d2be585a 100644
--- a/src/resources/client_info/visitors/SlotDescriptorData.java
+++ b/src/resources/client_info/visitors/SlotDescriptorData.java
@@ -32,21 +32,25 @@ import java.util.ArrayList;
import java.util.List;
import resources.client_info.ClientData;
+import resources.client_info.IffNode;
+import resources.client_info.SWGFile;
import utilities.ByteUtilities;
public class SlotDescriptorData extends ClientData {
private List slots = new ArrayList<>();
- public void handleChunkData(String form, String node, ByteBuffer data) {
- if (!form.equals("0000") && !node.equals("DATA"))
- return;
-
- while (data.hasRemaining()) {
- slots.add(ByteUtilities.nextString(data));
- data.get();
+ @Override
+ public void readIff(SWGFile iff) {
+ iff.enterNextForm(); // version
+
+ IffNode chunk = iff.enterChunk("DATA");
+
+ String slot;
+ while((slot = chunk.readString()) != null && !slot.isEmpty()) {
+ slots.add(slot);
}
-
+
}
public List getSlots() {
diff --git a/src/services/player/CharacterCreationService.java b/src/services/player/CharacterCreationService.java
index 8141bbeb..4f614392 100644
--- a/src/services/player/CharacterCreationService.java
+++ b/src/services/player/CharacterCreationService.java
@@ -312,6 +312,8 @@ public class CharacterCreationService extends Service {
for (String template : profTemplates.get(profession).getItems(ClientFactory.formatToSharedFile(race))) {
TangibleObject item = createTangible(objManager, template);
+ if (item == null)
+ return;
// Move the new item to the player's clothing slots and add to equipment list
item.moveToContainer(player, player);
player.addEquipment(item);