Updated ServerFactory to allow parsing of tab-deliminated Server Datatable Files (.sdf txt files) to Interchangeable File Format for source control diff viewing instead of using binary files

An IFF is created for the corresponding SDF if: one does not exist or the SDF's modify date is > than the IFF's modify date
This commit is contained in:
Waverunner
2015-07-20 12:42:41 -04:00
parent 9763777731
commit e225aa8727
11 changed files with 454 additions and 10 deletions

1
.gitignore vendored
View File

@@ -2,5 +2,6 @@
/clientdata
/.settings
/odb
/serverdata/**/*.iff
packets.txt
log.txt

Binary file not shown.

View File

@@ -0,0 +1,107 @@
Template Name Category Subcategory Type Flag
s s s[unknown] s I[0] I[0]
object/building/tatooine/cloning_facility_tatooine.iff cloningfacility
object/building/tatooine/cloning_facility_tatooine_small.iff cloningfacility
object/building/tatooine/bank_tatooine.iff bank
object/building/naboo/bank_naboo.iff bank
object/building/corellia/bank_corellia.iff bank
object/building/tatooine/cantina_tatooine.iff cantina 1
object/building/tatooine/capitol_tatooine.iff capitol
object/building/tatooine/guild_combat_tatooine_style_01.iff guild guild_combat
object/building/tatooine/guild_commerce_tatooine_style_01.iff guild guild_commerce
object/building/tatooine/guild_theater_tatooine_style_01.iff guild guild_theater 1
object/building/tatooine/guild_university_tatooine_style_01.iff guild guild_university
object/building/tatooine/hospital_tatooine_style01.iff medicalcenter 1
object/building/tatooine/hospital_tatooine_style02.iff medicalcenter 1
object/building/tatooine/hotel_tatooine_style_01.iff hotel
object/building/tatooine/hotel_tatooine_general.iff hotel
object/building/tatooine/junkshop_watto.iff @map_loc_n:junkshop_watto junkshop
object/building/tatooine/lucky_despot.iff @map_loc_n:lucky_despot cantina 1
object/building/tatooine/shuttleport_tatooine.iff shuttleport
object/building/tatooine/starport_tatooine.iff starport
object/building/corellia/cantina_corellia.iff cantina 1
object/building/corellia/cloning_corellia.iff cloningfacility
object/building/corellia/guild_combat_corellia_style_01.iff guild guild_combat
object/building/corellia/guild_commerce_corellia_style_01.iff guild guild_commerce
object/building/corellia/guild_theater_corellia_s01.iff guild guild_theater 1
object/building/corellia/guild_university_corellia_style_01.iff guild guild_university
object/building/corellia/hospital_corellia.iff medicalcenter 1
object/building/corellia/hospital_corellia_s02.iff medicalcenter 1
object/building/corellia/hotel_corellia.iff hotel
object/building/corellia/shuttleport_corellia.iff shuttleport
object/building/corellia/starport_corellia.iff starport
object/building/naboo/cantina_naboo.iff cantina 1
object/building/naboo/capitol_naboo_theed.iff capitol
object/building/naboo/cloning_facility_naboo.iff cloningfacility
object/building/naboo/guild_combat_naboo_style_01.iff guild guild_combat
object/building/naboo/guild_commerce_naboo_style_01.iff guild guild_commerce
object/building/naboo/guild_theater_naboo_s01.iff guild guild_theater 1
object/building/naboo/guild_university_naboo_style_01.iff guild guild_university
object/building/naboo/hangar_naboo_theed.iff starport
object/building/naboo/hospital_naboo_style01.iff medicalcenter 1
object/building/naboo/hospital_naboo_style02.iff medicalcenter 1
object/building/naboo/hotel_naboo_theed.iff hotel
object/building/naboo/palace_naboo_theed.iff @map_loc_n:theed_palace capitol
object/building/naboo/shuttleport_naboo.iff shuttleport
object/building/naboo/starport_naboo.iff starport
object/building/military/outpost_cloning_facility.iff cloningfacility
object/building/military/outpost_cloning_facility_s02.iff cloningfacility
object/building/military/outpost_cloning_facility_s03.iff cloningfacility
object/building/military/outpost_starport.iff starport
object/building/military/small_imperial_cloning_facility.iff cloningfacility
object/building/military/small_imperial_cloning_facility_s02.iff cloningfacility
object/building/corellia/capitol_corellia.iff capitol
object/building/poi/scout_camp_s4.iff camp 1
object/building/poi/scout_camp_s5.iff camp 1
object/building/player/city/cloning_naboo.iff cloningfacility
object/building/player/city/cloning_corellia.iff cloningfacility
object/building/player/city/cloning_tatooine.iff cloningfacility
object/building/player/city/hospital_naboo.iff medicalcenter
object/building/player/city/hospital_corellia.iff medicalcenter
object/building/player/city/hospital_tatooine.iff medicalcenter
object/building/player/city/cityhall_tatooine.iff city
object/building/player/city/cityhall_naboo.iff city
object/building/player/city/cityhall_corellia.iff city
object/building/player/city/theater_tatooine.iff theater
object/building/player/city/theater_naboo.iff theater
object/building/player/city/theater_corellia.iff theater
object/building/player/city/shuttleport_tatooine.iff shuttleport
object/building/player/city/shuttleport_naboo.iff shuttleport
object/building/player/city/shuttleport_corellia.iff shuttleport
object/building/player/city/bank_corellia.iff bank
object/building/player/city/bank_tatooine.iff bank
object/building/player/city/bank_naboo.iff bank
object/building/player/city/cantina_tatooine.iff cantina
object/building/player/city/cantina_naboo.iff cantina
object/building/player/city/cantina_corellia.iff cantina
object/building/corellia/garage_corellia.iff garage
object/building/naboo/parking_garage_naboo_style_1.iff garage
object/building/tatooine/parking_garage_tatooine_style_1.iff garage
object/building/player/player_garage_tatooine_style_01.iff garage
object/building/player/player_garage_corellia_style_01.iff garage
object/building/player/player_garage_naboo_style_01.iff garage
object/building/tatooine/salon_tatooine.iff salon
object/building/corellia/salon_corellia.iff salon
object/building/naboo/salon_naboo.iff salon
object/building/faction_perk/hq/hq_s01_rebel_pvp.iff rebel sf_rebel_forward_base 1
object/building/faction_perk/hq/hq_s01_imp_pvp.iff imperial sf_imperial_forward_base 1
object/building/faction_perk/hq/hq_s02_rebel_pvp.iff rebel sf_rebel_minor_base 1
object/building/faction_perk/hq/hq_s02_imp_pvp.iff imperial sf_imperial_minor_base 1
object/building/faction_perk/hq/hq_s03_rebel_pvp.iff rebel sf_rebel_major_base 1
object/building/faction_perk/hq/hq_s03_imp_pvp.iff imperial sf_imperial_major_base 1
object/building/faction_perk/hq/hq_s04_rebel_pvp.iff rebel sf_rebel_hq 1
object/building/faction_perk/hq/hq_s04_imp_pvp.iff imperial sf_imperial_hq 1
object/building/faction_perk/hq/hq_s05_rebel_pvp.iff rebel sf_rebel_hq 1
object/building/faction_perk/hq/hq_s05_imp_pvp.iff imperial sf_imperial_hq 1
object/building/faction_perk/hq/hq_s04_rebel.iff rebel rebel_hq
object/building/faction_perk/hq/hq_s04_imp.iff imperial imperial_hq
object/building/faction_perk/hq/hq_s05_rebel.iff rebel rebel_hq
object/building/faction_perk/hq/hq_s05_imp.iff imperial imperial_hq
object/building/kashyyyk/mun_kachirho_starport.iff starport
object/building/mustafar/structures/must_new_mining_facility.iff cantina
object/building/mustafar/structures/must_mining_cantina_marker.iff starport
object/building/mustafar/structures/must_mining_clone_marker.iff cloningfacility
object/building/naboo/rori_restuss_starport.iff starport
object/building/naboo/rori_restuss_shuttleport.iff shuttleport
object/building/dathomir/dathomir_quarantine_zone_starport.iff starport
object/building/dathomir/dathomir_quarantine_zone_cantina.iff cantina

