Skip to content

Instantly share code, notes, and snippets.

@DivinityArcane
Last active December 12, 2015 07:08
Show Gist options
  • Save DivinityArcane/4734276 to your computer and use it in GitHub Desktop.
Save DivinityArcane/4734276 to your computer and use it in GitHub Desktop.
Boredom.
// A very simple dAmn bot in Go
// - Justin Eittreim <eittreim.justin@live.com>
// - http://DivinityArcane.deviantart.com/
package main
import (
"fmt"
"net"
"runtime"
"strings"
)
func main() {
runtime.GOMAXPROCS(2)
server, port := "chat.deviantart.com", 3900
user, pk := "username_goes_here", "authtoken_goes_here"
owner, msg := "DivinityArcane", "Hello, from <b>Go</b>!"
trigger := "/$"
autojoin := []string{"botdom", "deviousdevelopment"}
endpoint := fmt.Sprintf("%s:%d", server, port)
sock, err := net.Dial("tcp", endpoint)
if err != nil {
fmt.Printf("Error while connecting: %v\n", err)
return
}
defer sock.Close()
buffer := make([]byte, 8192)
send(sock, "dAmnClient 0.3\nagent=go")
for {
rcvd, err := sock.Read(buffer)
if rcvd == 0 || err != nil {
fmt.Printf("Disconnected. %v\n", err)
return
}
packbuf := make([]byte, rcvd)
packbuf = buffer[0:rcvd]
packet := new(DAmnPacket)
packet.Parse(string(packbuf))
switch packet.Command {
default:
fmt.Println("Unparsed packet: " + packet.Command)
case "ping":
send(sock, "pong")
fmt.Println("Pong!")
case "disconnect":
fmt.Println("Disconnected!")
return
case "dAmnServer":
fmt.Printf("Connected to dAmnServer %s\n", packet.Parameter)
send(sock, fmt.Sprintf("login %s\npk=%s", user, pk))
case "login":
if packet.Args["e"] != "ok" {
fmt.Println("Incorrect username or authtoken.")
return
}
fmt.Printf("Logged in as %s\n", packet.Parameter)
for _, chat := range autojoin {
send(sock, fmt.Sprintf("join chat:%s", chat))
}
case "join":
send(sock, fmt.Sprintf("send %s\n\nmsg main\n\n%s", packet.Parameter, msg))
case "recv":
switch packet.SubCommand {
default:
fmt.Println("Unparsed recv type: " + packet.SubCommand)
case "msg":
is_owner := false
if packet.Args["from"] == owner {
is_owner = true
}
if strings.HasPrefix(packet.Body, trigger+"about") {
send(sock, fmt.Sprintf("send %s\n\nmsg main\n\nHi! I'm a simple Go bot made by :devDivinityArcane:!", packet.Parameter))
} else if strings.HasPrefix(packet.Body, trigger+"quit") && is_owner {
send(sock, fmt.Sprintf("send %s\n\nmsg main\n\nQuitting", packet.Parameter))
send(sock, "disconnect")
}
}
}
}
}
func send(sock net.Conn, data string) {
fmt.Fprintf(sock, "%s\n%c", data, 0)
}
type DAmnPacket struct {
Command, Parameter, SubCommand, SubParameter, Body string
Args map[string]string
}
func (p *DAmnPacket) Parse(pkt string) bool {
p.Args = make(map[string]string)
pos := 0
if pos = strings.Index(pkt, "\n"); pos == -1 {
return false
}
header := pkt[0:pos]
if spos := strings.Index(header, " "); spos != -1 {
p.Command = header[0:spos]
p.Parameter = header[spos+1:]
} else {
p.Command = header
}
pkt = pkt[pos+1:]
if pos = strings.Index(pkt, "\n\n"); pos != -1 {
p.Body = pkt[pos+2:]
pkt = pkt[0:pos]
}
data := strings.Split(pkt, "\n")
for _, chunk := range data {
if len(chunk) == 0 {
continue
}
if pos = strings.Index(chunk, "="); pos != -1 {
key, value := chunk[0:pos], chunk[pos+1:]
p.Args[key] = value
continue
}
if pos = strings.Index(chunk, " "); pos != -1 {
p.SubCommand, p.SubParameter = chunk[0:pos], chunk[pos+1:]
}
}
return true
}
func (p *DAmnPacket) PullBodyArgs() bool {
if len(p.Body) <= 0 {
return false
}
if !strings.Contains(p.Body, "\n") || !strings.Contains(p.Body, "=") {
return false
}
data := strings.Split(p.Body, "\n")
for _, chunk := range data {
if len(chunk) == 0 {
continue
}
if pos := strings.Index(chunk, "="); pos != -1 {
key, value := chunk[0:pos], chunk[pos+1:]
p.Args[key] = value
continue
}
}
return true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment