mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-07-31 15:09:21 +07:00
Added boolean parameter to read/write StatList functions
entry.Saved was not appropriate for determining this feature Implemented prop list flags into StatListWriterTest tests Added additional logging to help with organizing encoded stats
This commit is contained in:
@ -9,11 +9,11 @@ import com.riiablo.logger.MDC;
|
||||
public class StatListReader {
|
||||
private static final Logger log = LogManager.getLogger(StatListReader.class);
|
||||
|
||||
public StatGetter read(StatListBuilder stats, short stat, BitInput bits) {
|
||||
public StatGetter read(StatListBuilder stats, short stat, BitInput bits, boolean cs) {
|
||||
log.traceEntry("read(stats: {}, stat: {}, bits: {})", stats, stat, bits);
|
||||
final ItemStatCost.Entry entry = Stat.entry(stat);
|
||||
final int param, value;
|
||||
if (entry.Saved) {
|
||||
if (cs) {
|
||||
log.trace("Reading character save stat...");
|
||||
assert !entry.CSvSigned : "entry.CSvSigned(" + entry.CSvSigned + ") unsupported";
|
||||
param = (int) bits.read63u(entry.CSvParam);
|
||||
@ -26,18 +26,23 @@ public class StatListReader {
|
||||
return stats.put(stat, param, value).last();
|
||||
}
|
||||
|
||||
public StatListGetter read(StatListBuilder stats, BitInput bits) {
|
||||
public StatListGetter read(StatListBuilder stats, BitInput bits, boolean cs) {
|
||||
log.traceEntry("read(stats: {}, bits: {})", stats, bits);
|
||||
for (short stat; (stat = bits.read15u(Stat.BITS)) != Stat.NONE;) {
|
||||
try {
|
||||
MDC.put("stat", stat);
|
||||
final byte numEncoded = Stat.getNumEncoded(stat);
|
||||
try {
|
||||
if (numEncoded > 1) MDC.put("numEncoded", numEncoded);
|
||||
if (numEncoded > 1) {
|
||||
MDC.put("numEncoded", numEncoded);
|
||||
MDC.put("encodedStat", stat);
|
||||
}
|
||||
for (short j = stat, s = (short) (stat + numEncoded); j < s; j++) {
|
||||
read(stats, j, bits);
|
||||
if (j > stat) MDC.put("encodedStat", j);
|
||||
read(stats, j, bits, cs);
|
||||
}
|
||||
} finally {
|
||||
MDC.remove("encodedStat");
|
||||
MDC.remove("numEncoded");
|
||||
}
|
||||
} finally {
|
||||
@ -51,10 +56,10 @@ public class StatListReader {
|
||||
/**
|
||||
* Reads a single property list into {@link Attributes#base()}
|
||||
*/
|
||||
public StatListGetter read(Attributes attrs, BitInput bits) {
|
||||
public StatListGetter read(Attributes attrs, BitInput bits, boolean cs) {
|
||||
final StatList stats = attrs.base().clear();
|
||||
final StatListBuilder builder = stats.buildList();
|
||||
return read(builder, bits);
|
||||
return read(builder, bits, cs);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,7 +72,7 @@ public class StatListReader {
|
||||
if (((flags >> i) & 1) == 1) {
|
||||
try {
|
||||
MDC.put("propList", StatListFlags.itemToString(i));
|
||||
read(builder, bits);
|
||||
read(builder, bits, false);
|
||||
} finally {
|
||||
MDC.remove("propList");
|
||||
}
|
||||
|
@ -11,10 +11,10 @@ import com.riiablo.logger.MDC;
|
||||
public class StatListWriter {
|
||||
private static final Logger log = LogManager.getLogger(StatListWriter.class);
|
||||
|
||||
public void write(StatListGetter stats, StatGetter stat, BitOutput bits) {
|
||||
public void write(StatListGetter stats, StatGetter stat, BitOutput bits, boolean cs) {
|
||||
log.traceEntry("write(stats: {}, stat: {}, bits: {})", stats, stat, bits);
|
||||
final ItemStatCost.Entry entry = stat.entry();
|
||||
if (entry.Saved) {
|
||||
if (cs) {
|
||||
if (log.traceEnabled()) log.trace("Writing character save stat {}", stat.debugString());
|
||||
assert !entry.CSvSigned : "entry.CSvSigned(" + entry.CSvSigned + ") unsupported";
|
||||
bits.write63u(stat.param(), entry.CSvParam);
|
||||
@ -26,7 +26,7 @@ public class StatListWriter {
|
||||
}
|
||||
}
|
||||
|
||||
public void write(StatListGetter stats, BitOutput bits) {
|
||||
public void write(StatListGetter stats, BitOutput bits, boolean cs) {
|
||||
for (Iterator<StatGetter> it = stats.iterator(); it.hasNext();) {
|
||||
final StatGetter stat = it.next();
|
||||
final short id = stat.id();
|
||||
@ -35,15 +35,20 @@ public class StatListWriter {
|
||||
bits.write15u(id, Stat.BITS);
|
||||
final byte numEncoded = Stat.getNumEncoded(id);
|
||||
try {
|
||||
if (numEncoded > 1) MDC.put("numEncoded", numEncoded);
|
||||
write(stats, stat, bits);
|
||||
if (numEncoded > 1) {
|
||||
MDC.put("numEncoded", numEncoded);
|
||||
MDC.put("encodedStat", id);
|
||||
}
|
||||
write(stats, stat, bits, cs);
|
||||
for (short j = 1; j < numEncoded; j++) {
|
||||
final StatGetter next = it.next();
|
||||
assert next.id() == id + j : String.format(
|
||||
"it.next(%s) != %d : getNumEncoded(%s)[%d..%d]", next, id + j, id + j, id, id + numEncoded - 1);
|
||||
write(stats, stat, bits);
|
||||
MDC.put("encodedStat", next.id());
|
||||
write(stats, stat, bits, cs);
|
||||
}
|
||||
} finally {
|
||||
MDC.remove("encodedStat");
|
||||
MDC.remove("numEncoded");
|
||||
}
|
||||
} finally {
|
||||
@ -53,4 +58,22 @@ public class StatListWriter {
|
||||
|
||||
bits.write15u(Stat.NONE, Stat.BITS);
|
||||
}
|
||||
|
||||
public void write(Attributes attrs, BitOutput bits) {
|
||||
throw new UnsupportedOperationException(); // TODO: character saves
|
||||
}
|
||||
|
||||
public void write(Attributes attrs, BitOutput bits, int flags, int maxLists) {
|
||||
final StatList stats = attrs.list();
|
||||
for (int i = 0; i < maxLists; i++) {
|
||||
if (((flags >> i) & 1) == 1) {
|
||||
try {
|
||||
MDC.put("propList", StatListFlags.itemToString(i));
|
||||
write(stats.get(i), bits, false);
|
||||
} finally {
|
||||
MDC.remove("propList");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public class StatListReaderTest {
|
||||
final BitInput bits = ByteInput.wrap(bytes).unalign();
|
||||
final Attributes attrs = Attributes.aggregateAttributes();
|
||||
final StatListReader reader = new StatListReader();
|
||||
reader.read(attrs.base().buildList(), bits);
|
||||
reader.read(attrs.base().buildList(), bits, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -89,7 +89,7 @@ public class StatListReaderTest {
|
||||
final BitInput bits = ByteInput.wrap(bytes).unalign().skipBits(197);
|
||||
final Attributes attrs = Attributes.aggregateAttributes();
|
||||
final StatListReader reader = new StatListReader();
|
||||
final StatListGetter stats = reader.read(attrs.base().buildList(), bits);
|
||||
final StatListGetter stats = reader.read(attrs.base().buildList(), bits, false);
|
||||
Assert.assertTrue(stats.contains(Stat.item_healafterkill));
|
||||
Assert.assertEquals(11, stats.get(Stat.item_healafterkill).value1());
|
||||
|
||||
|
@ -22,6 +22,10 @@ import com.riiablo.logger.Level;
|
||||
import com.riiablo.logger.LogManager;
|
||||
import com.riiablo.mpq.MPQFileHandleResolver;
|
||||
|
||||
import static com.riiablo.attributes.StatListFlags.FLAG_MAGIC;
|
||||
import static com.riiablo.attributes.StatListFlags.FLAG_RUNE;
|
||||
import static com.riiablo.attributes.StatListFlags.NUM_ITEM_LISTS;
|
||||
|
||||
public class StatListWriterTest {
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
@ -42,20 +46,21 @@ public class StatListWriterTest {
|
||||
LogManager.setLevel("com.riiablo.attributes", Level.TRACE);
|
||||
}
|
||||
|
||||
private void testItem(byte[] data, long bitsToSkip, int length) {
|
||||
private void testItem(byte[] data, long bitsToSkip, int length, int flags) {
|
||||
final int offset = (int) (bitsToSkip >> 3);
|
||||
final int bitOffset = (int) (bitsToSkip & 0x7);
|
||||
ByteInput in = ByteInput.wrap(Unpooled.wrappedBuffer(data, offset, length));
|
||||
BitInput bitInput = in.unalign().skipBits(bitOffset);
|
||||
StatListReader reader = new StatListReader();
|
||||
final StatListGetter stats = reader.read(StatList.obtain().buildList(), bitInput);
|
||||
final Attributes attrs = Attributes.aggregateAttributes();
|
||||
reader.read(attrs, bitInput, flags, NUM_ITEM_LISTS);
|
||||
System.out.println(ByteBufUtil.prettyHexDump(in.buffer(), 0, in.buffer().readerIndex()));
|
||||
|
||||
ByteOutput out = ByteOutput.wrap(Unpooled.buffer(length, length));
|
||||
BitOutput bitOutput = out.unalign().writeRaw(data[offset], bitOffset);
|
||||
System.out.println(ByteBufUtil.prettyHexDump(out.buffer()));
|
||||
StatListWriter writer = new StatListWriter();
|
||||
writer.write(stats, bitOutput);
|
||||
writer.write(attrs, bitOutput, flags, NUM_ITEM_LISTS);
|
||||
bitOutput.flush();
|
||||
System.out.println(ByteBufUtil.prettyHexDump(out.buffer()));
|
||||
|
||||
@ -63,7 +68,77 @@ public class StatListWriterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void read_item_grief_stats() {
|
||||
testItem(Gdx.files.internal("test/Grief.d2i").readBytes(), 197, 0x12);
|
||||
public void Spirit() {
|
||||
testItem(Gdx.files.internal("test/Spirit.d2i").readBytes(), 216, 0x19, FLAG_MAGIC | FLAG_RUNE);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void Annihilus() {
|
||||
// testItem(Gdx.files.internal("test/Annihilus.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Hunters_Bow_of_Blight() {
|
||||
// testItem(Gdx.files.internal("test/Hunter's Bow of Blight.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Horadric_Malus() {
|
||||
// testItem(Gdx.files.internal("test/Horadric Malus.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Wirts_Leg() {
|
||||
// testItem(Gdx.files.internal("test/Wirt's Leg.d2i").readBytes());
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void Grief() {
|
||||
testItem(Gdx.files.internal("test/Grief.d2i").readBytes(), 197, 0x12, FLAG_RUNE);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void Horadric_Cube() {
|
||||
// testItem(Gdx.files.internal("test/Horadric Cube.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Flawed_Ruby() {
|
||||
// testItem(Gdx.files.internal("test/Flawed Ruby.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Thul_Rune() {
|
||||
// testItem(Gdx.files.internal("test/Thul Rune.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Tome_of_Town_Portal() {
|
||||
// testItem(Gdx.files.internal("test/Tome of Town Portal.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Tome_of_Identify() {
|
||||
// testItem(Gdx.files.internal("test/Tome of Identify.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Rugged_Small_Charm_of_Vita() {
|
||||
// testItem(Gdx.files.internal("test/Rugged Small Charm of Vita.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Aldurs_Advance() {
|
||||
// testItem(Gdx.files.internal("test/Aldur's Advance.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Blood_Eye() {
|
||||
// testItem(Gdx.files.internal("test/Blood Eye.d2i").readBytes());
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void Vampire_Gaze() {
|
||||
// testItem(Gdx.files.internal("test/Vampire Gaze.d2i").readBytes());
|
||||
// }
|
||||
}
|
Reference in New Issue
Block a user