package org.black_ixx.bossshop.nbt;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.black_ixx.bossshop.BossShop;
import org.black_ixx.bossshop.core.BSShopManager;
import org.black_ixx.bossshop.mail.MailManager;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import cc.util.bossshop.ClassHelper;
import cc.util.bossshop.FBukkit;
import cc.util.bossshop.NMSHelper;
import cc.util.bossshop.config.CommentedSection;
import cc.util.bossshop.config.CommentedYamlConfig;
import cc.util.bossshop.filemanager.AFileManager;
import cc.util.bossshop.pluginmodel.INeedConfig;
import cc.util.bossshop.pluginmodel.INeedReload;

/**
 * NBT管理系统,用于NBT的创建,保存和恢复
 * @author 聪聪
 *
 */
public class NBTEditManager extends AFileManager implements INeedConfig,INeedReload{

    public static final String SEC_NBT_MAIN="NBTS";
    public static final String SEC_NBT_CONTENT="Content";
    public static final String SEC_AUTO_ADD="AutoAdd";
    public static final String SEC_LAST_USE_TIME="LastUseTime";
    /**
     * 用于NBT节点中名中＂.＂符号的替换
     */
    private static char re='$';
    private final HashMap<String,NBT> nbtmap=new HashMap<>();
    private int mExpiredDays=7;

    /**
     * 无初始化限制条件
     * @param plugin
     */
    public NBTEditManager(BossShop pplugin){
        super(pplugin,"nbt.yml","1.1");
        pplugin.registerConfigModel(this);
        pplugin.registerReloadModel(this);
    }
    
    @Override
    public void setConfig(){
        CommentedYamlConfig tConfig=this.mPlugin.getConfigManager().getConfig();
        this.mExpiredDays=tConfig.getInt("AutoClear.NBTExpiredDays",this.mExpiredDays);
        if(this.mExpiredDays<=0) this.mExpiredDays=Integer.MAX_VALUE;
    }
    
    /**
     * 切勿单独调用,防止NBT引用次数被重置
     */
    public boolean reloadConfig(){
        super.reloadConfig();
        this.checkUpdate();
        this.generateNBT();
        this.saveConfig();
        return true;
    }

    /**
     * 检查配置文件版本,用以更新配置文件
     * 当前更新范围 无版本->1.1
     */
    protected boolean checkUpdate(){
        boolean update=super.checkUpdate();
        if(!update) return false;
        String tversion=this.mConfig.getString(SEC_CFG_VERSION,"1.0");
        if(tversion.equalsIgnoreCase("1.0")){
            tversion="1.1";
            this.mConfig.set("index",null);
            if(tversion.compareToIgnoreCase("1.0")==0){
                ConfigurationSection sec=this.mConfig.getConfigurationSection(SEC_NBT_MAIN);
                if(sec!=null){
                    for(String label : sec.getKeys(false)){
                        ConfigurationSection nbtsec=sec.getConfigurationSection(label);
                        sec.set(label,null);
                        sec.set(label+"."+SEC_NBT_CONTENT,nbtsec);
                        sec.set(label+"."+SEC_AUTO_ADD,false);
                    }
                }
            }
        }
        this.mConfig.set(SEC_CFG_VERSION,this.mVersion);
        return true;
    }
    
    /**
     * 清理自动生成且引用次数为0的NBT节点
     * @return 清理的个数
     */
    public int clearNBT(){
        ConfigurationSection sec=this.mConfig.getConfigurationSection(SEC_NBT_MAIN);
        if(sec==null) return 0;
        
        //先检查商店和邮件是否在范围时间内引用了NBT,如果没有则重载来增加NBT最后引用时间
        MailManager mailMan=((BossShop)this.mPlugin).getManager(MailManager.class);
        if(System.currentTimeMillis()-mailMan.getLastReloadTime()>=this.mExpiredDays*86400000)
            mailMan.reloadConfig();
        BSShopManager shopMan=((BossShop)this.mPlugin).getManager(BSShopManager.class);
        if(System.currentTimeMillis()-shopMan.getLastReloadTime()>=this.mExpiredDays*86400000)
            shopMan.reloadConfig();
        
        int count=0;
        Iterator<Entry<String,NBT>> it=this.nbtmap.entrySet().iterator();
        while(it.hasNext()){
            Entry<String,NBT> entry=it.next();
            NBT nbt=entry.getValue();
            if(nbt.autoadd&&System.currentTimeMillis()-nbt.lastUseTime>this.mExpiredDays*86400000){
                sec.set(entry.getKey(),null);
                it.remove();
                count++;
            }
        }
        if(count>0){
            this.saveConfig();
            this.debug("NBT库清理函数被调用,共清理 " +count+" 个过期NBT");
        }
        return count;
    }
    
