diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..445e913 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +/app/chaturbate/chaturbate +/app/bongacams/bongacams diff --git a/client/client.go b/client/client.go new file mode 100644 index 0000000..c9c3d94 --- /dev/null +++ b/client/client.go @@ -0,0 +1,31 @@ +package main + +import ( + "net" + "time" +) + +var echoSocket = make(chan []byte) + +func startSocket() { + for { + select { + case b := <-echoSocket: + conn, err := net.Dial("unix", "/tmp/echo.sock") + if err == nil { + conn.Write(b) + conn.Close() + } + } + } +} + +func main() { + go startSocket() + + for { + echoSocket <- []byte(`{"chanel":"stripchat","room":"naughtyobsessions","donator":"tbone6893","amount":333}`) + echoSocket <- []byte(`{"chanel":"stripchat","index":28}`) + time.Sleep(1e9) + } +} diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..c104e83 --- /dev/null +++ b/server/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "log" + "net" + "net/http" + "os" +) + +func main() { + + go broadcast() + go startSocket() + + http.HandleFunc("/ws/", wsHandler) + + const SOCK = "/tmp/ws.sock" + removeSocket(SOCK) + unixListener, err := net.Listen("unix", SOCK) + if err != nil { + log.Fatal("Listen (ws socket): ", err) + } + defer unixListener.Close() + os.Chmod(SOCK, 0777) + log.Fatal(http.Serve(unixListener, nil)) +} diff --git a/server/socket.go b/server/socket.go new file mode 100644 index 0000000..0d910e3 --- /dev/null +++ b/server/socket.go @@ -0,0 +1,42 @@ +package main + +import ( + "log" + "net" + "os" +) + +func removeSocket(s string) { + if _, err := os.Stat(s); err == nil { + os.Remove(s) + } +} + +func startSocket() { + const SOCK = "/tmp/echo.sock" + removeSocket(SOCK) + listener, err := net.Listen("unix", SOCK) + if err != nil { + log.Fatal("Listen (echo socket): ", err) + } + defer listener.Close() + for { + conn, err := listener.Accept() + if err != nil { + log.Fatal("accept error:", err) + } + go socketHandler(conn) + } +} + +func socketHandler(conn net.Conn) { + defer conn.Close() + buf := make([]byte, 512) + for { + n, err := conn.Read(buf) + if err != nil { + return + } + ws.Send <- wsMessage{Message: buf[0:n], Decode: true} + } +} diff --git a/server/websocket.go b/server/websocket.go new file mode 100644 index 0000000..1bb2abb --- /dev/null +++ b/server/websocket.go @@ -0,0 +1,140 @@ +package main + +import ( + "fmt" + "net/http" + "time" + + "github.com/gorilla/websocket" + jsoniter "github.com/json-iterator/go" +) + +type enterChanel struct { + Conn *websocket.Conn + Chanel string +} + +type wsMessage struct { + Message []byte + Decode bool +} + +var upgrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + CheckOrigin: func(r *http.Request) bool { + if r.Header.Get("origin") == "https://statbate.com" { + return true + } + return false + }, +} + +var ( + wsClients = make(map[*websocket.Conn]string) + + json = jsoniter.ConfigCompatibleWithStandardLibrary + + ws = struct { + Count chan int + Add chan *websocket.Conn + Del chan *websocket.Conn + Send chan wsMessage + Enter chan enterChanel + }{ + Count: make(chan int, 100), + Add: make(chan *websocket.Conn, 100), + Del: make(chan *websocket.Conn, 100), + Send: make(chan wsMessage, 100), + Enter: make(chan enterChanel, 100), + } +) + +func broadcast() { + ticker := time.NewTicker(30 * time.Second) + for { + select { + case conn := <-ws.Add: + wsClients[conn] = "" + + case conn := <-ws.Del: + delete(wsClients, conn) + + case <-ws.Count: + ws.Count <- len(wsClients) + + case r := <-ws.Enter: + wsClients[r.Conn] = r.Chanel + + case r := <-ws.Send: + sendMessage(r.Message, r.Decode) + + case <-ticker.C: + sendMessage([]byte("ping"), false) + } + } +} + +func sendMessage(message []byte, decode bool) { + chanel := "" + if decode { + var input map[string]interface{} + if err := json.Unmarshal(message, &input); err != nil { + fmt.Println("json error: ", err.Error()) + return + } + if input["chanel"] != nil { + chanel = input["chanel"].(string) + } + } + + fmt.Println(string(message), decode, chanel) + + for conn, ch := range wsClients { + if decode && ch != chanel { + continue + } + if err := conn.WriteMessage(1, message); err != nil { + conn.Close() + delete(wsClients, conn) + } + } +} + +func wsHandler(w http.ResponseWriter, r *http.Request) { + conn, err := upgrader.Upgrade(w, r, nil) + if err != nil { + return + } + go readWS(conn) +} + +func readWS(conn *websocket.Conn) { + defer conn.Close() + + ws.Add <- conn + + defer func() { + ws.Del <- conn + }() + + chanels := map[string]bool{ + "chaturbate": true, + "bongacams": true, + "stripchat": true, + } + + for { + _, message, err := conn.ReadMessage() + if err != nil { + fmt.Println("readWS", err.Error()) + return + } + + input := string(message) + + if len(input) < 32 && chanels[input] { + ws.Enter <- enterChanel{Conn: conn, Chanel: input} + } + } +}