View File

@@ -0,0 +1,37 @@
planet city x z
s s f f
tatooine Mos Eisley 3528 -4804
tatooine Bestine -1290 -3590
tatooine Mos Espa -2902 2130
tatooine Mos Entha 1291 3138
tatooine Wayfar -5124 -6530
tatooine Anchorhead 40 -5348
tatooine Mos Taike 3813 2354
corellia Coronet -178 -4504
corellia Tyrena -5140 -2450
corellia Bela Vistal 6766 -5692
corellia Kor Vella -3420 3146
corellia Doaba Guerfel 3274 5582
corellia Vreni Island -5538 -6176
naboo Theed -5488 4380
naboo Keren 1888 2700
naboo Moenia 4836 -4830.5
naboo Dee'ja Peak 4686 -1375
naboo Kaddara 5288 6687
rori Narmle -5140 -2368
rori Restuss 5318 5680
rori Rebel Outpost 3677 -6447
endor Research Outpost 3222 -3467
endor Smuggler Outpost -898 1587
talus Dearic 422 -3004
talus Nashal 4163 5220
yavin4 Mining Outpost -312 4865
yavin4 Labor Outpost -6925 -5707
dantooine Mining Outpost -640 2486
dantooine Pirate Outpost 1588 -6399
dantooine Imperial Outpost -4224 -2400
dathomir Trade Outpost 599 3071
dathomir Quarentine Zone -6358 930
dathomir Science Outpost -85 -1600
lok Nym's Stronghold 440 5029
lok Imperial Outpost -1920 -3084

