package main import ( "encoding/json" "flag" "fmt" "log" "net/url" "os" "os/signal" "strconv" "strings" "time" "github.com/Hri7566/mpp-client-go/mpp" "github.com/gorilla/websocket" "github.com/joho/godotenv" ) var addr = flag.String("addr", "mppclone.com:8443", "websocket address") var token string func main() { helpCommands = commands SetupDb() flag.Parse() log.SetFlags(0) err := godotenv.Load() if err != nil { log.Fatal(err) } token = os.Getenv("MPPNET_TOKEN") StartSocket(addr) } func StartSocket(address *string) { interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) url := url.URL{Scheme: "wss", Host: *addr} ws, _, err := websocket.DefaultDialer.Dial(url.String(), nil) if err != nil { log.Fatal("dial:", err) } defer ws.Close() done := make(chan struct{}) serverTicker := time.NewTicker(15 * time.Second) serverTickerQuit := make(chan struct{}) go func() { for { select { case <-serverTicker.C: SendTimeMessage(ws) case <-serverTickerQuit: serverTicker.Stop() } } }() go func() { defer close(done) for { _, message, err := ws.ReadMessage() if err != nil { log.Println("read:", err) return } // log.Printf("recv: %s", message) go ReceiveMessage(ws, message) // if (!sentHi) { // // histr := "[{\"m\":\"hi\"},{\"m\":\"ch\",\"_id\":\"βœ§π““π“”π“₯ π“‘π“Έπ“Έπ“Άβœ§\"}]" // histr := "[{\"m\":\"hi\",\"token\":\"" + *token + "\"}]" // println("Sending hi message: " + histr) // err := ws.WriteMessage(1, []byte(histr)) // if err != nil { // log.Println(err) // } // SendTimeMessage(ws) // sentHi = true // } } }() ticker := time.NewTicker(time.Second) defer ticker.Stop() for { select { case <-done: return case <-interrupt: log.Println("interrupt") err := ws.WriteMessage( websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), ) if err != nil { log.Println("write close:", err) return } select { case <-done: case <-time.After(time.Second): } return } } } func ReceiveMessage(ws *websocket.Conn, data []byte) { var tmp []json.RawMessage err := json.Unmarshal(data, &tmp) if err != nil { log.Fatal(err) return } var header struct { Type string `json:"m"` } for _, raw := range tmp { _ = json.Unmarshal(raw, &header) switch header.Type { case "hi": msg := mpp.HiMppMessage{} _ = json.Unmarshal(raw, &msg) ReceiveHiMessage(ws, &msg) case "nq": msg := mpp.NoteQuotaMppMessage{} _ = json.Unmarshal(raw, &msg) ReceiveNqMessage(&msg) case "t": msg := mpp.TimeMppMessage{} _ = json.Unmarshal(raw, &msg) case "a": msg := mpp.ChatMppMessage{} _ = json.Unmarshal(raw, &msg) ReceiveChatMessage(ws, &msg) case "b": SendHandshake(ws) default: return } } // println("Correctly deserialized JSON") // spew.Dump(tmp) // for _, msg := range msgs { // println(msg.Type) // } } func ReceiveNqMessage(msg *mpp.NoteQuotaMppMessage) { // println(msg.MaxHistLen) } func ReceiveHiMessage(ws *websocket.Conn, msg *mpp.HiMppMessage) { println("I am " + msg.User.Name) chstr := "[{\"m\":\"ch\",\"_id\":\"βœ§π““π“”π“₯ π“‘π“Έπ“Έπ“Άβœ§\"}]" // println("Sending ch message: " + chstr) err2 := ws.WriteMessage(1, []byte(chstr)) if err2 != nil { log.Println(err2) } } func SendHandshake(ws *websocket.Conn) { // histr := "[{\"m\":\"hi\"},{\"m\":\"ch\",\"_id\":\"βœ§π““π“”π“₯ π“‘π“Έπ“Έπ“Άβœ§\"}]" histr := "[{\"m\":\"hi\",\"token\":\"" + token + "\"}]" // println("Sending hi message: " + histr) err := ws.WriteMessage(1, []byte(histr)) if err != nil { log.Println(err) } SendTimeMessage(ws) // sentHi = true } type CommandData struct { mpp.ChatMppMessage Args []string Cmd string } type Command struct { Id string Callback func(ws *websocket.Conn, data *CommandData) string } var helpCommands []Command var commands []Command = []Command{ { Id: "help", Callback: func(ws *websocket.Conn, data *CommandData) string { output := "Commands: " for _, cmd := range helpCommands { output += cmd.Id + ", " } return strings.Trim(output[:len(output)-2], " ") }, }, { Id: "about", Callback: func(ws *websocket.Conn, data *CommandData) string { return "written in go version go1.22.2 linux/amd64" }, }, { Id: "me", Callback: func(ws *websocket.Conn, data *CommandData) string { bal, err := GetBalance(data.Part.Uid) if err != nil { log.Println(err) return "An error has occurred." } return "Your balance: " + strconv.FormatFloat(bal, 'f', -1, 64) }, }, { Id: "nu", Callback: func(ws *websocket.Conn, data *CommandData) string { return "I'd just like to interject for a moment. What you're refering to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX." }, }, } var botPrefix string = "g" func ReceiveChatMessage(ws *websocket.Conn, msg *mpp.ChatMppMessage) { log.Println(msg.Part.Uid[0:6] + " <" + msg.Part.Name + ">: " + msg.Message) if strings.HasPrefix(msg.Message, botPrefix) { args := strings.Split(msg.Message, " ") cmd := args[0][1:] var data CommandData = CommandData{ ChatMppMessage: *msg, Args: args, Cmd: cmd, } for _, command := range commands { if data.Cmd == command.Id { message := command.Callback(ws, &data) if message != "" { SendChat(ws, message) } break } } // switch data.Cmd { // case "help": // SendChat(ws, "golang test"); // } } } func SendTimeMessage(ws *websocket.Conn) { unixtime := fmt.Sprintf("%d", time.Now().Unix()) tstr := "[{\"m\": \"t\", \"t\": " + unixtime + "}]" // println("Sending t message: " + tstr) ws.WriteMessage(1, []byte(tstr)) } func SendChat(ws *websocket.Conn, message string) { ws.WriteMessage(1, []byte("[{\"m\":\"a\",\"message\":\"\u034f"+message+"\"}]")) }