Ejemplo n.º 1
0
func (c *Client) parseMessage(rm router.Message) {
	var t struct {
		Type string `msgpack:"type"`
		ID   string `msgpack:"id"`
	}
	err := msgpack.Unmarshal(rm.Payload, &t)
	if err != nil {
		return
	}

	id, err := utils.NewNodeIDFromString(t.ID)
	if err != nil {
		return
	}

	var m Message
	switch t.Type {
	case "chat":
		u := struct {
			Content ChatMessage `msgpack:"content"`
		}{}
		err := msgpack.Unmarshal(rm.Payload, &u)
		if err != nil {
			return
		}
		m = u.Content

	case "ack":
		u := struct {
			Content MessageAck `msgpack:"content"`
		}{}
		err := msgpack.Unmarshal(rm.Payload, &u)
		if err != nil {
			return
		}
		m = u.Content

	case "prof-res":
		u := struct {
			Content UserProfileResponse `msgpack:"content"`
		}{}
		err := msgpack.Unmarshal(rm.Payload, &u)
		if err != nil {
			return
		}
		m = u.Content
		c.Roster.Set(id, u.Content.Profile)

	case "prof-req":
		c.SendProfile(id)

	}

	if m != nil && t.Type != "ack" {
		c.mbuf.Push(readPair{M: m, ID: rm.Node})
		if !bytes.Equal(rm.Node.NS[:], utils.GroupNamespace[:]) {
			c.sendAck(rm.Node, rm.ID)
		}
	}
}
Ejemplo n.º 2
0
func (s *Session) commandLoop() {
	var chatID *utils.NodeID

	go func() {
		for {
			m, src, err := s.cli.Read()
			if err != nil {
				return
			}
			if msg, ok := m.(murcott.ChatMessage); ok {
				/*
					if chatID == nil {
						chatID = &src
						color.Printf("\n -> Start a chat with @{Wk} %s @{|}\n\n", src.String())
					}
				*/
				str := src.String()
				color.Printf("\r* @{Wk}%s@{|} %s\n", str[len(str)-8:], msg.Text())
				fmt.Print("* ")
			}
		}
	}()

	bio := bufio.NewReader(os.Stdin)
	for {
		if chatID == nil {
			fmt.Print("> ")
		} else {
			fmt.Print("* ")
		}
		line, _, err := bio.ReadLine()
		if err != nil {
			return
		}
		c := strings.Split(string(line), " ")
		if len(c) == 0 || c[0] == "" {
			continue
		}
		switch c[0] {
		case "/chat":
			if len(c) != 2 {
				color.Printf(" -> @{Rk}ERROR:@{|} /chat takes 1 argument\n")
			} else {
				nid, err := utils.NewNodeIDFromString(c[1])
				if err != nil {
					color.Printf(" -> @{Rk}ERROR:@{|} invalid ID\n")
				} else {
					s.cli.Join(nid)
					chatID = &nid
					color.Printf(" -> Start a chat with @{Wk} %s @{|}\n\n", nid.String())
				}
			}
		case "/add":
			if len(c) != 2 {
				color.Printf(" -> @{Rk}ERROR:@{|} /add takes 1 argument\n")
			} else {
				nid, err := utils.NewNodeIDFromString(c[1])
				if err != nil {
					color.Printf(" -> @{Rk}ERROR:@{|} invalid ID\n")
				} else {
					s.cli.Roster.Set(nid, murcott.UserProfile{})
				}
			}
		case "/mkg":
			key := utils.GeneratePrivateKey()
			id := utils.NewNodeID(utils.GroupNamespace, key.Digest())
			color.Printf("Group ID: @{Wk} %s @{|}\n\n", id.String())

		case "/stat":
			color.Printf("  * NumGoroutine() = %d\n", runtime.NumGoroutine())
			nodes := s.cli.ActiveSessions()
			color.Printf("  * active sessions (%d) *\n", len(nodes))
			for _, n := range nodes {
				color.Printf(" %v\n", n)
			}
			list := s.cli.Roster.List()
			color.Printf("  * Roster (%d) *\n", len(list))
			for _, n := range list {
				color.Printf(" %v %s \n", n, s.cli.Roster.Get(n).Nickname)
			}

		case "/end":
			if chatID != nil {
				color.Printf(" -> End current chat\n")
				s.cli.Leave(*chatID)
				chatID = nil
			}
		case "/exit", "/quit":
			color.Printf(" -> See you@{Kg}.@{Kr}.@{Ky}.@{|}\n")
			return
		case "/help":
			showHelp()
		default:
			if chatID == nil {
				color.Printf(" -> @{Rk}ERROR:@{|} unknown command\n")
				showHelp()
			} else {
				s.cli.SendMessage(*chatID, murcott.NewPlainChatMessage(string(line)))
			}
		}
	}
}