Files
CustomNPC-Plus/src/main/java/noppes/npcs/util/NBTJsonUtil.java
T

323 lines
8.2 KiB
Java
Raw Normal View History

2018-09-13 12:03:28 -04:00
package noppes.npcs.util;
2023-01-12 21:33:06 -05:00
import com.google.common.io.Files;
import cpw.mods.fml.common.ObfuscationReflectionHelper;
import net.minecraft.nbt.*;
import noppes.npcs.LogWriter;
2023-01-12 21:33:06 -05:00
import org.apache.commons.io.Charsets;
import java.io.*;
2018-09-13 12:03:28 -04:00
import java.util.ArrayList;
import java.util.List;
public class NBTJsonUtil {
public static String Convert(NBTTagCompound compound){
List<JsonLine> list = new ArrayList<JsonLine>();
JsonLine line = ReadTag("", compound, list);
line.removeComma();
return ConvertList(list);
}
public static NBTTagCompound Convert(String json) throws JsonException{
json = json.trim();
JsonFile file = new JsonFile(json);
if(!json.startsWith("{") || !json.endsWith("}"))
2023-06-01 22:48:22 -05:00
throw new JsonException("Not properly incapsulated between { }", file);
2018-09-13 12:03:28 -04:00
NBTTagCompound compound = new NBTTagCompound();
FillCompound(compound, file);
return compound;
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public static void FillCompound(NBTTagCompound compound, JsonFile json) throws JsonException{
if(json.startsWith("{") || json.startsWith(","))
json.cut(1);
if(json.startsWith("}"))
return;
2023-06-01 20:34:25 -04:00
int index = json.indexOf(":");
2018-09-13 12:03:28 -04:00
if(index < 1)
throw new JsonException("Expected key after ," ,json);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
String key = json.substring(0, index);
json.cut(index + 1);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
NBTBase base = ReadValue(json);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
if(base == null)
base = new NBTTagString();
if(key.startsWith("\""))
key = key.substring(1);
if(key.endsWith("\""))
key = key.substring(0, key.length() - 1);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
compound.setTag(key, base);
if(json.startsWith(","))
FillCompound(compound, json);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public static NBTBase ReadValue(JsonFile json) throws JsonException{
if(json.startsWith("{")){
NBTTagCompound compound = new NBTTagCompound();
FillCompound(compound, json);
if(!json.startsWith("}")){
throw new JsonException("Expected }", json);
}
json.cut(1);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
return compound;
}
if(json.startsWith("[")){
json.cut(1);
NBTTagList list = new NBTTagList();
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
NBTBase value = ReadValue(json);
while(value != null){
list.appendTag(value);
if(!json.startsWith(","))
break;
json.cut(1);
value = ReadValue(json);
}
if(!json.startsWith("]")){
throw new JsonException("Expected ]", json);
}
json.cut(1);
if(list.func_150303_d() == 3){
int[] arr = new int[list.tagCount()];
for(int i = 0; list.tagCount() > 0 ; i++){
arr[i] = ((NBTTagInt)list.removeTag(0)).func_150287_d();
}
return new NBTTagIntArray(arr);
}
if(list.func_150303_d() == 1){
byte[] arr = new byte[list.tagCount()];
for(int i = 0; list.tagCount() > 0 ; i++){
arr[i] = ((NBTTagByte)list.removeTag(0)).func_150290_f();
}
return new NBTTagByteArray(arr);
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
return list;
}
if(json.startsWith("\"")){
json.cut(1);
String s = "";
boolean ignore = false;
while(!json.startsWith("\"") || ignore){
String cut = json.cutDirty(1);
ignore = cut.equals("\\");
s += cut;
}
json.cut(1);
return new NBTTagString(s.replace("\\\"", "\""));
}
String s = "";
while(!json.startsWith(",", "]", "}")){
s += json.cut(1);
}
s = s.trim().toLowerCase();
2023-01-09 13:57:14 -05:00
if(s.isEmpty() || s.contains("bytes]"))
2018-09-13 12:03:28 -04:00
return null;
try{
if(s.endsWith("d")){
return new NBTTagDouble(Double.parseDouble(s.substring(0, s.length() - 1)));
}
if(s.endsWith("f")){
return new NBTTagFloat(Float.parseFloat(s.substring(0, s.length() - 1)));
}
if(s.endsWith("b")){
return new NBTTagByte(Byte.parseByte(s.substring(0, s.length() - 1)));
}
if(s.endsWith("s")){
return new NBTTagShort(Short.parseShort(s.substring(0, s.length() - 1)));
}
if(s.endsWith("l")){
return new NBTTagLong(Long.parseLong(s.substring(0, s.length() - 1)));
}
if(s.contains("."))
return new NBTTagDouble(Double.parseDouble(s));
else
return new NBTTagInt(Integer.parseInt(s));
}
catch(NumberFormatException ex){
throw new JsonException("Unable to convert: "+ s +" to a number", json);
}
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
private static List<NBTBase> getListData(NBTTagList list){
return ObfuscationReflectionHelper.getPrivateValue(NBTTagList.class, list, 0);
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
private static JsonLine ReadTag(String name, NBTBase base, List<JsonLine> list){
if(!name.isEmpty())
name = "\"" + name + "\": ";
2023-06-01 22:48:22 -05:00
if(base.getId() == 8){//NBTTagString
2018-09-13 12:03:28 -04:00
String data = ((NBTTagString)base).func_150285_a_();
data = data.replace("\"", "\\\""); //replace " with \"
list.add(new JsonLine(name + "\"" + data + "\""));
}
else if(base.getId() == 9){//NBTTagList
list.add(new JsonLine(name + "["));
NBTTagList tags = (NBTTagList) base;
JsonLine line = null;
List<NBTBase> data = getListData(tags);
for(NBTBase b : data)
line = ReadTag("", b, list);
if(line != null)
line.removeComma();
list.add(new JsonLine("]"));
}
else if(base.getId() == 10){ //NBTTagCompound
list.add(new JsonLine(name + "{"));
NBTTagCompound compound = (NBTTagCompound)base;
JsonLine line = null;
for(Object key : compound.func_150296_c())
line = ReadTag(key.toString(), compound.getTag(key.toString()), list);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
if(line != null)
line.removeComma();
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
list.add(new JsonLine("}"));
}
else if(base.getId() == 11){//NBTTagList
list.add(new JsonLine(name + base.toString().replaceFirst(",]", "]")));
}
else{
list.add(new JsonLine(name + base));
}
JsonLine line = list.get(list.size() - 1);
line.line += ",";
return line;
}
private static String ConvertList(List<JsonLine> list) {
String json = "";
int tab = 0;
for(JsonLine tag : list){
if(tag.reduceTab())
tab--;
for(int i = 0; i < tab; i++){
json += " ";
}
json += tag + "\n";
if(tag.increaseTab())
tab++;
}
return json;
}
public static NBTTagCompound loadNBTData(File file){
try {
return CompressedStreamTools.readCompressed(new FileInputStream(file));
} catch (Exception e) {
LogWriter.error("Error loading: " + file.getName(), e);
}
return new NBTTagCompound();
}
static class JsonLine{
2018-09-13 12:03:28 -04:00
private String line;
public JsonLine(String line){
this.line = line;
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public void removeComma(){
if(line.endsWith(","))
line = line.substring(0, line.length() - 1);
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public boolean reduceTab(){
int length = line.length();
return length == 1 && (line.endsWith("}") || line.endsWith("]"))
2023-06-01 22:48:22 -05:00
|| length == 2 && (line.endsWith("},") ||line.endsWith("],"));
2018-09-13 12:03:28 -04:00
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public boolean increaseTab(){
return line.endsWith("{") || line.endsWith("[");
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
@Override
public String toString(){
return line;
}
}
static class JsonFile{
private String original;
private String text;
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public JsonFile(String text){
this.text = text;
this.original = text;
}
public String cutDirty(int i) {
String s = text.substring(0, i);
text = text.substring(i);
return s;
}
public String cut(int i) {
String s = text.substring(0, i);
text = text.substring(i).trim();
return s;
}
public String substring(int beginIndex, int endIndex) {
return text.substring(beginIndex, endIndex);
}
public int indexOf(String s) {
return text.indexOf(s);
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public String getCurrentPos(){
int lengthOr = original.length();
int lengthCur = text.length();
int currentPos = lengthOr - lengthCur;
String done = original.substring(0, currentPos);
String[] lines = done.split("\r\n|\r|\n");
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
int pos = 0;
String line = "";
if(lines.length > 0){
pos = lines[lines.length - 1].length();
line = original.split("\r\n|\r|\n")[lines.length - 1].trim();
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
return "Line: " + lines.length + ", Pos: " + pos + ", Text: " + line;
}
public boolean startsWith(String... ss) {
for(String s : ss)
if(text.startsWith(s))
return true;
return false;
}
public boolean endsWith(String s) {
return text.endsWith(s);
}
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public static NBTTagCompound LoadFile(File file) throws IOException, JsonException {
return Convert(Files.toString(file, Charsets.UTF_8));
}
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
public static void SaveFile(File file, NBTTagCompound compound) throws IOException, JsonException {
String json = Convert(compound);
OutputStreamWriter writer = null;
try{
writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
writer.write(json);
2023-06-01 22:48:22 -05:00
2018-09-13 12:03:28 -04:00
}
finally{
if(writer != null)
writer.close();
}
}
}