mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-07-28 05:38:21 +07:00
Added support for binary excel loading (see #26)
Refactored Excel parse factory methods to load methods Added tentative serialization code to MonStats
This commit is contained in:
@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.assets.AssetManager;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import com.riiablo.codec.TXT;
|
||||
import com.riiablo.codec.excel.ArmType;
|
||||
import com.riiablo.codec.excel.Armor;
|
||||
import com.riiablo.codec.excel.BodyLocs;
|
||||
@ -141,7 +140,7 @@ public class Files {
|
||||
MagicSuffix = load(MagicSuffix.class, Excel.EXPANSION);
|
||||
MonAI = load(MonAI.class);
|
||||
MonMode = load(MonMode.class);
|
||||
monstats = load2(MonStats.class, Excel.EXPANSION);
|
||||
monstats = load(MonStats.class, Excel.EXPANSION);
|
||||
monstats2 = load(MonStats2.class, Excel.EXPANSION);
|
||||
RarePrefix = load(RarePrefix.class, Excel.EXPANSION);
|
||||
RareSuffix = load(RareSuffix.class, Excel.EXPANSION);
|
||||
@ -176,8 +175,7 @@ public class Files {
|
||||
|
||||
private <T extends Excel> T loadInternal(Class<T> clazz, String filename) {
|
||||
FileHandle handle = Gdx.files.internal("data/" + filename + ".txt");
|
||||
TXT txt = TXT.loadFromFile(handle);
|
||||
return Excel.parse(txt, clazz);
|
||||
return Excel.load(clazz, handle);
|
||||
}
|
||||
|
||||
private <T extends Excel> T load(Class<T> clazz, ObjectSet<String> ignore) {
|
||||
@ -189,8 +187,8 @@ public class Files {
|
||||
}
|
||||
|
||||
private <T extends Excel> T load(Class<T> clazz, String tableName, ObjectSet<String> ignore) {
|
||||
FileHandle handle = Riiablo.mpqs.resolve(EXCEL_PATH + tableName + ".txt");
|
||||
TXT txt = TXT.loadFromFile(handle);
|
||||
return Excel.parse(txt, clazz, ignore);
|
||||
FileHandle txt = Riiablo.mpqs.resolve(EXCEL_PATH + tableName + ".txt");
|
||||
FileHandle bin = Gdx.files.internal(EXCEL_PATH + tableName + ".bin");
|
||||
return Excel.load(clazz, txt, bin, ignore);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,25 @@
|
||||
package com.riiablo.codec.excel;
|
||||
|
||||
import com.google.common.io.LittleEndianDataInputStream;
|
||||
|
||||
import android.support.annotation.CallSuper;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.ObjectIntMap;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import com.badlogic.gdx.utils.ObjectSet;
|
||||
import com.badlogic.gdx.utils.StreamUtils;
|
||||
import com.riiablo.codec.TXT;
|
||||
import com.riiablo.util.ClassUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -28,7 +37,9 @@ public abstract class Excel<T extends Excel.Entry> implements Iterable<T> {
|
||||
private static final boolean DEBUG_IGNORED = DEBUG && !true;
|
||||
private static final boolean DEBUG_ENTRIES = DEBUG && !true;
|
||||
private static final boolean DEBUG_INDEXES = DEBUG && !true;
|
||||
private static final boolean DEBUG_KEY = DEBUG && true;
|
||||
private static final boolean DEBUG_KEY = DEBUG && !true;
|
||||
private static final boolean DEBUG_BIN = DEBUG && true;
|
||||
private static final boolean DEBUG_TIME = DEBUG && true;
|
||||
|
||||
private static final boolean FORCE_PRIMARY_KEY = false;
|
||||
|
||||
@ -46,6 +57,10 @@ public abstract class Excel<T extends Excel.Entry> implements Iterable<T> {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Index {}
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Binned {}
|
||||
|
||||
public static class Entry {
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ -65,213 +80,284 @@ public abstract class Excel<T extends Excel.Entry> implements Iterable<T> {
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Key {}
|
||||
|
||||
public void readBin(DataInput in) throws IOException {}
|
||||
|
||||
public void writeBin(DataOutput out) throws IOException {}
|
||||
}
|
||||
|
||||
ObjectIntMap<String> STRING_TO_ID = EMPTY_MAP;
|
||||
IntMap<T> entries = new IntMap<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Excel> T parse(TXT txt, Class<T> excelClass) {
|
||||
return parse(txt, excelClass, Excel.<String>emptySet());
|
||||
public static <T extends Excel> T load(Class<T> excelClass, FileHandle txt) {
|
||||
return load(excelClass, txt, Excel.<String>emptySet());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Excel> T parse(TXT txt, Class<T> excelClass, ObjectSet<String> ignore) {
|
||||
public static <T extends Excel> T load(Class<T> excelClass, FileHandle txt, ObjectSet<String> ignore) {
|
||||
return load(excelClass, txt, null, ignore);
|
||||
}
|
||||
|
||||
public static <T extends Excel> T load(Class<T> excelClass, FileHandle txt, FileHandle bin, ObjectSet<String> ignore) {
|
||||
try {
|
||||
if (ignore == null) ignore = emptySet();
|
||||
|
||||
Class<Entry> entryClass = getEntryClass(excelClass);
|
||||
if (entryClass == null) throw new AssertionError(excelClass + " does not implement " + Entry.class);
|
||||
|
||||
final boolean index = entryClass.getAnnotation(Index.class) != null;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
Field primaryKey = null, firstKey = null;
|
||||
T excel = excelClass.newInstance();
|
||||
ObjectMap<Field, int[]> columns = new ObjectMap<>();
|
||||
String[] TMP = new String[1];
|
||||
for (Field field : entryClass.getFields()) {
|
||||
Entry.Column column = field.getAnnotation(Entry.Column.class);
|
||||
if (column == null) continue;
|
||||
T excel;
|
||||
FileHandle file;
|
||||
if (isBinned(excelClass) && bin != null && bin.exists()) {
|
||||
if (DEBUG_BIN) Gdx.app.debug(TAG, "Loading bin " + bin);
|
||||
excel = loadBin(bin, excelClass);
|
||||
file = bin;
|
||||
} else {
|
||||
if (DEBUG_BIN) Gdx.app.debug(TAG, "Loading txt " + txt);
|
||||
excel = loadTxt(txt, excelClass, entryClass, ignore);
|
||||
file = txt;
|
||||
}
|
||||
|
||||
Entry.Key key = field.getAnnotation(Entry.Key.class);
|
||||
if (key != null) {
|
||||
if (index) {
|
||||
Gdx.app.error(TAG, "primary key set in class annotated with " + Index.class);
|
||||
} else if (primaryKey != null) {
|
||||
boolean primaryDeclared = ClassUtils.isDeclaredField(entryClass, primaryKey);
|
||||
boolean fieldDeclared = ClassUtils.isDeclaredField(entryClass, field);
|
||||
if (primaryDeclared != fieldDeclared) {
|
||||
if (fieldDeclared) {
|
||||
if (DEBUG_KEY) Gdx.app.debug(TAG, "primary key " + primaryKey.getName() + " -> " + field.getName());
|
||||
primaryKey = field;
|
||||
}
|
||||
} else {
|
||||
Gdx.app.error(TAG, "more than one primary key for " + entryClass + " " + primaryKey.getName() + " and " + field.getName());
|
||||
long end = System.currentTimeMillis();
|
||||
if (DEBUG_TIME) Gdx.app.debug(TAG, "Loaded " + file + " in " + (end - start) + "ms");
|
||||
|
||||
excel.init();
|
||||
return excel;
|
||||
} catch (Throwable t) {
|
||||
throw new GdxRuntimeException("Couldn't load excel " + excelClass, t);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends Excel> T loadTxt(FileHandle handle, Class<T> excelClass, Class<Entry> entryClass, ObjectSet<String> ignore) throws Exception {
|
||||
TXT txt = TXT.loadFromFile(handle);
|
||||
|
||||
final boolean index = ClassUtils.hasAnnotation(entryClass, Index.class);
|
||||
|
||||
Field primaryKey = null, firstKey = null;
|
||||
T excel = excelClass.newInstance();
|
||||
ObjectMap<Field, int[]> columns = new ObjectMap<>();
|
||||
String[] TMP = new String[1];
|
||||
for (Field field : entryClass.getFields()) {
|
||||
Entry.Column column = field.getAnnotation(Entry.Column.class);
|
||||
if (column == null) continue;
|
||||
|
||||
Entry.Key key = field.getAnnotation(Entry.Key.class);
|
||||
if (key != null) {
|
||||
if (index) {
|
||||
Gdx.app.error(TAG, "primary key set in class annotated with " + Index.class);
|
||||
} else if (primaryKey != null) {
|
||||
boolean primaryDeclared = ClassUtils.isDeclaredField(entryClass, primaryKey);
|
||||
boolean fieldDeclared = ClassUtils.isDeclaredField(entryClass, field);
|
||||
if (primaryDeclared != fieldDeclared) {
|
||||
if (fieldDeclared) {
|
||||
if (DEBUG_KEY) Gdx.app.debug(TAG, "primary key " + primaryKey.getName() + " -> " + field.getName());
|
||||
primaryKey = field;
|
||||
}
|
||||
} else {
|
||||
primaryKey = field;
|
||||
Gdx.app.error(TAG, "more than one primary key for " + entryClass + " " + primaryKey.getName() + " and " + field.getName());
|
||||
}
|
||||
} else {
|
||||
primaryKey = field;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstKey == null) firstKey = field;
|
||||
if (firstKey == null) firstKey = field;
|
||||
|
||||
final String format = column.format();
|
||||
final String values[] = column.values();
|
||||
final int startIndex = column.startIndex();
|
||||
final int endIndex = column.endIndex();
|
||||
final int columnIndex = column.columnIndex();
|
||||
if (columnIndex >= 0) {
|
||||
columns.put(field, new int[] { columnIndex });
|
||||
} else if (format.isEmpty()) {
|
||||
final String fieldName = field.getName();
|
||||
if (values.length > 0) {
|
||||
String[] columnNames = new String[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
String name = values[i];
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, name);
|
||||
columnNames[i] = name;
|
||||
}
|
||||
final String format = column.format();
|
||||
final String values[] = column.values();
|
||||
final int startIndex = column.startIndex();
|
||||
final int endIndex = column.endIndex();
|
||||
final int columnIndex = column.columnIndex();
|
||||
if (columnIndex >= 0) {
|
||||
columns.put(field, new int[] { columnIndex });
|
||||
} else if (format.isEmpty()) {
|
||||
final String fieldName = field.getName();
|
||||
if (values.length > 0) {
|
||||
String[] columnNames = new String[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
String name = values[i];
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, name);
|
||||
columnNames[i] = name;
|
||||
}
|
||||
|
||||
columns.put(field, txt.getColumnId(columnNames));
|
||||
} else if (startIndex == 0 && endIndex == 0) {
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, fieldName);
|
||||
TMP[0] = fieldName;
|
||||
columns.put(field, txt.getColumnId(TMP));
|
||||
} else {
|
||||
String[] columnNames = new String[endIndex - startIndex];
|
||||
columns.put(field, txt.getColumnId(columnNames));
|
||||
} else if (startIndex == 0 && endIndex == 0) {
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, fieldName);
|
||||
TMP[0] = fieldName;
|
||||
columns.put(field, txt.getColumnId(TMP));
|
||||
} else {
|
||||
String[] columnNames = new String[endIndex - startIndex];
|
||||
for (int i = startIndex, j = 0; i < endIndex; i++, j++) {
|
||||
String name = fieldName + i;
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, name);
|
||||
columnNames[j] = name;
|
||||
}
|
||||
|
||||
columns.put(field, txt.getColumnId(columnNames));
|
||||
}
|
||||
} else {
|
||||
if (startIndex == 0 && endIndex == 0) {
|
||||
TMP[0] = format;
|
||||
columns.put(field, txt.getColumnId(TMP));
|
||||
} else {
|
||||
String[] columnNames = new String[endIndex - startIndex];
|
||||
if (values.length == 0) {
|
||||
for (int i = startIndex, j = 0; i < endIndex; i++, j++) {
|
||||
String name = fieldName + i;
|
||||
String name = String.format(format, i);
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, name);
|
||||
columnNames[j] = name;
|
||||
}
|
||||
|
||||
columns.put(field, txt.getColumnId(columnNames));
|
||||
}
|
||||
} else {
|
||||
if (startIndex == 0 && endIndex == 0) {
|
||||
TMP[0] = format;
|
||||
columns.put(field, txt.getColumnId(TMP));
|
||||
} else {
|
||||
String[] columnNames = new String[endIndex - startIndex];
|
||||
if (values.length == 0) {
|
||||
for (int i = startIndex, j = 0; i < endIndex; i++, j++) {
|
||||
String name = String.format(format, i);
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, name);
|
||||
columnNames[j] = name;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
String name = String.format(format, values[i]);
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, name);
|
||||
columnNames[i] = name;
|
||||
}
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
String name = String.format(format, values[i]);
|
||||
if (DEBUG_COLS) Gdx.app.debug(TAG, name);
|
||||
columnNames[i] = name;
|
||||
}
|
||||
|
||||
columns.put(field, txt.getColumnId(columnNames));
|
||||
}
|
||||
|
||||
columns.put(field, txt.getColumnId(columnNames));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (primaryKey == null && !index) {
|
||||
if (FORCE_PRIMARY_KEY) {
|
||||
throw new IllegalStateException(entryClass + " does not have a " + Entry.Key.class + " set!");
|
||||
if (primaryKey == null && !index) {
|
||||
if (FORCE_PRIMARY_KEY) {
|
||||
throw new IllegalStateException(entryClass + " does not have a " + Entry.Key.class + " set!");
|
||||
} else {
|
||||
primaryKey = firstKey;
|
||||
Gdx.app.error(TAG, entryClass + " does not have a " + Entry.Key.class + " set! Using " + firstKey.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_COL_IDS) {
|
||||
for (ObjectMap.Entry<Field, int[]> entry : columns.entries()) {
|
||||
Gdx.app.debug(TAG, entry.key.getName() + ": " + Arrays.toString(entry.value));
|
||||
}
|
||||
}
|
||||
|
||||
final int primaryKeyCol = index ? -1 : columns.get(primaryKey)[0];
|
||||
final Class primaryKeyType = index ? null : primaryKey.getType();
|
||||
final int size = txt.getRows();
|
||||
for (int i = 0, j = excel.offset(); i < size; i++) {
|
||||
Entry entry = entryClass.newInstance();
|
||||
|
||||
String rowName = txt.getRowName(i);
|
||||
if (ignore.contains(rowName)) {
|
||||
if (DEBUG_IGNORED) Gdx.app.debug(TAG, "Skipping row " + i + ", ignoring rows named " + rowName);
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = index ? null : txt.getString(i, primaryKeyCol);
|
||||
for (ObjectMap.Entry<Field, int[]> row : columns.entries()) {
|
||||
Field field = row.key;
|
||||
int[] columnIds = row.value;
|
||||
Class type = field.getType();
|
||||
assert type.isArray() || columnIds.length == 1 : "field should only correspond to 1 column: " + field.getName() + ", " + columnIds.length + " columns (is it supposed to be an array?)";
|
||||
if (type == String.class) {
|
||||
String value = txt.getString(i, columnIds[0]);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == String[].class) {
|
||||
String[] value = txt.getString(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == byte.class) {
|
||||
byte value = txt.getByte(i, columnIds[0]);
|
||||
field.setByte(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == byte[].class) {
|
||||
byte[] value = txt.getByte(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == short.class) {
|
||||
short value = txt.getShort(i, columnIds[0]);
|
||||
field.setShort(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == short[].class) {
|
||||
short[] value = txt.getShort(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == int.class) {
|
||||
int value = txt.getInt(i, columnIds[0]);
|
||||
field.setInt(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == int[].class) {
|
||||
int[] value = txt.getInt(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == long.class) {
|
||||
long value = txt.getLong(i, columnIds[0]);
|
||||
field.setLong(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == long[].class) {
|
||||
long[] value = txt.getLong(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == boolean.class) {
|
||||
boolean value = txt.getBoolean(i, columnIds[0]);
|
||||
field.setBoolean(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == boolean[].class) {
|
||||
boolean[] value = txt.getBoolean(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else {
|
||||
primaryKey = firstKey;
|
||||
Gdx.app.error(TAG, entryClass + " does not have a " + Entry.Key.class + " set! Using " + firstKey.getName());
|
||||
throw new UnsupportedOperationException("No support for " + type + " fields");
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_COL_IDS) {
|
||||
for (ObjectMap.Entry<Field, int[]> entry : columns.entries()) {
|
||||
Gdx.app.debug(TAG, entry.key.getName() + ": " + Arrays.toString(entry.value));
|
||||
}
|
||||
if (index) {
|
||||
excel.put(j++, entry);
|
||||
} else if (primaryKeyType == int.class) {
|
||||
int id = primaryKey.getInt(entry);
|
||||
excel.put(id, entry);
|
||||
} else if (primaryKeyType == String.class) {
|
||||
String id = name;//(String) primaryKey.get(entry);
|
||||
excel.put(j, entry);
|
||||
|
||||
if (excel.STRING_TO_ID == EMPTY_MAP) excel.STRING_TO_ID = new ObjectIntMap();
|
||||
if (!excel.STRING_TO_ID.containsKey(id)) excel.STRING_TO_ID.put(id, j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
final int primaryKeyCol = index ? -1 : columns.get(primaryKey)[0];
|
||||
final Class primaryKeyType = index ? null : primaryKey.getType();
|
||||
final int size = txt.getRows();
|
||||
for (int i = 0, j = excel.offset(); i < size; i++) {
|
||||
Entry entry = entryClass.newInstance();
|
||||
return excel;
|
||||
}
|
||||
|
||||
String rowName = txt.getRowName(i);
|
||||
if (ignore.contains(rowName)) {
|
||||
if (DEBUG_IGNORED) Gdx.app.debug(TAG, "Skipping row " + i + ", ignoring rows named " + rowName);
|
||||
continue;
|
||||
}
|
||||
private static <T extends Excel> T loadBin(FileHandle bin, Class<T> excelClass) throws Exception {
|
||||
byte[] bytes = bin.readBytes();
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = new ByteArrayInputStream(bytes);
|
||||
LittleEndianDataInputStream dis = new LittleEndianDataInputStream(in);
|
||||
T excel = excelClass.newInstance();
|
||||
excel.readBin(dis);
|
||||
return excel;
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(in);
|
||||
}
|
||||
}
|
||||
|
||||
String name = index ? null : txt.getString(i, primaryKeyCol);
|
||||
for (ObjectMap.Entry<Field, int[]> row : columns.entries()) {
|
||||
Field field = row.key;
|
||||
int[] columnIds = row.value;
|
||||
Class type = field.getType();
|
||||
assert type.isArray() || columnIds.length == 1 : "field should only correspond to 1 column: " + field.getName() + ", " + columnIds.length + " columns (is it supposed to be an array?)";
|
||||
if (type == String.class) {
|
||||
String value = txt.getString(i, columnIds[0]);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == String[].class) {
|
||||
String[] value = txt.getString(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == byte.class) {
|
||||
byte value = txt.getByte(i, columnIds[0]);
|
||||
field.setByte(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == byte[].class) {
|
||||
byte[] value = txt.getByte(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == short.class) {
|
||||
short value = txt.getShort(i, columnIds[0]);
|
||||
field.setShort(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == short[].class) {
|
||||
short[] value = txt.getShort(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == int.class) {
|
||||
int value = txt.getInt(i, columnIds[0]);
|
||||
field.setInt(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == int[].class) {
|
||||
int[] value = txt.getInt(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == long.class) {
|
||||
long value = txt.getLong(i, columnIds[0]);
|
||||
field.setLong(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == long[].class) {
|
||||
long[] value = txt.getLong(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else if (type == boolean.class) {
|
||||
boolean value = txt.getBoolean(i, columnIds[0]);
|
||||
field.setBoolean(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), value));
|
||||
} else if (type == boolean[].class) {
|
||||
boolean[] value = txt.getBoolean(i, columnIds);
|
||||
field.set(entry, value);
|
||||
if (DEBUG_ENTRIES) Gdx.app.debug(TAG, String.format("Entry[%d](%s).%s=%s", j, name, field.getName(), Arrays.toString(value)));
|
||||
} else {
|
||||
throw new UnsupportedOperationException("No support for " + type + " fields");
|
||||
}
|
||||
}
|
||||
static boolean isBinned(Class c) {
|
||||
return ClassUtils.hasAnnotation(c, Binned.class);
|
||||
}
|
||||
|
||||
if (index) {
|
||||
excel.put(j++, entry);
|
||||
} else if (primaryKeyType == int.class) {
|
||||
int id = primaryKey.getInt(entry);
|
||||
excel.put(id, entry);
|
||||
} else if (primaryKeyType == String.class) {
|
||||
String id = name;//(String) primaryKey.get(entry);
|
||||
excel.put(j, entry);
|
||||
public final boolean isBinned() {
|
||||
return isBinned(this.getClass());
|
||||
}
|
||||
|
||||
if (excel.STRING_TO_ID == EMPTY_MAP) excel.STRING_TO_ID = new ObjectIntMap();
|
||||
if (!excel.STRING_TO_ID.containsKey(id)) excel.STRING_TO_ID.put(id, j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
public void readBin(DataInput in) throws IOException {}
|
||||
|
||||
public void writeBin(DataOutput out) throws IOException {}
|
||||
|
||||
public static <T extends Excel> T read(Class<T> excelClass, DataInput in) {
|
||||
if (!isBinned(excelClass)) {
|
||||
throw new GdxRuntimeException(excelClass + " is not annotated with " + Excel.Binned.class);
|
||||
}
|
||||
|
||||
try {
|
||||
T excel = excelClass.newInstance();
|
||||
excel.readBin(in);
|
||||
excel.init();
|
||||
return excel;
|
||||
} catch (Throwable t) {
|
||||
|
@ -1,8 +1,36 @@
|
||||
package com.riiablo.codec.excel;
|
||||
|
||||
import com.riiablo.codec.excel.Excel;
|
||||
import com.badlogic.gdx.utils.ObjectIntMap;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
@Excel.Binned
|
||||
public class MonStats extends Excel<MonStats.Entry> {
|
||||
@Override
|
||||
public void readBin(DataInput in) throws IOException {
|
||||
STRING_TO_ID = new ObjectIntMap();
|
||||
int size = in.readInt();
|
||||
//System.out.println(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
Entry entry = new Entry();
|
||||
entry.readBin(in);
|
||||
//System.out.println(entry.hcIdx + ":" + entry.Id);
|
||||
put(entry.hcIdx, entry);
|
||||
|
||||
if (!STRING_TO_ID.containsKey(entry.Id)) STRING_TO_ID.put(entry.Id, entry.hcIdx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBin(DataOutput out) throws IOException {
|
||||
out.writeInt(size());
|
||||
for (MonStats.Entry entry : entries.values()) {
|
||||
entry.writeBin(out);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Entry extends Excel.Entry {
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -215,5 +243,374 @@ public class MonStats extends Excel<MonStats.Entry> {
|
||||
@Column public boolean SplGetModeChart;
|
||||
@Column public boolean SplEndGeneric;
|
||||
@Column public boolean SplClientEnd;
|
||||
|
||||
@Override
|
||||
public void readBin(DataInput in) throws IOException {
|
||||
Id = in.readUTF();
|
||||
hcIdx = in.readInt();
|
||||
BaseId = in.readUTF();
|
||||
NextInClass = in.readUTF();
|
||||
TransLvl = in.readInt();
|
||||
NameStr = in.readUTF();
|
||||
MonStatsEx = in.readUTF();
|
||||
MonProp = in.readUTF();
|
||||
MonType = in.readUTF();
|
||||
AI = in.readUTF();
|
||||
DescStr = in.readUTF();
|
||||
Code = in.readUTF();
|
||||
enabled = in.readBoolean();
|
||||
rangedtype = in.readBoolean();
|
||||
placespawn = in.readBoolean();
|
||||
spawn = in.readUTF();
|
||||
spawnx = in.readInt();
|
||||
spawny = in.readInt();
|
||||
spawnmode = in.readUTF();
|
||||
minion1 = in.readUTF();
|
||||
minion2 = in.readUTF();
|
||||
SetBoss = in.readBoolean();
|
||||
BossXfer = in.readBoolean();
|
||||
PartyMin = in.readInt();
|
||||
PartyMax = in.readInt();
|
||||
MinGrp = in.readInt();
|
||||
MaxGrp = in.readInt();
|
||||
sparsePopulate = in.readInt();
|
||||
Velocity = in.readInt();
|
||||
Run = in.readInt();
|
||||
Rarity = in.readInt();
|
||||
Level = new int[3];
|
||||
for (int x = 0; x < 3; x++) Level[x] = in.readInt();
|
||||
MonSound = in.readUTF();
|
||||
UMonSound = in.readUTF();
|
||||
threat = in.readInt();
|
||||
aidel = new int[3];
|
||||
for (int x = 0; x < 3; x++) aidel[x] = in.readInt();
|
||||
aidist = new int[3];
|
||||
for (int x = 0; x < 3; x++) aidist[x] = in.readInt();
|
||||
aip1 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip1[x] = in.readInt();
|
||||
aip2 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip2[x] = in.readInt();
|
||||
aip3 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip3[x] = in.readInt();
|
||||
aip4 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip4[x] = in.readInt();
|
||||
aip5 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip5[x] = in.readInt();
|
||||
aip6 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip6[x] = in.readInt();
|
||||
aip7 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip7[x] = in.readInt();
|
||||
aip8 = new int[3];
|
||||
for (int x = 0; x < 3; x++) aip8[x] = in.readInt();
|
||||
MissA1 = in.readUTF();
|
||||
MissA2 = in.readUTF();
|
||||
MissS1 = in.readUTF();
|
||||
MissS2 = in.readUTF();
|
||||
MissS3 = in.readUTF();
|
||||
MissS4 = in.readUTF();
|
||||
MissC = in.readUTF();
|
||||
MissSQ = in.readUTF();
|
||||
Align = in.readInt();
|
||||
isSpawn = in.readBoolean();
|
||||
isMelee = in.readBoolean();
|
||||
npc = in.readBoolean();
|
||||
interact = in.readBoolean();
|
||||
inventory = in.readBoolean();
|
||||
inTown = in.readBoolean();
|
||||
lUndead = in.readBoolean();
|
||||
hUndead = in.readBoolean();
|
||||
demon = in.readBoolean();
|
||||
flying = in.readBoolean();
|
||||
opendoors = in.readBoolean();
|
||||
boss = in.readBoolean();
|
||||
primeevil = in.readBoolean();
|
||||
killable = in.readBoolean();
|
||||
switchai = in.readBoolean();
|
||||
noAura = in.readBoolean();
|
||||
nomultishot = in.readBoolean();
|
||||
neverCount = in.readBoolean();
|
||||
petIgnore = in.readBoolean();
|
||||
deathDmg = in.readBoolean();
|
||||
genericSpawn = in.readBoolean();
|
||||
zoo = in.readBoolean();
|
||||
SendSkills = in.readInt();
|
||||
Skill1 = in.readUTF();
|
||||
Sk1mode = in.readUTF();
|
||||
Sk1lvl = in.readInt();
|
||||
Skill2 = in.readUTF();
|
||||
Sk2mode = in.readUTF();
|
||||
Sk2lvl = in.readInt();
|
||||
Skill3 = in.readUTF();
|
||||
Sk3mode = in.readUTF();
|
||||
Sk3lvl = in.readInt();
|
||||
Skill4 = in.readUTF();
|
||||
Sk4mode = in.readUTF();
|
||||
Sk4lvl = in.readInt();
|
||||
Skill5 = in.readUTF();
|
||||
Sk5mode = in.readUTF();
|
||||
Sk5lvl = in.readInt();
|
||||
Skill6 = in.readUTF();
|
||||
Sk6mode = in.readUTF();
|
||||
Sk6lvl = in.readInt();
|
||||
Skill7 = in.readUTF();
|
||||
Sk7mode = in.readUTF();
|
||||
Sk7lvl = in.readInt();
|
||||
Skill8 = in.readUTF();
|
||||
Sk8mode = in.readUTF();
|
||||
Sk8lvl = in.readInt();
|
||||
Drain = new int[3];
|
||||
for (int x = 0; x < 3; x++) Drain[x] = in.readInt();
|
||||
coldeffect = new int[3];
|
||||
for (int x = 0; x < 3; x++) coldeffect[x] = in.readInt();
|
||||
ResDm = new int[3];
|
||||
for (int x = 0; x < 3; x++) ResDm[x] = in.readInt();
|
||||
ResMa = new int[3];
|
||||
for (int x = 0; x < 3; x++) ResMa[x] = in.readInt();
|
||||
ResFi = new int[3];
|
||||
for (int x = 0; x < 3; x++) ResFi[x] = in.readInt();
|
||||
ResLi = new int[3];
|
||||
for (int x = 0; x < 3; x++) ResLi[x] = in.readInt();
|
||||
ResCo = new int[3];
|
||||
for (int x = 0; x < 3; x++) ResCo[x] = in.readInt();
|
||||
ResPo = new int[3];
|
||||
for (int x = 0; x < 3; x++) ResPo[x] = in.readInt();
|
||||
DamageRegen = in.readInt();
|
||||
SkillDamage = in.readUTF();
|
||||
noRatio = in.readBoolean();
|
||||
NoShldBlock = in.readBoolean();
|
||||
ToBlock = new int[3];
|
||||
for (int x = 0; x < 3; x++) ToBlock[x] = in.readInt();
|
||||
Crit = in.readInt();
|
||||
minHP = new int[3];
|
||||
for (int x = 0; x < 3; x++) minHP[x] = in.readInt();
|
||||
maxHP = new int[3];
|
||||
for (int x = 0; x < 3; x++) maxHP[x] = in.readInt();
|
||||
AC = new int[3];
|
||||
for (int x = 0; x < 3; x++) AC[x] = in.readInt();
|
||||
Exp = new int[3];
|
||||
for (int x = 0; x < 3; x++) Exp[x] = in.readInt();
|
||||
A1MinD = new int[3];
|
||||
for (int x = 0; x < 3; x++) A1MinD[x] = in.readInt();
|
||||
A1MaxD = new int[3];
|
||||
for (int x = 0; x < 3; x++) A1MaxD[x] = in.readInt();
|
||||
A1TH = new int[3];
|
||||
for (int x = 0; x < 3; x++) A1TH[x] = in.readInt();
|
||||
A2MinD = new int[3];
|
||||
for (int x = 0; x < 3; x++) A2MinD[x] = in.readInt();
|
||||
A2MaxD = new int[3];
|
||||
for (int x = 0; x < 3; x++) A2MaxD[x] = in.readInt();
|
||||
A2TH = new int[3];
|
||||
for (int x = 0; x < 3; x++) A2TH[x] = in.readInt();
|
||||
S1MinD = new int[3];
|
||||
for (int x = 0; x < 3; x++) S1MinD[x] = in.readInt();
|
||||
S1MaxD = new int[3];
|
||||
for (int x = 0; x < 3; x++) S1MaxD[x] = in.readInt();
|
||||
S1TH = new int[3];
|
||||
for (int x = 0; x < 3; x++) S1TH[x] = in.readInt();
|
||||
El1Mode = in.readUTF();
|
||||
El1Type = in.readUTF();
|
||||
El1Pct = new int[3];
|
||||
for (int x = 0; x < 3; x++) El1Pct[x] = in.readInt();
|
||||
El1MinD = new int[3];
|
||||
for (int x = 0; x < 3; x++) El1MinD[x] = in.readInt();
|
||||
El1MaxD = new int[3];
|
||||
for (int x = 0; x < 3; x++) El1MaxD[x] = in.readInt();
|
||||
El1Dur = new int[3];
|
||||
for (int x = 0; x < 3; x++) El1Dur[x] = in.readInt();
|
||||
El2Mode = in.readUTF();
|
||||
El2Type = in.readUTF();
|
||||
El2Pct = new int[3];
|
||||
for (int x = 0; x < 3; x++) El2Pct[x] = in.readInt();
|
||||
El2MinD = new int[3];
|
||||
for (int x = 0; x < 3; x++) El2MinD[x] = in.readInt();
|
||||
El2MaxD = new int[3];
|
||||
for (int x = 0; x < 3; x++) El2MaxD[x] = in.readInt();
|
||||
El2Dur = new int[3];
|
||||
for (int x = 0; x < 3; x++) El2Dur[x] = in.readInt();
|
||||
El3Mode = in.readUTF();
|
||||
El3Type = in.readUTF();
|
||||
El3Pct = new int[3];
|
||||
for (int x = 0; x < 3; x++) El3Pct[x] = in.readInt();
|
||||
El3MinD = new int[3];
|
||||
for (int x = 0; x < 3; x++) El3MinD[x] = in.readInt();
|
||||
El3MaxD = new int[3];
|
||||
for (int x = 0; x < 3; x++) El3MaxD[x] = in.readInt();
|
||||
El3Dur = new int[3];
|
||||
for (int x = 0; x < 3; x++) El3Dur[x] = in.readInt();
|
||||
TreasureClass1 = new String[3];
|
||||
for (int x = 0; x < 3; x++) TreasureClass1[x] = in.readUTF();
|
||||
TreasureClass2 = new String[3];
|
||||
for (int x = 0; x < 3; x++) TreasureClass2[x] = in.readUTF();
|
||||
TreasureClass3 = new String[3];
|
||||
for (int x = 0; x < 3; x++) TreasureClass3[x] = in.readUTF();
|
||||
TreasureClass4 = new String[3];
|
||||
for (int x = 0; x < 3; x++) TreasureClass4[x] = in.readUTF();
|
||||
TCQuestId = in.readInt();
|
||||
TCQuestCP = in.readInt();
|
||||
SplEndDeath = in.readInt();
|
||||
SplGetModeChart = in.readBoolean();
|
||||
SplEndGeneric = in.readBoolean();
|
||||
SplClientEnd = in.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBin(DataOutput out) throws IOException {
|
||||
out.writeUTF(Id);
|
||||
out.writeInt(hcIdx);
|
||||
out.writeUTF(BaseId);
|
||||
out.writeUTF(NextInClass);
|
||||
out.writeInt(TransLvl);
|
||||
out.writeUTF(NameStr);
|
||||
out.writeUTF(MonStatsEx);
|
||||
out.writeUTF(MonProp);
|
||||
out.writeUTF(MonType);
|
||||
out.writeUTF(AI);
|
||||
out.writeUTF(DescStr);
|
||||
out.writeUTF(Code);
|
||||
out.writeBoolean(enabled);
|
||||
out.writeBoolean(rangedtype);
|
||||
out.writeBoolean(placespawn);
|
||||
out.writeUTF(spawn);
|
||||
out.writeInt(spawnx);
|
||||
out.writeInt(spawny);
|
||||
out.writeUTF(spawnmode);
|
||||
out.writeUTF(minion1);
|
||||
out.writeUTF(minion2);
|
||||
out.writeBoolean(SetBoss);
|
||||
out.writeBoolean(BossXfer);
|
||||
out.writeInt(PartyMin);
|
||||
out.writeInt(PartyMax);
|
||||
out.writeInt(MinGrp);
|
||||
out.writeInt(MaxGrp);
|
||||
out.writeInt(sparsePopulate);
|
||||
out.writeInt(Velocity);
|
||||
out.writeInt(Run);
|
||||
out.writeInt(Rarity);
|
||||
for (int x : Level) out.writeInt(x);
|
||||
out.writeUTF(MonSound);
|
||||
out.writeUTF(UMonSound);
|
||||
out.writeInt(threat);
|
||||
for (int x : aidel) out.writeInt(x);
|
||||
for (int x : aidist) out.writeInt(x);
|
||||
for (int x : aip1) out.writeInt(x);
|
||||
for (int x : aip2) out.writeInt(x);
|
||||
for (int x : aip3) out.writeInt(x);
|
||||
for (int x : aip4) out.writeInt(x);
|
||||
for (int x : aip5) out.writeInt(x);
|
||||
for (int x : aip6) out.writeInt(x);
|
||||
for (int x : aip7) out.writeInt(x);
|
||||
for (int x : aip8) out.writeInt(x);
|
||||
out.writeUTF(MissA1);
|
||||
out.writeUTF(MissA2);
|
||||
out.writeUTF(MissS1);
|
||||
out.writeUTF(MissS2);
|
||||
out.writeUTF(MissS3);
|
||||
out.writeUTF(MissS4);
|
||||
out.writeUTF(MissC);
|
||||
out.writeUTF(MissSQ);
|
||||
out.writeInt(Align);
|
||||
out.writeBoolean(isSpawn);
|
||||
out.writeBoolean(isMelee);
|
||||
out.writeBoolean(npc);
|
||||
out.writeBoolean(interact);
|
||||
out.writeBoolean(inventory);
|
||||
out.writeBoolean(inTown);
|
||||
out.writeBoolean(lUndead);
|
||||
out.writeBoolean(hUndead);
|
||||
out.writeBoolean(demon);
|
||||
out.writeBoolean(flying);
|
||||
out.writeBoolean(opendoors);
|
||||
out.writeBoolean(boss);
|
||||
out.writeBoolean(primeevil);
|
||||
out.writeBoolean(killable);
|
||||
out.writeBoolean(switchai);
|
||||
out.writeBoolean(noAura);
|
||||
out.writeBoolean(nomultishot);
|
||||
out.writeBoolean(neverCount);
|
||||
out.writeBoolean(petIgnore);
|
||||
out.writeBoolean(deathDmg);
|
||||
out.writeBoolean(genericSpawn);
|
||||
out.writeBoolean(zoo);
|
||||
out.writeInt(SendSkills);
|
||||
out.writeUTF(Skill1);
|
||||
out.writeUTF(Sk1mode);
|
||||
out.writeInt(Sk1lvl);
|
||||
out.writeUTF(Skill2);
|
||||
out.writeUTF(Sk2mode);
|
||||
out.writeInt(Sk2lvl);
|
||||
out.writeUTF(Skill3);
|
||||
out.writeUTF(Sk3mode);
|
||||
out.writeInt(Sk3lvl);
|
||||
out.writeUTF(Skill4);
|
||||
out.writeUTF(Sk4mode);
|
||||
out.writeInt(Sk4lvl);
|
||||
out.writeUTF(Skill5);
|
||||
out.writeUTF(Sk5mode);
|
||||
out.writeInt(Sk5lvl);
|
||||
out.writeUTF(Skill6);
|
||||
out.writeUTF(Sk6mode);
|
||||
out.writeInt(Sk6lvl);
|
||||
out.writeUTF(Skill7);
|
||||
out.writeUTF(Sk7mode);
|
||||
out.writeInt(Sk7lvl);
|
||||
out.writeUTF(Skill8);
|
||||
out.writeUTF(Sk8mode);
|
||||
out.writeInt(Sk8lvl);
|
||||
for (int x : Drain) out.writeInt(x);
|
||||
for (int x : coldeffect) out.writeInt(x);
|
||||
for (int x : ResDm) out.writeInt(x);
|
||||
for (int x : ResMa) out.writeInt(x);
|
||||
for (int x : ResFi) out.writeInt(x);
|
||||
for (int x : ResLi) out.writeInt(x);
|
||||
for (int x : ResCo) out.writeInt(x);
|
||||
for (int x : ResPo) out.writeInt(x);
|
||||
out.writeInt(DamageRegen);
|
||||
out.writeUTF(SkillDamage);
|
||||
out.writeBoolean(noRatio);
|
||||
out.writeBoolean(NoShldBlock);
|
||||
for (int x : ToBlock) out.writeInt(x);
|
||||
out.writeInt(Crit);
|
||||
for (int x : minHP) out.writeInt(x);
|
||||
for (int x : maxHP) out.writeInt(x);
|
||||
for (int x : AC) out.writeInt(x);
|
||||
for (int x : Exp) out.writeInt(x);
|
||||
for (int x : A1MinD) out.writeInt(x);
|
||||
for (int x : A1MaxD) out.writeInt(x);
|
||||
for (int x : A1TH) out.writeInt(x);
|
||||
for (int x : A2MinD) out.writeInt(x);
|
||||
for (int x : A2MaxD) out.writeInt(x);
|
||||
for (int x : A2TH) out.writeInt(x);
|
||||
for (int x : S1MinD) out.writeInt(x);
|
||||
for (int x : S1MaxD) out.writeInt(x);
|
||||
for (int x : S1TH) out.writeInt(x);
|
||||
out.writeUTF(El1Mode);
|
||||
out.writeUTF(El1Type);
|
||||
for (int x : El1Pct) out.writeInt(x);
|
||||
for (int x : El1MinD) out.writeInt(x);
|
||||
for (int x : El1MaxD) out.writeInt(x);
|
||||
for (int x : El1Dur) out.writeInt(x);
|
||||
out.writeUTF(El2Mode);
|
||||
out.writeUTF(El2Type);
|
||||
for (int x : El2Pct) out.writeInt(x);
|
||||
for (int x : El2MinD) out.writeInt(x);
|
||||
for (int x : El2MaxD) out.writeInt(x);
|
||||
for (int x : El2Dur) out.writeInt(x);
|
||||
out.writeUTF(El3Mode);
|
||||
out.writeUTF(El3Type);
|
||||
for (int x : El3Pct) out.writeInt(x);
|
||||
for (int x : El3MinD) out.writeInt(x);
|
||||
for (int x : El3MaxD) out.writeInt(x);
|
||||
for (int x : El3Dur) out.writeInt(x);
|
||||
for (String x : TreasureClass1) out.writeUTF(x);
|
||||
for (String x : TreasureClass2) out.writeUTF(x);
|
||||
for (String x : TreasureClass3) out.writeUTF(x);
|
||||
for (String x : TreasureClass4) out.writeUTF(x);
|
||||
out.writeInt(TCQuestId);
|
||||
out.writeInt(TCQuestCP);
|
||||
out.writeInt(SplEndDeath);
|
||||
out.writeBoolean(SplGetModeChart);
|
||||
out.writeBoolean(SplEndGeneric);
|
||||
out.writeBoolean(SplClientEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,4 +12,8 @@ public class ClassUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasAnnotation(Class c, Class annotationClass) {
|
||||
return c.getAnnotation(annotationClass) != null;
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.badlogic.gdx.assets.AssetDescriptor;
|
||||
import com.badlogic.gdx.assets.AssetManager;
|
||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.OrthographicCamera;
|
||||
@ -100,8 +101,8 @@ public class DS1Viewer extends ApplicationAdapter {
|
||||
Riiablo.cofs = new COFs(assets);
|
||||
//COFD2.loadFromFile(resolver.resolve("data\\global\\cmncof_a1.d2"));
|
||||
|
||||
TXT txt = TXT.loadFromFile(Gdx.files.local("data/ds1types.txt"));
|
||||
DS1Types = Excel.parse(txt, com.riiablo.map.DS1Types.class);
|
||||
FileHandle txt = Gdx.files.local("data/ds1types.txt");
|
||||
DS1Types = Excel.load(com.riiablo.map.DS1Types.class, txt);
|
||||
|
||||
VisUI.load();
|
||||
|
||||
|
98
tools/src/com/riiablo/codec/excel/BinGenerationTool.java
Normal file
98
tools/src/com/riiablo/codec/excel/BinGenerationTool.java
Normal file
@ -0,0 +1,98 @@
|
||||
package com.riiablo.codec.excel;
|
||||
|
||||
import com.google.common.io.LittleEndianDataInputStream;
|
||||
import com.google.common.io.LittleEndianDataOutputStream;
|
||||
|
||||
import com.badlogic.gdx.ApplicationAdapter;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.backends.headless.HeadlessApplication;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||
import com.badlogic.gdx.utils.StreamUtils;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BinGenerationTool extends ApplicationAdapter {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new HeadlessApplication(new BinGenerationTool(args));
|
||||
}
|
||||
|
||||
final String[] args;
|
||||
|
||||
BinGenerationTool(String[] args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
try {
|
||||
generate(args[0], args[1]);
|
||||
} catch (Throwable t) {
|
||||
throw new GdxRuntimeException(t);
|
||||
}
|
||||
|
||||
Gdx.app.exit();
|
||||
}
|
||||
|
||||
public void generate(String fileName, String className) throws Exception {
|
||||
Class<Excel> excelClass = (Class<Excel>) Class.forName(className);
|
||||
if (!Excel.isBinned(excelClass)) {
|
||||
System.out.println(excelClass + " is not annotated with " + Excel.Binned.class);
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(fileName);
|
||||
//InputStream in = FileUtils.openInputStream(file);
|
||||
//TXT txt = TXT.loadFromStream(in);
|
||||
FileHandle txt = new FileHandle(file);
|
||||
|
||||
Excel excel = Excel.load(excelClass, txt, null, Excel.EXPANSION);
|
||||
|
||||
String binFileName = generateBinName(fileName);
|
||||
File binFile = new File(binFileName);
|
||||
OutputStream out = FileUtils.openOutputStream(binFile);
|
||||
BufferedOutputStream buffer = new BufferedOutputStream(out);
|
||||
LittleEndianDataOutputStream dos = null;
|
||||
try {
|
||||
dos = new LittleEndianDataOutputStream(buffer);
|
||||
excel.writeBin(dos);
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(dos);
|
||||
}
|
||||
|
||||
InputStream in = FileUtils.openInputStream(binFile);
|
||||
BufferedInputStream bufferIn = new BufferedInputStream(in);
|
||||
LittleEndianDataInputStream dis = null;
|
||||
try {
|
||||
dis = new LittleEndianDataInputStream(bufferIn);
|
||||
Excel copy = excelClass.newInstance();
|
||||
copy.readBin(dis);
|
||||
} finally {
|
||||
StreamUtils.closeQuietly(dis);
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateBinName(String fileName) {
|
||||
return FilenameUtils.getPath(fileName) + FilenameUtils.getBaseName(fileName) + ".bin";
|
||||
}
|
||||
|
||||
private static Method getMethod(Class clazz, Class annotation) {
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.getAnnotation(annotation) != null) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
65
tools/src/com/riiablo/codec/excel/ExcelGenerationTool.java
Normal file
65
tools/src/com/riiablo/codec/excel/ExcelGenerationTool.java
Normal file
@ -0,0 +1,65 @@
|
||||
package com.riiablo.codec.excel;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ExcelGenerationTool {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (String arg : args) {
|
||||
generate(arg + "$Entry");
|
||||
}
|
||||
}
|
||||
|
||||
public static void generate(String _package) throws Exception {
|
||||
Class clazz = Class.forName(_package);
|
||||
Field[] fields = clazz.getFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
Class type = field.getType();
|
||||
if (type.isArray()) {
|
||||
type = type.getComponentType();
|
||||
System.out.printf("for (%s x : %s) out.write%s(x);%n", type.getSimpleName(), field.getName(), getMethod(field));
|
||||
} else {
|
||||
System.out.printf("out.write%s(%s);%n", getMethod(field), field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("-----------------------------------");
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
Excel.Entry.Column column = field.getAnnotation(Excel.Entry.Column.class);
|
||||
Class type = field.getType();
|
||||
if (type.isArray()) {
|
||||
type = type.getComponentType();
|
||||
System.out.printf("%s = new %s[%d];%n", field.getName(), type.getSimpleName(), column.endIndex() - column.startIndex());
|
||||
System.out.printf("for (int x = %d; x < %d; x++) %s[x] = in.read%s();%n", column.startIndex(), column.endIndex(), field.getName(), getMethod(field));
|
||||
} else {
|
||||
System.out.printf("%s = in.read%s();%n", field.getName(), getMethod(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMethod(Field field) {
|
||||
Class type = field.getType();
|
||||
if (type.isArray()) {
|
||||
type = type.getComponentType();
|
||||
}
|
||||
|
||||
if (type == String.class) {
|
||||
return "UTF";
|
||||
} else if (type == byte.class) {
|
||||
return "Byte";
|
||||
} else if (type == short.class) {
|
||||
return "Short";
|
||||
} else if (type == int.class) {
|
||||
return "Int";
|
||||
} else if (type == long.class) {
|
||||
return "Long";
|
||||
} else if (type == boolean.class) {
|
||||
return "Boolean";
|
||||
} else {
|
||||
throw new UnsupportedOperationException("No support for " + type + " fields");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user