package main import ( "encoding/json" "flag" "fmt" "log" "os" "sync" "time" "git.thc420.dev/blackbeard420/gomirc.git" "git.thc420.dev/blackbeard420/irc" ) type Network struct { Url string `json:"url"` Nick string `json:"nick"` Channel string `json:"channel"` Name string `json:"name"` Monitor bool `json:"monitor"` Connection irc.Connection } type Config struct { Networks []Network `json:"networks"` } var netmap map[string]*Network var netmutex sync.Mutex func main() { cfgpath := flag.String("cfg", "config.json", "path to config file") flag.Parse() log.Printf("Loading config: %s", *cfgpath) buf, err := os.ReadFile(*cfgpath) if err != nil { log.Fatalf("FATAL: %s", err.Error()) } conf := Config{} json.Unmarshal(buf, &conf) netmap = make(map[string]*Network) wg := sync.WaitGroup{} for _, n := range conf.Networks { wg.Add(1) initRelay(&n) } wg.Wait() } func initRelay(n *Network) { log.Printf("Connecting to [%s] %s = Monitor Mode: %t", n.Name, n.Channel, n.Monitor) netmutex.Lock() defer netmutex.Unlock() netmap[n.Name] = n n.Connection = *irc.NewConnection(n.Url, n.Nick, n.Nick, nil, []string{n.Channel}) if !n.Monitor { n.Connection.PrivmsgCallbackEx = handleMessage n.Connection.JoinCallbackEx = handleJoin n.Connection.PartCallbackEx = handlePart n.Connection.QuitCallbackEx = handleQuit } go runRelay(n) } func deleteRelay(n string) { netmutex.Lock() defer netmutex.Unlock() delete(netmap, n) } func runRelay(n *Network) { n.Connection.Run() log.Printf("Network connection lost [%s]", n.Name) time.Sleep(time.Second * 15) initRelay(n) } func handleMessage(c *irc.Connection, channel, nick, msg string) { relay(c, fmt.Sprintf("<%s> %s", irc.GetNick(nick), msg)) } func handleJoin(c *irc.Connection, from, target string) { relay(c, fmt.Sprintf("<%s> joined %s", irc.GetNick(from), target)) } func handlePart(c *irc.Connection, from, target, msg string) { relay(c, fmt.Sprintf("<%s> parted %s %s", irc.GetNick(from), target, msg)) } func handleQuit(c *irc.Connection, from, msg string) { relay(c, fmt.Sprintf("<%s> has quit [%s]", irc.GetNick(from), msg)) } func relay(c *irc.Connection, msg string) { netmutex.Lock() defer netmutex.Unlock() us := getByConn(c) networkid := gomirc.Grey().Sprintf("[%s]", netmap[us].Name) for _, n := range netmap { if n.Name != us { n.Connection.SendPrivmsg(n.Channel, fmt.Sprintf("%s %s", networkid, msg)) } } } func getByConn(c *irc.Connection) string { for _, n := range netmap { if n.Connection.Sock == c.Sock { return n.Name } } return "" }