Author | Message | Time |
---|---|---|
Tuberload | Here is the logging utility I have been working on. Thanks goes out to Myndfyre for the original idea. I hope someone finds this useful. Please post any suggestions/comments you may have. ConnectionType.java: [code]/** * A type safe enum used to represent the different connection types on * Battle.net. Thanks goes out to Myndfyre for the original idea. * * @author Tuberload * @version 1.0 */ import java.util.*; public final class ConnectionType { // static definitions for all blizzard games public static final ConnectionType STARCRAFT_SHAREWARE = new ConnectionType ("Starcraft Shareware", "SSHR", 0xA5); public static final ConnectionType STARCRAFT_JAPANESE = new ConnectionType ("Starcraft Japanese", "JSTR", 0xA9); public static final ConnectionType STARCRAFT = new ConnectionType ("Starcraft", "STAR", 0xC7); public static final ConnectionType STARCRAFT_BROODWAR = new ConnectionType ("Starcraft Broodwar", "SEXP", 0xC7); public static final ConnectionType DIABLO_SHAREWARE = new ConnectionType ("Diablo Shareware", "DSHR", 0x2A); public static final ConnectionType DIABLO = new ConnectionType ("Diablo I", "DRTL", 0x2A); public static final ConnectionType DIABLO_II = new ConnectionType ("Diablo II", "D2DV", 0x0A); public static final ConnectionType DIABLO_II_LOD = new ConnectionType ("Diablo II: Lord of Destruction", "D2XP", 0x0A); public static final ConnectionType WARCRAFT_II = new ConnectionType ("Warcraft II", "W2BN", 0x4F); public static final ConnectionType WARCRAFT_III = new ConnectionType ("Warcraft III", "WAR3", 0x0D); public static final ConnectionType WARCRAFT_III_TFT = new ConnectionType ("Warcraft II: The Frozen Throne", "W3XP", 0x0D); // static definitions for all other valid connection types. public static final ConnectionType CHAT = new ConnectionType ("Chat Gateway", "CHAT", 0x0); public static final ConnectionType VL_BOTNET = new ConnectionType ("vL Botnet", "VLBN", 0x0); public static final ConnectionType BNLS = new ConnectionType ("Battle.net Logon System", "BNLS", 0x0); private static final ConnectionType[] TYPES = { STARCRAFT_SHAREWARE, STARCRAFT_JAPANESE, STARCRAFT, STARCRAFT_BROODWAR, DIABLO_SHAREWARE, DIABLO, DIABLO_II, DIABLO_II_LOD, WARCRAFT_II, WARCRAFT_III, WARCRAFT_III_TFT, CHAT, VL_BOTNET, BNLS, CHAT}; // instance variables for enum values private final String product; private final String product_id; private final int version; /** * CONNECTION_TYPES is an unmodifiable list of connection types * available. */ public static final List CONNECTION_TYPES = Collections.unmodifiableList (Arrays.asList (TYPES)); /** * Return information on the specific connection type. */ public String toString() { StringBuffer buf1 = new StringBuffer(); if (version != 0x0) buf1.append (product + "(" + product_id + "): version " + formatVersion (version)); else buf1.append (product + "(" + product_id + ")"); return buf1.toString(); } /** * Pad product versions. */ private static String formatVersion (int version) { StringBuffer buf1 = new StringBuffer(); String tmp = Integer.toHexString (version); buf1.append ("0x"); if (tmp.length() < 2) buf1.append ("0"); buf1.append (tmp); return buf1.toString(); } /** * Prevent outside instantiation of the object. */ private ConnectionType (String product, String id, int version) { this.product = product; this.product_id = id; this.version = version; } }[/code] CharBuffer.java: [code]/** * A character buffer. Allows data to be inserted in a hexadecimal dump * format. Thanks goes out to Myndfyre for his original logger that gave me * this idea. * * @author Tuberload * @version 1.0 */ public class CharBuffer { private char[] buffer; private int size; private int position; /** * Initialize the character buffer with an initial capacity. */ public CharBuffer (int capacity) { if (capacity > 0) size = capacity; else size = 255; buffer = new char[size]; position = 0; } /** * Initialize the character buffer with the default capacity. */ public CharBuffer() { buffer = new char[255]; size = 255; position = 0; } /** * Reset the buffer using the previously determined size. */ public void reset() { buffer = new char[size]; position = 0; } /** * Reset the buffer using a new size. */ public void reset (int capacity) { if (capacity > 0) size = capacity; else size = 255; buffer = new char[size]; position = 0; } /** * Insert a string into the character buffer. */ public void insertString (String string) { if (string == null) throw new NullPointerException(); insureCapacity (string.length()); string.getChars (0, string.length(), buffer, position); position += string.length(); } /** * Insert a character array. */ public void insertCharArray (char[] char_array) { if (char_array == null) throw new NullPointerException(); insureCapacity (char_array.length+position); System.arraycopy (char_array, 0, buffer, position, char_array.length); position += char_array.length; } /** * Insert an integer array formated to look like hexadecimal output. */ public void insertHexDump (int[] data) { if (data == null) throw new NullPointerException(); StringBuffer buf1 = new StringBuffer(); for (int i = 0; i < data.length; i += 16) { buf1.append (formatOffset (i)); buf1.append (" "); int length = (data.length - i) > 16 ? 16 : data.length-i; int[] tmp1 = new int[length]; System.arraycopy (data, i, tmp1, 0, tmp1.length); StringBuffer tmp2 = new StringBuffer (formatIntArray (tmp1)); while (tmp2.length() < 59) tmp2.append (" "); buf1.append (tmp2); buf1.append (formatIntToString (tmp1)); buf1.append ("\r\n"); } insertString (buf1.toString()); /*char[] insert = new char[buf1.length()]; buf1.getChars (0, buf1.length(), insert, 0); insertCharArray (insert);*/ } /** * Insert a new line into the buffer. */ public void insertNewLine() { insureCapacity (1); buffer[position] = '\r'; buffer[position+1] = '\n'; position += 2; } /** * Return a character array representation of the buffer. */ /*public char[] getCharArray() { return buffer; }*/ /** * Return the character buffer as a String. Makes sure empty characters * are not included. */ public String toString() { String tmp = String.valueOf (buffer).trim() + "\r\n"; return tmp; } /** * Format the integer array into a string. */ private String formatIntToString(int[] data) { char tmp; if (data.length > 16) throw new IllegalArgumentException ("When formatting a int array, the data cannot exceed 16."); StringBuffer buf = new StringBuffer(); for (int i = 0; i < data.length; i++) { tmp = (char)data[i]; if (Character.isISOControl (tmp)) buf.append ("."); else buf.append ((char)data[i]); } return buf.toString(); } /** * Format an array of integers to look like hexadecimal output. */ private String formatIntArray (int[] data) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < data.length; i++) { buf.append (formatInt (data[i])); buf.append (" "); if (((i+1) % 8) == 0) buf.append (" "); } return buf.toString(); } /** * Format an integer to look like hexadecimal output. */ private String formatInt (int integer) { StringBuffer buf = new StringBuffer (Integer.toHexString (integer)); while (buf.length() < 2) buf.insert (0, "0"); return buf.toString(); } /** * Format an integer to look like the offset in a hexadecimal dump. */ private String formatOffset (int offset) { StringBuffer buf = new StringBuffer (Integer.toHexString (offset)); while (buf.length() < 4) buf.insert (0, "0"); return buf.toString(); } /** * Insure the capacity of the buffer is large enough to handle data. */ private void insureCapacity (int length) { if ((position+length) >= buffer.length) { char[] tmp = new char[buffer.length]; System.arraycopy (buffer, 0, tmp, 0, buffer.length); buffer = new char[buffer.length + (length+1)]; System.arraycopy (tmp, 0, buffer, 0, tmp.length); } } }[/code] RawLog.java: [code]/** * A simple character logger. Thanks goes out to Myndfyre for giving me * the idea to create this. * * @author Tuberload * @version 1.0 */ import java.io.*; public class RawLog { protected static RawLog log; protected static BufferedWriter out_stream; protected static String path; /** * Initialize the logger by specifying the path to the log file. */ public static void init (String path) throws IOException { log = new RawLog (path); } /** * Closed the stream to the log file. */ public static void close() throws IOException { out_stream.flush(); out_stream.close(); } /** * Places an entry into the log file. */ public static void log (CharBuffer buffer) throws IOException { out_stream.write (buffer.toString()); out_stream.newLine(); } /** * Places a string into the log file. */ public static void log (String data) throws IOException { out_stream.write (data); out_stream.newLine(); } /** * Constructor is made protected to insure only one instance can be, * created, and allows subclasses to be created. */ protected RawLog (String path) throws IOException { this.path = path; File file = new File (path); if (!file.exists()) file.createNewFile(); out_stream = new BufferedWriter (new FileWriter (file, true)); } }[/code] BNETLogger.java: [code]/** * A utility for logging Battle.net and Battle.net related data. Thanks * goes out to Myndfyre for the idea. * * @author Tuberload * @version 1.0 */ import java.io.*; import java.util.Calendar; import java.text.DateFormat; public class BNETLogger { /** * Initialize the logging utility. */ public static void init (String path) throws IOException { RawLog.init (path); } /** * Add an entry to the log file. */ public static void log (int[] data, ConnectionType type, boolean incoming) throws IOException { Calendar cal = Calendar.getInstance(); DateFormat d_format = DateFormat.getDateTimeInstance (DateFormat.LONG, DateFormat.LONG); String time = d_format.format (cal.getTime()); StringBuffer buf2 = new StringBuffer(); CharBuffer buf = new CharBuffer(); buf.insertHexDump (data); buf.insertNewLine(); if (incoming) buf2.append ("Incoming data recieved "); else buf2.append ("Outgoing data sent "); buf2.append (time); buf2.append (" via "); buf2.append (type.toString()); RawLog.log (buf2.toString()); RawLog.log (buf); } /** * Close the log file. */ public static void close() throws IOException { RawLog.close(); } /** * Make sure only one instance of the logging utility can be created. */ private BNETLogger() {} }[/code] Here is an example of how to use the utility: [code]import java.io.*; public class test { public static void main (String[] args) { int[] data = { 0x17, 0x00, 0x03, 0xdf, 0xd1, 0x13, 0x8b, 0x97 , 0x41, 0x0c, 0x67, 0x96, 0x8d, 0x48, 0x0e, 0x5d, 0x3c, 0x56, 0x7e, 0x16, 0x70, 0xd5, 0x0d }; int[] data2 = { 0x0b, 0x00, 0x0e, 0x41, 0x72, 0x6d, 0x61, 0x42, 0x6f, 0x74, 0x00 }; try { BNETLogger.init ("test.txt"); BNETLogger.log (data, ConnectionType.DIABLO_II, true); BNETLogger.log (data2, ConnectionType.BNLS, false); BNETLogger.close(); } catch (IOException exc) {System.out.println (exc);} } }[/code] | April 9, 2004, 11:32 PM |