Welcome to Yumao′s Blog.
FFxiv Log日志抽取格式化工具
, 2014年11月27日 , Java Language , 评论 在〈FFxiv Log日志抽取格式化工具〉中留言功能已關閉 ,

最開始先說下log的生成規則好了
ffxiv在登入遊戲之後
會在內存保存視窗內的log
需要在遊戲內勾選選項才會有相關方面log生成
在內存中累計到1000條記錄之後
會將其以特殊的方式
轉存至個人資料夾中的壹系列log文檔中
以達到釋放內存效用

 

此工具只針對于已生成的log文檔
對于即時生成的文檔無效
(因爲根本沒讀他

 

以下是code

package name.yumao.sqlog;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class test {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		String logPatch="C:\\Users\\soc\\Desktop\\log";
		File file = new File(logPatch);
		String[] filelist = file.list();
		int newerFile = 0;
		long newerModified = new File(logPatch + File.separator + filelist[newerFile]).lastModified();
		for (int i = 0; i < filelist.length; i++) {
			File tmpFile = new File(logPatch + File.separator + filelist[i]);
			if(tmpFile.lastModified()>newerModified){
				newerModified = tmpFile.lastModified();
				newerFile = i;
			}
		}
		File outLog = new File("C:\\Users\\soc\\Documents\\ffxivlog.log");
		OutputStream fis=new FileOutputStream(outLog);
		OutputStreamWriter fw=new OutputStreamWriter(fis,"UTF-8");
//		System.out.println("命中即时日志:" + filelist[newerFile]);
		for (int filecount = 0; filecount < filelist.length; filecount++) {
//			System.out.println("命中日志:" + filelist[filecount]);
		RandomAccessFile randomAccessFile = new RandomAccessFile(logPatch + File.separator + filelist[filecount], "r");
//		randomAccessFile.seek(0xfa8);
		byte[] lengthBytes = new byte[4];
		//读取文件头长度
		randomAccessFile.seek(0x0);
		int headerlen ;
		lengthBytes[0] = randomAccessFile.readByte();
		lengthBytes[1] = randomAccessFile.readByte();
		lengthBytes[2] = randomAccessFile.readByte();
		lengthBytes[3] = randomAccessFile.readByte();
	    int sleng = (int) ((lengthBytes[0] & 0xFF)
	            | ((lengthBytes[1] & 0xFF)<<8)
	            | ((lengthBytes[2] & 0xFF)<<16)
	            | ((lengthBytes[3] & 0xFF)<<24));
		lengthBytes[0] = randomAccessFile.readByte();
		lengthBytes[1] = randomAccessFile.readByte();
		lengthBytes[2] = randomAccessFile.readByte();
		lengthBytes[3] = randomAccessFile.readByte();
	    int eleng = (int) ((lengthBytes[0] & 0xFF)
	            | ((lengthBytes[1] & 0xFF)<<8)
	            | ((lengthBytes[2] & 0xFF)<<16)
	            | ((lengthBytes[3] & 0xFF)<<24));
	    headerlen = eleng - sleng;
//	    System.out.println(headerlen);
		//读取转存文件长度 从0x008开始 到headerlen*4+8结束
		randomAccessFile.seek(0x8);
		List<Integer> strLength = new ArrayList<Integer>();
		int value;
		while(randomAccessFile.getFilePointer()<(headerlen*4+8)){
			lengthBytes[0] = randomAccessFile.readByte();
			lengthBytes[1] = randomAccessFile.readByte();
			lengthBytes[2] = randomAccessFile.readByte();
			lengthBytes[3] = randomAccessFile.readByte();
		    value = (int) ((lengthBytes[0] & 0xFF)
		            | ((lengthBytes[1] & 0xFF)<<8)
		            | ((lengthBytes[2] & 0xFF)<<16)
		            | ((lengthBytes[3] & 0xFF)<<24));
		    strLength.add(value);
		}
//		System.out.println(strLength.size());
		byte[] tmp;
		String logStr = "";
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for(int i=0;i<strLength.size();i++){
			if(i == 0){
				tmp = new byte[strLength.get(i)];
				for(int j=0;j<strLength.get(i);j++){
					tmp[j]=randomAccessFile.readByte();
				}

			}else{
				tmp = new byte[strLength.get(i)-strLength.get(i-1)];
				for(int j=0;j<strLength.get(i)-strLength.get(i-1);j++){
					tmp[j]=randomAccessFile.readByte();
				}
			}
			logStr = new String(tmp,"UTF-8");
//			logStr = df.format(Long.parseLong(logStr.substring(0,8),16)*1000) +" "+ logStr.substring(8);
//			logStr = logStr.replaceAll("\n", "").replaceAll("\r", "").replaceAll("\r\n", "");
			if(logStr.contains("")){
//				System.out.println(logStr);
			fw.write(formatLogStr(tmp).replaceAll("\n", "").replaceAll("\r", "").replaceAll("\r\n", "")+"\r\n");
			fw.flush();}
		}
	}fw.close();
	}
	public static String formatLogStr(byte[] byteStr) throws Exception{
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		System.out.println(new String(HexUtils.HexString2Bytes("E381AEE694BBE69283"),"UTF-8"));
		String hexStr = HexUtils.Bytes2HexString(byteStr).replaceAll(" ", "");
//		System.out.println(hexStr);
		if(hexStr.contains(HexUtils.Bytes2HexString("12A9".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("1130".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("12AB".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("492E".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("112D".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("492D".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("292F".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("1329".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("292D".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("1131".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("133A".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("12AA".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("103A".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("112E".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("112F".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("312F".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("12BA".getBytes()).replace(" ", ""))
				||hexStr.contains(HexUtils.Bytes2HexString("14AB".getBytes()).replace(" ", ""))){
			if(hexStr.contains("01010101")&&hexStr.contains("010101")){
				String headerStr = hexStr.substring(0,28);
				String nickName = hexStr.substring(hexStr.indexOf("01010101")+12);
				nickName = nickName.substring(0,nickName.indexOf("03"));
				String bodyStr = "";
				bodyStr = hexStr.substring(hexStr.indexOf("E381"));
				hexStr = headerStr + nickName + bodyStr;
			}
		}
		else if(hexStr.contains("32393239")){
			if(hexStr.contains("01010101")&&hexStr.contains("010101")){
				if(hexStr.substring(28).startsWith("E38")){
					String headerStr = hexStr.substring(0,hexStr.indexOf("E381AEE694BBE69283")+"E381AEE694BBE69283".length());
					hexStr = hexStr.substring(hexStr.indexOf("E381AEE694BBE69283")+"E381AEE694BBE69283".length());
					String nickName = hexStr.substring(hexStr.indexOf("01010101")+12);
					nickName = nickName.substring(0,nickName.indexOf("03"));
					String bodyStr = "";
					bodyStr = hexStr.substring(hexStr.indexOf("E381"));
					hexStr = headerStr+"20"+ nickName + bodyStr;
				}else{
					String headerStr = hexStr.substring(0,28);
					String nickName = hexStr.substring(hexStr.indexOf("01010101")+12);
					nickName = nickName.substring(0,nickName.indexOf("03"));
					String bodyStr = "";
					bodyStr = hexStr.substring(hexStr.indexOf("E381"));
					hexStr = headerStr + nickName + bodyStr;
				}
			}
		}else{

		}
		hexStr = hexStr.replaceAll("EE81AF", "E28692");
		String str = new String(HexUtils.HexString2Bytes(hexStr),"UTF-8");
		//替换时间头

		str = df.format(Long.parseLong(str.substring(0,8),16)*1000) +" "+ str.substring(8);
		System.out.println(str);
		return str;
	}
}
关键字:, , ,

评论已关闭