View File

@@ -27,21 +27,14 @@
package resources.client_info;
import utilities.ByteUtilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* Created by Waverunner on 6/9/2015
*/
public abstract class DataFactory {
// readFile only called if dataMap doesn't contain the file as a key or it's value is null
protected ClientData readFile(String file) {
if (file == null || file.isEmpty()) {
System.err.println("File cannot be null or empty!");
@@ -64,6 +57,27 @@ public abstract class DataFactory {
return clientData;
}
protected File writeFile(SWGFile swgFile, ClientData data) {
if (swgFile == null || data == null) {
System.err.println("File or data objects cannot be null or empty!");
return null;
}
File save = new File(swgFile.getFileName());
data.writeIff(swgFile);
try {
swgFile.save(save);
} catch (IOException e) {
e.printStackTrace();
}
return save;
}
protected abstract ClientData createDataObject(String type);
protected ClientData createDataObject(SWGFile swgFile) {
return createDataObject(swgFile.getType());
}
protected abstract String getFolder();
}

View File

@@ -67,26 +67,46 @@ public class IffNode {
return bb.get();
}
public void writeByte(byte val) {
bb.order(ByteOrder.LITTLE_ENDIAN).put(val);
}
public short readShort() {
initBuffer();
return bb.order(ByteOrder.LITTLE_ENDIAN).getShort();
}
public void writeShort(short val) {
bb.order(ByteOrder.LITTLE_ENDIAN).putShort(val);
}
public int readInt() {
initBuffer();
return bb.order(ByteOrder.LITTLE_ENDIAN).getInt();
}
public void writeInt(int val) {
bb.order(ByteOrder.LITTLE_ENDIAN).putInt(val);
}
public float readFloat() {
initBuffer();
return bb.getFloat();
}
public void writeFloat(float val) {
bb.putFloat(val);
}
public long readLong() {
initBuffer();
return bb.order(ByteOrder.LITTLE_ENDIAN).getLong();
}
public void writeLong(long val) {
bb.order(ByteOrder.LITTLE_ENDIAN).putLong(val);
}
public int readUInt() {
initBuffer();
return bb.order(ByteOrder.BIG_ENDIAN).getInt();
@@ -119,6 +139,11 @@ public class IffNode {
return string;
}
public void writeString(String s) {
bb.put(s.getBytes(Charset.forName("US-ASCII")));
writeByte((byte) 0);
}
public void readChunk(ChunkReader reader) {
initBuffer();
while(bb.hasRemaining()) {
@@ -198,6 +223,14 @@ public class IffNode {
if (bb == null) bb = ByteBuffer.wrap(getChunkData());
}
public void initWriteBuffer(int size) {
bb = ByteBuffer.allocate(size);
}
public void updateChunk() {
chunkData = bb.array();
}
private byte[] createForm() {
List<byte[]> childrenData = new ArrayList<>();
int size = 0;

View File

@@ -45,6 +45,11 @@ public class SWGFile {
public SWGFile() {}
public SWGFile(String fileName, String type) {
this(type);
this.fileName = fileName;
}
public SWGFile(String type) {
this.type = type;
this.master = new IffNode(type, true);

View File

@@ -29,6 +29,17 @@ package resources.client_info;
import resources.client_info.visitors.DatatableData;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Created by Waverunner on 6/9/2015
@@ -42,6 +53,138 @@ public final class ServerFactory extends DataFactory {
return (data != null ? (DatatableData) data : null);
}
public void updateServerIffs() throws IOException {
File root = new File(getFolder());
Files.walkFileTree(root.toPath(), new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
if (path.toString().endsWith("sdf")) {
String name = path.toString();
name = name.substring(0, name.length() - 4) + ".iff";
File iff = new File(name);
if (!iff.exists()) {
convertSif(path, name);
System.out.println("Created Server Datatable: " + name);
} else {
File sif = path.toFile();
if (sif.lastModified() > iff.lastModified()) {
convertSif(path, name);
System.out.println("Updated Server Datatable: " + name);
}
}
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path path, IOException e) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path path, IOException e) throws IOException {
return FileVisitResult.CONTINUE;
}
});
}
private void convertSif(Path sif, String newPath) {
SWGFile swgFile = new SWGFile(newPath, "DTII");
DatatableData data = (DatatableData) createDataObject(swgFile);
String[] columnTypes = null;
String[] columnNames = null;
Object[][] table = null;
List<String> defaultValues = new ArrayList<>();
try {
int lineNum = -1;
List<String> rows = Files.readAllLines(sif);
Iterator<String> itr = rows.iterator();
while (itr.hasNext()) {
String row = itr.next();
if (row == null || row.isEmpty() || row.startsWith("#") || row.startsWith("//")) {
itr.remove();
continue;
}
// Don't break out of the loop, make sure we remove all the commented/null/empty rows
if (!(lineNum <= 1))
continue;
lineNum++;
if (lineNum == 0) {
columnNames = row.split("\t");
} else if (lineNum == 1) {
columnTypes = row.split("\t");
for (int i = 0; i < columnTypes.length; i++) {
String columnType = columnTypes[i];
if (columnType.contains("[")) {
String[] split = columnType.split("\\[");
columnTypes[i] = split[0].toLowerCase();
defaultValues.add(split[1].replace("]", ""));
} else {
columnTypes[i] = columnType.toLowerCase();
defaultValues.add("");
}
}
}
itr.remove();
}
if (columnNames == null || columnTypes == null) {
System.err.println("Failed to convert sif " + sif.getFileName());
return;
}
table = new Object[rows.size()][columnTypes.length];
for (int i = 0; i < rows.size(); i++) {
createDatatableRow(i, rows.get(i), columnTypes, table, defaultValues);
}
} catch (IOException e) {
e.printStackTrace();
}
data.setColumnNames(columnNames);
data.setColumnTypes(columnTypes);
data.setTable(table);
writeFile(swgFile, data);
}
private void createDatatableRow(int rowNum, String line, String[] columnTypes, Object[][] table, List<String> defValues) {
String[] values = line.split("\t", -1);
for (int t = 0; t < columnTypes.length; t++) {
String type = columnTypes[t];
String val = values[t];
if (val.isEmpty() && !defValues.get(t).isEmpty())
val = defValues.get(t);
switch(type) {
case "b": table[rowNum][t] = Boolean.valueOf(val); break;
case "h":
case "i": table[rowNum][t] = Integer.valueOf(val); break;
case "f": table[rowNum][t] = Float.valueOf(val); break;
case "s": table[rowNum][t] = val; break;
default: System.err.println("Don't know how to parse type " + type); break;
}
}
}
@Override
protected ClientData createDataObject(String type) {
switch(type) {
@@ -55,7 +198,7 @@ public final class ServerFactory extends DataFactory {
return "./serverdata/";
}
private static ServerFactory getInstance() {
public static ServerFactory getInstance() {
if (instance == null)
instance = new ServerFactory();
return instance;

View File

@@ -62,6 +62,79 @@ public class DatatableData extends ClientData {
}
}
@Override
public void writeIff(SWGFile iff) {
iff.addForm("0001");
writeColumns(iff.addChunk("COLS"));
writeTypes(iff.addChunk("TYPE"));
writeRows(iff.addChunk("ROWS"));
}
private void writeColumns(IffNode chunk) {
int size = getTableStringSize(columnNames);
chunk.initWriteBuffer(size + 4);
chunk.writeInt(columnNames.length);
for (String columnName : columnNames) {
chunk.writeString(columnName);
}
chunk.updateChunk();
}
private void writeTypes(IffNode chunk) {
int size = getTableStringSize(columnTypes);
chunk.initWriteBuffer(size);
for (String columnType : columnTypes) {
chunk.writeString(columnType);
}
chunk.updateChunk();
}
private void writeRows(IffNode chunk) {
int size = 0;
int rows = table.length;
for (int i = 0; i < columnTypes.length; i++) {
String type = columnTypes[i];
switch(type) {
case "b":
case "f":
case "h":
case "i": size += 4 * rows; break;
case "s": {
for (int r = 0; r < rows; r++) {
size += ((String) table[r][i]).length() + 1;
}
break;
}
default: System.err.println("Cannot write row type " + type);
}
}
chunk.initWriteBuffer(size + 4);
chunk.writeInt(rows);
for (int r = 0; r < rows; r++) {
for (int t = 0; t < columnTypes.length; t++) {
String type = columnTypes[t];
switch(type) {
case "b":
case "h":
case "i": chunk.writeInt((Integer) table[r][t]); break;
case "f": chunk.writeFloat((Float) table[r][t]); break;
case "s": chunk.writeString((String) table[r][t]); break;
default: System.err.println("Cannot write datatable to type " + type);
}
}
}
chunk.updateChunk();
}
private void parseTypes(IffNode chunk) {
columnTypes = new String[columnNames.length];
@@ -190,4 +263,23 @@ public class DatatableData extends ClientData {
return columnTypes[column];
}
public void setColumnNames(String[] columnNames) {
this.columnNames = columnNames;
}
public void setColumnTypes(String[] columnTypes) {
this.columnTypes = columnTypes;
}
public void setTable(Object[][] table) {
this.table = table;
}
private int getTableStringSize(String[] table) {
int size = 0;
for (String s : table) {
size += s.length() + 1;
}
return size;
}
}

View File

@@ -28,8 +28,10 @@
package services;
import java.io.File;
import java.io.IOException;
import resources.Galaxy;
import resources.client_info.ServerFactory;
import resources.config.ConfigFile;
import resources.control.Manager;
import resources.server_info.Config;
@@ -46,6 +48,8 @@ public class EngineManager extends Manager {
addChildService(networkManager);
addChildService(shutdownService);
initializeServerFactory();
}
@Override
@@ -56,7 +60,7 @@ public class EngineManager extends Manager {
wipeCharacterDatabase();
if (config.getInt("WIPE-ODB-FILES", 0) == 1)
wipeOdbFiles();
return super.initialize();
}
@@ -73,5 +77,13 @@ public class EngineManager extends Manager {
}
}
}
private void initializeServerFactory() {
try {
ServerFactory.getInstance().updateServerIffs();
} catch (IOException e) {
e.printStackTrace();
}
}
}