    /**
     * 添加物品的NBT到库存
     * @param item 要获取NBT的物品
     * @param auto 是否是自动添加的
     * @return 添加成功后存储在文件中的NBT节点名,如果物品没有nbt信息,将返回null
     */
    public String addItemNBTToStock(ItemStack item,boolean auto){
        Object tObj_NBTTagCompound_tag=NMSHelper.getNBTTagCompound(item);
        if(tObj_NBTTagCompound_tag==null) return null;
        Object tNBTTagCompound_tagClone=ClassHelper.invokeMethod(tObj_NBTTagCompound_tag,NMSHelper.clazz_NBTBase);    //克隆方法
        Map<String,Object> tagContent=NMSHelper.getNBTTagMapFromTag(tNBTTagCompound_tagClone);
        if(tagContent==null||tagContent.isEmpty())
            return null;
        NBT addNBT=this.getNBTByTag(tNBTTagCompound_tagClone);
        if(addNBT==null){
            long time=System.currentTimeMillis()/1000;
            String label=time+"_"+item.getType().name();
            while(this.mConfig.contains(label)){
                time++;
                label=time+"_"+item.getType().name();
            }
            addNBT=new NBT(label,tNBTTagCompound_tagClone,auto);
            this.nbtmap.put(label,addNBT);
        }
        this.updateNBTLastTime(addNBT);
        return addNBT.mLabel;
    }
    
    /**
     * 更新NBT最后引用时间(配置文件和自身实例)
     * <p>如果NBT配置节点不存在会自动创建</p>
     * @param pNBT 要更新的NBT
     */
    public void updateNBTLastTime(NBT pNBT){
        ConfigurationSection sec=this.mConfig.getConfigurationSection(SEC_NBT_MAIN);
        if(sec==null) sec=this.mConfig.createSection(SEC_NBT_MAIN);
        ConfigurationSection nsec=sec.getConfigurationSection(pNBT.mLabel);
        if(nsec==null){
            nsec=sec.createSection(pNBT.mLabel);
            nsec.set(SEC_AUTO_ADD,pNBT.autoadd);
            ConfigurationSection content_sec=nsec.createSection(SEC_NBT_CONTENT);
            this.putNBTToSection(content_sec,pNBT.nbt);
        }
        nsec.set(SEC_LAST_USE_TIME,System.currentTimeMillis());
        pNBT.lastUseTime=System.currentTimeMillis();
        this.saveConfig();
    }
    
    /**
     * 根据pItem来获取NBT类实例
     * @param pItem Bukkit物品
     * @return 找到的NBl类实例或null
     */
    public NBT getNBTByItem(ItemStack pItem){
        return this.getNBTByTag(NMSHelper.getNBTTagCompound(pItem));
    }
    
    /**
     * 根据NBTTagCompound来获取NBT类实例
     * @param pTag
     * @return 找到的NBT类实例或null
     */
    private NBT getNBTByTag(Object pTag){
        if(pTag==null) return null;
        for(NBT sNBT : this.nbtmap.values()){
            if(sNBT.nbt.equals(pTag)) return sNBT;
        }
        return null;
    }

