// libnmdc project libnmdc.go package libnmdc import ( "errors" "fmt" "regexp" "strings" "time" ) const ( DEFAULT_CLIENT_TAG string = "libnmdc.go" DEFAULT_HUB_NAME string = "(unknown)" SEND_KEEPALIVE_EVERY time.Duration = 29 * time.Second AUTO_RECONNECT_AFTER time.Duration = 30 * time.Second ) var rx_protocolMessage *regexp.Regexp var rx_publicChat *regexp.Regexp var rx_incomingTo *regexp.Regexp var ErrNotConnected error = errors.New("Not connected") func init() { rx_protocolMessage = regexp.MustCompile("(?ms)^[^|]*\\|") rx_publicChat = regexp.MustCompile("(?ms)^<([^>]*)> (.*)$") rx_incomingTo = regexp.MustCompile("(?ms)^([^ ]+) From: ([^ ]+) \\$<([^>]*)> (.*)") } func NMDCUnescape(encoded string) string { v1 := strings.Replace(encoded, "$", "$", -1) v2 := strings.Replace(v1, "|", "|", -1) return strings.Replace(v2, "&", "&", -1) } func NMDCEscape(plaintext string) string { v1 := strings.Replace(plaintext, "&", "&", -1) v2 := strings.Replace(v1, "|", "|", -1) return strings.Replace(v2, "$", "$", -1) } func NMDCUnlock(lock []byte) string { nibble_swap := func(b byte) byte { return ((b << 4) & 0xF0) | ((b >> 4) & 0x0F) } chr := func(b byte) string { if b == 0 || b == 5 || b == 36 || b == 96 || b == 124 || b == 126 { return fmt.Sprintf("/%%DCN%04d%%/", b) } else { return string(b) } } key := chr(nibble_swap(lock[0] ^ lock[len(lock)-2] ^ lock[len(lock)-3] ^ 5)) for i := 1; i < len(lock); i += 1 { key += chr(nibble_swap(lock[i] ^ lock[i-1])) } return key }