126 lines
2.4 KiB
Go
126 lines
2.4 KiB
Go
|
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)
|
||
|
}
|
||
|
}
|