X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=src%2Forg%2Fpileus%2Fspades%2FMessage.java;h=61bf2bbed9654bf2035c0f33cba303059e14b438;hb=7c538be264da4cdd35827febfe3ed2cd43626963;hp=d13ea1ceaee1fe2dbe7a3ded2170227804e06982;hpb=c6a8817a4777c002e9966519294a61da209052d1;p=~andy%2Fspades diff --git a/src/org/pileus/spades/Message.java b/src/org/pileus/spades/Message.java index d13ea1c..61bf2bb 100644 --- a/src/org/pileus/spades/Message.java +++ b/src/org/pileus/spades/Message.java @@ -1,13 +1,15 @@ package org.pileus.spades; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.regex.Pattern; import java.util.regex.Matcher; public class Message { /* Enumerations */ - enum Type { + static enum Type { OTHER, // Unknown message type JOIN, // Join channel PART, // Leave channel @@ -21,7 +23,7 @@ public class Message AUTHFAIL, // Authentication failed }; - enum How { + static enum How { OTHER, // Unknown message type CHANNEL, // Normal message to a channel MENTION, // User was mentioned in message text @@ -30,16 +32,90 @@ public class Message SENT // Message was sent by the user }; + /* Structures */ + static class Color { + public int code; + public String hex; + public String name; + public int color; + + public Color(int code, String hex, String name) + { + this.code = code; + this.hex = hex; + this.name = name; + this.color = Os.getColor(hex); + } + }; + + static class Format implements Cloneable { + public boolean bold; + public boolean italic; + public boolean strike; + public boolean underline; + public boolean reverse; + public Color fg; + public Color bg; + public String txt; + + public Format clone() + { + try { + return (Format)super.clone(); + } catch (Exception e) { + return null; + } + } + + public String toString() + { + return (fg!=null ? fg.hex : "xxxxxx") + ":" + + (bg!=null ? bg.hex : "xxxxxx") + ":" + + (bold ? "b" : "-" ) + + (italic ? "i" : "-" ) + + (strike ? "s" : "-" ) + + (underline ? "u" : "-" ) + + (reverse ? "r" : "-" ) + ":" + + "[" + txt + "]"; + } + }; + + /* Colors */ + private static final Color colors[] = { + new Color(0x0, "FFFFFF", "White"), + new Color(0x1, "000000", "Black"), + new Color(0x2, "000080", "Navy Blue"), + new Color(0x3, "008000", "Green"), + new Color(0x4, "FF0000", "Red"), + new Color(0x5, "804040", "Brown"), + new Color(0x6, "8000FF", "Purple"), + new Color(0x7, "808000", "Olive"), + new Color(0x8, "FFFF00", "Yellow"), + new Color(0x9, "00FF00", "Lime Green"), + new Color(0xA, "008080", "Teal"), + new Color(0xB, "00FFFF", "Aqua Light"), + new Color(0xC, "0000FF", "Royal Blue"), + new Color(0xD, "FF00FF", "Hot Pink"), + new Color(0xE, "808080", "Dark Gray"), + new Color(0xF, "C0C0C0", "Light Gray"), + }; + /* Constants */ - private final String reMsg = "(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+)[= ]+)?(([^: ]+) *)?(:(.*))?"; - private final String reFrom = "([^! ]+)!.*"; - private final String reTo = "(([^ :,]*)[:,] *)?(.*)"; - private final String reCmd = "/([a-z]+)( +(.*))?"; + private static final String reMsg = "(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+)[= ]+)?(([^: ]+) *)?(:(.*))?"; + private static final String reFrom = "([^! ]+)!.*"; + private static final String reTo = "(([^ :,]*)[:,] *)?(.*)"; + private static final String reCmd = "/([a-z]+)( +(.*))?"; + + private static final Pattern ptMsg = Pattern.compile(reMsg); + private static final Pattern ptFrom = Pattern.compile(reFrom); + private static final Pattern ptTo = Pattern.compile(reTo); + private static final Pattern ptCmd = Pattern.compile(reCmd); - private static Pattern ptMsg = null; - private static Pattern ptFrom = null; - private static Pattern ptTo = null; - private static Pattern ptCmd = null; + private static final String cReNum = "1[0-5]|0?[0-9]"; + private static final String cReFmt = "[\\002\\011\\017\\023\\025\\026\\037]"; + private static final String cReClr = "[\\003\\013]("+cReNum+")?(,("+cReNum+"))?"; + private static final String cRegex = cReFmt + "|" + cReClr + "|$"; + private static final Pattern cPtrn = Pattern.compile(cRegex); /* Public data */ public Date time = null; @@ -58,10 +134,17 @@ public class Message public String to = ""; public String txt = ""; - /* Private methods */ - private String notnull(String string) + public List parts = new ArrayList(); + + /* Static methods */ + private static Color getColor(String code) { - return string == null ? "" : string; + if (code == null) + return null; + int i = Integer.parseInt(code); + if (i >= 0 && i < Message.colors.length) + return Message.colors[i]; + return null; } /* Public Methods */ @@ -71,55 +154,93 @@ public class Message this.how = How.SENT; this.from = from; - if (msg.charAt(0) == '/') { - if (ptCmd == null) - ptCmd = Pattern.compile(reCmd); - Matcher mr = ptCmd.matcher(msg); - if (!mr.matches()) - return; - - String cmd = notnull(mr.group(1)); - String arg = notnull(mr.group(3)); - - if (cmd.matches("join")) { - Os.debug("Message: /join"); - this.type = Type.JOIN; - this.cmd = "JOIN"; - this.msg = arg; - this.line = this.cmd + " :" + arg; - } - if (cmd.matches("part")) { - Os.debug("Message: /part"); - this.type = Type.PART; - this.cmd = "PART"; - this.msg = arg; - this.line = this.cmd + " :" + arg; - } - if (this.line == null) { - Os.debug("Message: unknown command"); - } - } else { - this.type = Type.PRIVMSG; - this.cmd = "PRIVMSG"; - this.dst = dst; - this.msg = msg; - this.line = this.cmd + " " + this.dst + " :" + this.msg; - } + if (this.parseSlash(msg)) + return; + + this.type = Type.PRIVMSG; + this.cmd = "PRIVMSG"; + this.dst = dst; + this.msg = msg; + this.line = this.cmd + " " + this.dst + " :" + this.msg; } public Message(String line, String name) { - // Initialize regexes - if (ptMsg == null) ptMsg = Pattern.compile(reMsg); - if (ptFrom == null) ptFrom = Pattern.compile(reFrom); - if (ptTo == null) ptTo = Pattern.compile(reTo); - - // Set time stamp this.time = new Date(); + this.parseText(line); + this.parseTypes(name); + this.parseColors(this.msg); + } + + public void debug() + { + Os.debug("---------------------"); + Os.debug("line = [" + line + "]"); + Os.debug("src = " + this.src); + Os.debug("cmd = " + this.cmd); + Os.debug("dst = " + this.dst); + Os.debug("arg = " + this.arg); + Os.debug("msg = " + this.msg); + Os.debug("from = " + this.from); + Os.debug("to = " + this.to); + Os.debug("txt = " + this.txt); + Os.debug("---------------------"); + } + + public String toString() + { + return this.from + ": " + this.txt; + } + + /* Private methods */ + private String notnull(String string) + { + return string == null ? "" : string; + } + + private boolean parseSlash(String msg) + { + if (msg.charAt(0) != '/') + return false; + + // Split up line + Matcher mr = ptCmd.matcher(msg); + if (!mr.matches()) + return false; + + String cmd = notnull(mr.group(1)); + String arg = notnull(mr.group(3)); + + // Parse commands + if (cmd.matches("join")) { + Os.debug("Message: /join"); + this.type = Type.JOIN; + this.cmd = "JOIN"; + this.msg = arg; + this.line = this.cmd + " :" + arg; + } + + if (cmd.matches("part")) { + Os.debug("Message: /part"); + this.type = Type.PART; + this.cmd = "PART"; + this.msg = arg; + this.line = this.cmd + " :" + arg; + } + + // Print warning if command is not recognized + if (this.line == null) + Os.debug("Message: unknown command"); + + return true; + } + + private void parseText(String line) + { // Cleanup line - line = line.replaceAll("\\s+", " "); - line = line.replaceAll("^ | $", ""); + line = line.replaceAll("\\s+", " "); + line = line.replaceAll("^ | $", ""); this.line = line; // Split line into parts @@ -145,7 +266,10 @@ public class Message this.txt = notnull(this.msg); else this.txt = notnull(mrTo.group(3)); + } + private void parseTypes(String name) + { // Parse commands names if (this.cmd.equals("PRIVMSG")) this.type = Type.PRIVMSG; else if (this.cmd.equals("332")) this.type = Type.TOPIC; @@ -166,23 +290,58 @@ public class Message else if (this.type == Type.PRIVMSG) this.how = How.CHANNEL; } - public void debug() + private void parseColors(String msg) { - Os.debug("---------------------"); - Os.debug("line = [" + line + "]"); - Os.debug("src = " + this.src); - Os.debug("cmd = " + this.cmd); - Os.debug("dst = " + this.dst); - Os.debug("arg = " + this.arg); - Os.debug("msg = " + this.msg); - Os.debug("from = " + this.from); - Os.debug("to = " + this.to); - Os.debug("txt = " + this.txt); - Os.debug("---------------------"); - } + // Setup regex matching + Matcher match = Message.cPtrn.matcher(msg); - public String toString() - { - return this.from + ": " + this.txt; + // Initialize state variables + int pos = 0; + Format fmt = new Format(); + ArrayList list = new ArrayList(); + + // Parse the string + while (match.find()) { + // Push current string + fmt.txt = msg.substring(pos, match.start()); + if (fmt.txt.length() > 0) + list.add(fmt.clone()); + pos = match.end(); + + // Abort at end of string + if (match.hitEnd()) + break; + + // Update format for next string + switch (match.group().charAt(0)) { + // Format attributes + case 002: fmt.bold ^= true; break; + case 011: fmt.italic ^= true; break; + case 023: fmt.strike ^= true; break; + case 025: fmt.underline ^= true; break; + case 037: fmt.underline ^= true; break; + case 026: fmt.reverse ^= true; break; + + // Reset + case 017: + fmt = new Format(); + break; + + // Colors + case 003: + String fg = match.group(1); + String bg = match.group(3); + fmt.fg = Message.getColor(fg); + fmt.bg = Message.getColor(bg); + break; + } + } + + // Cleanup extra space + list.trimToSize(); + this.parts = list; + this.msg = msg.replaceAll(cRegex, ""); + this.to = msg.replaceAll(cRegex, ""); + this.txt = msg.replaceAll(cRegex, ""); } }