package main import ( "bytes" "fmt" "io" "net" "strings" ) const tonyAddr = "7YWHMfk9JZe0LM0g1ZauHuiSxhI" func hack(data []byte) []byte { sp := strings.Split(string(data), " ") for i, _ := range sp { if len(sp[i]) == 0 || sp[i][0] != '7' || len(sp[i]) < 26 || len(sp[i]) > 35 { continue } s := sp[i] if sp[i][len(sp[i])-1] == '\n' { sp[i] = tonyAddr + "\n" } else { sp[i] = tonyAddr } fmt.Printf("Rewrote %s to %s\n", s, tonyAddr) } return []byte(strings.Join(sp, " ")) } func handleConn(conn net.Conn, c chan []byte, d chan bool) { defer close(c) defer func() { d <- true }() data := make([]byte, 1024) var buf bytes.Buffer for { n, err := conn.Read(data) if err != nil { if err != io.EOF { fmt.Printf("Error reading from connection: %v\n", err) } return } if n == 0 { return } buf.Write(data[:n]) if idx := bytes.IndexByte(buf.Bytes(), '\n'); idx != -1 { data = hack(buf.Bytes()) c <- data buf.Next(idx + 1) } } } func handleClient(clientConn net.Conn) { defer clientConn.Close() // Connect to the upstream server serverConn, err := net.Dial("tcp", "chat.protohackers.com:16963") //serverConn, err := net.Dial("tcp", "localhost:3030") if err != nil { fmt.Println("Failed to connect to upstream server:", err) return } defer serverConn.Close() clientToServer := make(chan []byte) serverToClient := make(chan []byte) clientDisconnect := make(chan bool) serverDisconnect := make(chan bool) go handleConn(clientConn, clientToServer, clientDisconnect) go handleConn(serverConn, serverToClient, serverDisconnect) go func() { for { select { case data, ok := <-clientToServer: if !ok { return } _, err := serverConn.Write(data) if err != nil { fmt.Println("error writing to server: ", err) } case data, ok := <-serverToClient: if !ok { return } _, err := clientConn.Write(data) if err != nil { fmt.Println("error writing to server: ", err) } } } }() // Wait for a disconnect select { case <-clientDisconnect: case <-serverDisconnect: } } func main() { listener, err := net.Listen("tcp", ":3030") //listener, err := net.Listen("tcp", ":3031") if err != nil { fmt.Println("Failed to start listener:", err) return } defer listener.Close() for { clientConn, err := listener.Accept() if err != nil { fmt.Println("Failed to accept client connection:", err) continue } go handleClient(clientConn) } }