    /**
     * 将NBT信息存储到配置文件指定的节点中
     */
    private void putNBTToSection(ConfigurationSection sec,Object tObj_NBTBase_nbt){
        if(NMSHelper.clazz_NBTTagCompound.isInstance(tObj_NBTBase_nbt)){
            Map<String,Object> nbtContents=NMSHelper.getNBTTagMapFromTag(tObj_NBTBase_nbt);
            for(Map.Entry<String,Object> entry : nbtContents.entrySet()){
                String cname=entry.getKey().replace('.',re);
                Object tObj_NBTBase_tnbt=entry.getValue();
                if(NMSHelper.clazz_NBTTagCompound.isInstance(tObj_NBTBase_tnbt)||NMSHelper.clazz_NBTTagList.isInstance(tObj_NBTBase_tnbt)){
                    ConfigurationSection nsec=sec.createSection(cname);
                    putNBTToSection(nsec,tObj_NBTBase_tnbt);
                }else sec.set(cname,this.getStringValue(tObj_NBTBase_tnbt));
            }
        }else if(NMSHelper.clazz_NBTTagList.isInstance(tObj_NBTBase_nbt)){
            List<Object> contentList=(List<Object>)ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagList_value);
            sec.set("_type_",9);
            int i=0;
            for(Object sNBTBase: contentList){
                String name=i+"";i++;
                if(NMSHelper.clazz_NBTTagCompound.isInstance(sNBTBase)||NMSHelper.clazz_NBTTagList.isInstance(sNBTBase)){
                    ConfigurationSection nsec=sec.createSection(name);
                    putNBTToSection(nsec,sNBTBase);
                }else{
                    String str=sNBTBase.toString();
                    if(NMSHelper.clazz_NBTTagString.isInstance(sNBTBase))
                        str=(String)ClassHelper.getFieldValue(sNBTBase,NMSHelper.field_NBTTagString_value);
                    sec.set(name,str);
                }
            }
            if(sec.getKeys(false).size()==1) sec.set("_type_",null);
        }else{
            warn("NBT Edit maybe make a bug");
        }
    }

    /**
     * 从配置文件中生成NBT
     */
    private void generateNBT(){
        this.nbtmap.clear();
        CommentedSection sec=this.mConfig.getConfigurationSection(SEC_NBT_MAIN);
        if(sec==null){
            sec=this.mConfig.createSection(SEC_NBT_MAIN);
            return ;
        }
        for(String label : sec.getKeys(false)){
            Object tObj_NBTTagCompound=ClassHelper.getInstance(NMSHelper.clazz_NBTTagCompound);
            CommentedSection nbtSec=sec.getConfigurationSection(label);
            if(label==null) continue;
            boolean auto=nbtSec.getBoolean(NBTEditManager.SEC_AUTO_ADD,false);
            CommentedSection contentSec=nbtSec.getConfigurationSection(NBTEditManager.SEC_NBT_CONTENT);
            if(contentSec==null){
                this.mPlugin.warn("NBT配置节点["+label+"]没有["+NBTEditManager.SEC_NBT_CONTENT+"]节点,这是一个配置错误");
                continue;
            }
            this.setTagContent(contentSec,tObj_NBTTagCompound);
            NBT cfgNBT=new NBT(label,tObj_NBTTagCompound,auto);
            cfgNBT.lastUseTime=nbtSec.getLong(NBTEditManager.SEC_LAST_USE_TIME,System.currentTimeMillis());;
            this.nbtmap.put(label,cfgNBT);
        }
    }

    /**
     * 使用该方法是必须接受返回结果
     * @param item 要设置nbt信息的物品
     * @param nbtLabel nbt标签,所有标签在数据文件夹下的nbt.yml中的NBTS节点下
     * @return 设置完nbt信息后的物品
     */
    public ItemStack setItemNBT(ItemStack item,String nbtLabel){
        NBT nbtcom=this.nbtmap.get(nbtLabel);
        if(nbtcom==null){
            if(StringUtils.isNotEmpty(nbtLabel))
                warn(C("Console.MissingNBTNode")+"["+nbtLabel+"]");
            return null;
        }
        this.updateNBTLastTime(nbtcom);
        ItemMeta meta=item.getItemMeta();
        List<String> lore_old=new ArrayList<String>();
        if(meta.hasLore()) lore_old.addAll(meta.getLore());
        Object tObj_NMSItemStack=ClassHelper.invokeStaticMethod(NMSHelper.method_CraftItemStack_asNMSCopy,item);
        if(tObj_NMSItemStack==null) return item;
        Object tObj_NBTTagCompound_tag=ClassHelper.getFieldValue(tObj_NMSItemStack,NMSHelper.field_NMSItemStack_tag);//获取物品tag
        if(tObj_NBTTagCompound_tag!=null){
            //清空原lore
            Map<String,Object> tagContent=NMSHelper.getNBTTagMapFromTag(tObj_NBTTagCompound_tag);
            Object tNBTTagCompound_display=tagContent.get("display");
            if(tNBTTagCompound_display!=null){
                Map<String,Object> tagDisplayContent=NMSHelper.getNBTTagMapFromTag(tNBTTagCompound_display);
                tagDisplayContent.remove("Lore");
            }
            this.mixNBT(tObj_NBTTagCompound_tag,nbtcom.nbt);
        }
        else{
            Object tNBTTagCompound_tagClone=ClassHelper.invokeMethod(nbtcom.nbt,NMSHelper.method_NBTTagCompound_clone);//克隆 nbt
            ClassHelper.setFieldValue(tObj_NMSItemStack,NMSHelper.field_NMSItemStack_tag,tNBTTagCompound_tagClone);//设置tag
        }
        ItemStack ritem=(ItemStack)ClassHelper.invokeStaticMethod(NMSHelper.method_CraftItemStack_asCraftMirror,tObj_NMSItemStack);
        meta=ritem.getItemMeta();
        List<String> lore_nbt=meta.getLore();
        if(lore_nbt==null) lore_nbt=new ArrayList<>();
        if(lore_old!=null) lore_nbt.addAll(lore_old);
        meta.setLore(lore_nbt);
        if(!FBukkit.isItemMetaEmpty(meta)){//防止空meta清空nbt
            ritem.setItemMeta(meta);
        }
        return ritem;
    }

    /**
     * 混合两个 NBTTagCompound,如果同时存在节点名相同但属性不同,优先保存前一个的数据
     */
    private void mixNBT(Object tObj_NBTTagCompound_to,Object tObj_NBTTagCompound_from){
        Object tNBTBase_toChild=null;
        Map<String,Object> tagFromContent=NMSHelper.getNBTTagMapFromTag(tObj_NBTTagCompound_from);//获取from com的map
        Map<String,Object> tagToContent=NMSHelper.getNBTTagMapFromTag(tObj_NBTTagCompound_to);//获取to com的map
        for(Object obj : tagFromContent.keySet()){
            String name=obj.toString();
            tNBTBase_toChild=tagToContent.get(name);  //尝试to com中是否有该节点
            Object tNBTBase_fromChild=tagFromContent.get(name); //获取from com中的该值
            if(tNBTBase_fromChild==null) continue;      //如果复制源为null就没必要继续了
            if(tNBTBase_toChild==null){                 //to com中不存在直接put
                tagToContent.put(name,tNBTBase_fromChild);
            }else{  //to com中存在,分类
                if(tNBTBase_toChild.getClass()==tNBTBase_fromChild.getClass()){//如果同是com
                    if(NMSHelper.clazz_NBTTagCompound.isInstance(tNBTBase_toChild))//如果是com,混合
                        mixNBT(tNBTBase_toChild,tNBTBase_fromChild);
                    else if(NMSHelper.clazz_NBTTagList.isInstance(tNBTBase_toChild)){//如果list,相加
                        List<Object> from_contentList=(List<Object>)ClassHelper.getFieldValue(tNBTBase_fromChild,NMSHelper.field_NBTTagList_value);//获取from taglist中的list
                        int tListSize=from_contentList.size();
                        for(int i=0;i<tListSize;i++){//将from中的内容放到to中
                            Object tNBTTagCompound_tb=from_contentList.get(i);//获取from list中的值
                            if(tNBTTagCompound_tb==null) continue;
                            ClassHelper.invokeMethod(tNBTBase_toChild,NMSHelper.method_NBTTagList_add,tNBTTagCompound_tb);
                        }
                    }else{//其他则直接覆盖
                        tagToContent.put(name,tNBTBase_fromChild);
                    }
                }else warn("same nbt node name exist of: "+name+",but they have different types,please check ");
            }
        }
    }

    /**
     * 将配置节点sec中的NBT信息放到tag中
     */
    private void setTagContent(CommentedSection sec,Object pObj_NBTBase){
        if(sec.getInt("_type_")==9&&NMSHelper.clazz_NBTTagList.isInstance(pObj_NBTBase)){// NBTTagList
            for(String n : sec.getKeys(false)){
                if(n.equalsIgnoreCase("_type_")) continue;
                Object value=sec.get(n);
                if(value instanceof String){
                    Object tObj_NBTBase_ntag=getNBTNode((String)value);
                    if(tObj_NBTBase_ntag!=null)
                        ClassHelper.invokeMethod(pObj_NBTBase,NMSHelper.method_NBTTagList_add,tObj_NBTBase_ntag);
                }else if(value instanceof CommentedSection){
                    CommentedSection nsec=(CommentedSection)value;
                    Object tObj_NBTBase_nbt=null;
                    if(nsec.getInt("_type_")==9) tObj_NBTBase_nbt=ClassHelper.getInstance(NMSHelper.clazz_NBTTagList);
                    else tObj_NBTBase_nbt=ClassHelper.getInstance(NMSHelper.clazz_NBTTagCompound);
                    ClassHelper.invokeMethod(pObj_NBTBase,NMSHelper.method_NBTTagList_add,tObj_NBTBase_nbt);
                    setTagContent(nsec,tObj_NBTBase_nbt);
                }else{
                    warn("NBT配置存在错误,无法处理["+sec.getCurrentPath()+"]的值"+value);
                }
            }
        }else if(NMSHelper.clazz_NBTTagCompound.isInstance(pObj_NBTBase)){// NBTTag NBTTagCompound
            Map<String,Object> tObj_content=NMSHelper.getNBTTagMapFromTag(pObj_NBTBase);
            for(String n : sec.getKeys(false)){
                Object value=sec.get(n);
                String tname=n.replace(re,'.');
                if(value instanceof String){
                    Object tObj_NBTBase_ntag=getNBTNode((String)value);
                    if(tObj_NBTBase_ntag!=null) tObj_content.put(tname,tObj_NBTBase_ntag);
                }else if(value instanceof CommentedSection){
                    CommentedSection nsec=(CommentedSection)value;
                    Object tObj_NBTBase_nbt=null;
                    if(nsec.getInt("_type_")==9) tObj_NBTBase_nbt=ClassHelper.getInstance(NMSHelper.clazz_NBTTagList);
                    else tObj_NBTBase_nbt=ClassHelper.getInstance(NMSHelper.clazz_NBTTagCompound);
                    tObj_content.put(tname,tObj_NBTBase_nbt);
                    setTagContent(nsec,tObj_NBTBase_nbt);
                }else{
                    warn("NBT配置存在错误,无法处理["+sec.getCurrentPath()+"]的值"+value);
                }
            }
        }else warn("你的NBT配置文件可能存在问题,节点"+sec.getCurrentPath()+"下\"_type_\"标识符错误");
    }

    /**
     * 根据字符串格式生成指定的NBT节点
     * @return 返回类型为NBTBase
     */
    private Object getNBTNode(String value){
        String[] vals=value.split("[|]",2);
        if(vals.length<2) return ClassHelper.getInstance(NMSHelper.clazz_NBTTagString,String.class,value);
        int type=0;
        try{
            type=Integer.parseInt(vals[0]);
        }
        catch(NumberFormatException nbfexp){
            warn("NBT.yml file at "+value+" is uncorrect,value before '|' must be a int");
            return null;
        }
        switch(type){
        case 1:
            try{
                byte tByteValue=Byte.parseByte(vals[1]);
                return ClassHelper.getInstance(NMSHelper.clazz_NBTTagByte,byte.class,tByteValue);
            }
            catch(NumberFormatException nbfexp){
                warn("NBT.yml file at "+value+" is uncorrect,value after '|' must be a byte value");
                return null;
            }
        case 2:
            try{
                short tShortValue=Short.parseShort(vals[1]);
                return ClassHelper.getInstance(NMSHelper.clazz_NBTTagShort,short.class,tShortValue);
            }
            catch(NumberFormatException nbfexp){
                warn("NBT.yml file at "+value+" is uncorrect,value after '|' must be a short value");
                return null;
            }
        case 3:
            try{
                int tIntValue=Integer.parseInt(vals[1]);
                return ClassHelper.getInstance(NMSHelper.clazz_NBTTagInt,int.class,tIntValue);
            }
            catch(NumberFormatException nbfexp){
                warn("NBT.yml file at "+value+" is uncorrect,value after '|' must be a int value");
                return null;
            }
        case 4:
            try{
                long tLongValue=Long.parseLong(vals[1]);
                return ClassHelper.getInstance(NMSHelper.clazz_NBTTagLong,long.class,tLongValue);
            }
            catch(NumberFormatException nbfexp){
                warn("NBT.yml file at "+value+" is uncorrect,value after '|' must be a long value");
                return null;
            }
        case 5:
            try{
                float tFloatValue=Float.parseFloat(vals[1]);
                return ClassHelper.getInstance(NMSHelper.clazz_NBTTagFloat,float.class,tFloatValue);
            }
            catch(NumberFormatException nbfexp){
                warn("NBT.yml file at "+value+" is uncorrect,value after '|' must be a float value");
                return null;
            }
        case 6:
            try{
                double tDoubleValue=Double.parseDouble(vals[1]);
                return ClassHelper.getInstance(NMSHelper.clazz_NBTTagDouble,double.class,tDoubleValue);
            }
            catch(NumberFormatException nbfexp){
                warn("NBT.yml file at "+value+" is uncorrect,value after '|' must be a double value");
                return null;
            }
        case 7:
            String[] bvals=vals[1].trim().split(",");
            List<Byte> blist=new ArrayList<>();
            for(String v : bvals){
                try{
                    blist.add(Byte.parseByte(v));
                }
                catch(NumberFormatException nbfexp){
                    warn("NBT.yml file at "+value+" is uncorrect,"+v+" is not a short value");
                }
            }
            byte[] mbvals=new byte[blist.size()];
            for(int i=0;i<blist.size();i++)
                mbvals[i]=blist.get(i);
            return ClassHelper.getInstance(NMSHelper.clazz_NBTTagByteArray,byte[].class,mbvals);
        case 11:
            String[] ivals=vals[1].trim().split(",");
            List<Integer> ilist=new ArrayList<>();
            for(String v : ivals){
                try{
                    ilist.add(Integer.parseInt(v));
                }
                catch(NumberFormatException nbfexp){
                    warn("NBT.yml file at "+value+" is uncorrect,"+v+" is not a int value");
                }
            }
            int[] mivals=new int[ilist.size()];
            for(int i=0;i<ilist.size();i++)
                mivals[i]=ilist.get(i);
            return ClassHelper.getInstance(NMSHelper.clazz_NBTTagIntArray,int[].class,mivals);
        case 8:
            return ClassHelper.getInstance(NMSHelper.clazz_NBTTagString,String.class,vals[1]);
        default:
            warn("NBT.yml file at "+value+" is unknow how to handle");
        }
        return null;
    }

    private String getStringValue(Object tObj_NBTBase_nbt){
        //ClassHelper.
        if(String.class.isInstance(tObj_NBTBase_nbt))
            return String.class.cast(tObj_NBTBase_nbt);
        String value="";
        if(NMSHelper.clazz_NBTTagByte.isInstance(tObj_NBTBase_nbt)){
            value="1|"+ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagByte_value);
        }else if(NMSHelper.clazz_NBTTagShort.isInstance(tObj_NBTBase_nbt)){
            value="2|"+ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagShort_value);
        }else if(NMSHelper.clazz_NBTTagInt.isInstance(tObj_NBTBase_nbt)){
            value="3|"+ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagInt_value);
        }else if(NMSHelper.clazz_NBTTagLong.isInstance(tObj_NBTBase_nbt)){
            value="4|"+ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagLong_value);
        }else if(NMSHelper.clazz_NBTTagFloat.isInstance(tObj_NBTBase_nbt)){
            value="5|"+ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagFloat_value);
        }else if(NMSHelper.clazz_NBTTagDouble.isInstance(tObj_NBTBase_nbt)){
            value="6|"+ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagDouble_value);
        }else if(NMSHelper.clazz_NBTTagByteArray.isInstance(tObj_NBTBase_nbt)){// 7 .c()
            value="7|";
            byte[] bvals=ClassHelper.getFieldValue(tObj_NBTBase_nbt,byte[].class,-1);
            for(byte bv : bvals)
                value+=bv+",";
            if(value.endsWith(",")) value=value.substring(0,value.length()-1);
        }else if(NMSHelper.clazz_NBTTagString.isInstance(tObj_NBTBase_nbt)){
            value="8|"+ClassHelper.getFieldValue(tObj_NBTBase_nbt,NMSHelper.field_NBTTagString_value);
        }else if(NMSHelper.clazz_NBTTagIntArray.isInstance(tObj_NBTBase_nbt)){// 11 .c()
            value="11|";
            int[] ivals=ClassHelper.getFieldValue(tObj_NBTBase_nbt,int[].class,-1);
            for(int iv : ivals)
                value+=iv+",";
            if(value.endsWith(",")) value=value.substring(0,value.length()-1);
        }else{
            warn("NBT of type: "+tObj_NBTBase_nbt.getClass().getName()+" unknow how to record,value: "+tObj_NBTBase_nbt.toString());
        }
        return value;
    }
}


