package server import ( "fmt" "io" "regexp" "strings" "go.neonxp.ru/qchat/internal/chat" ) var replacements = []replacement{ { From: *regexp.MustCompile(`\*(.+?)\*`), To: fmt.Sprintf("%s$1%s", escapeCodes[Bold], escapeCodes[Reset]), }, { From: *regexp.MustCompile(`\+(.+?)\+`), To: fmt.Sprintf("%s$1%s", escapeCodes[Italic], escapeCodes[Reset]), }, { From: *regexp.MustCompile(`\-(.+?)\-`), To: fmt.Sprintf("%s$1%s", escapeCodes[Strike], escapeCodes[Reset]), }, { From: *regexp.MustCompile(`_(.+?)_`), To: fmt.Sprintf("%s$1%s", escapeCodes[Underline], escapeCodes[Reset]), }, } func processUserEvent(message any, w io.Writer, user *chat.User) { switch message := message.(type) { case chat.Message: displayMessage(w, message, user) case chat.SelfMessage: displaySelfMessage(w, message) case chat.SystemMessage: displaySystemMessage(w, message) case chat.UserJoined: displayUserJoined(w, message) case chat.UserLeft: displayUserLeft(w, message) case chat.UserLogs: displayUserLogs(w, message) } } func displayMessage(w io.Writer, message chat.Message, user *chat.User) { msg := message.Message mentionFrom := "@" + user.Username mentionTo := string(escapeCodes[Yellow]) + string(escapeCodes[Underline]) + "@" + user.Username + string(escapeCodes[Reset]) if strings.Contains(msg, mentionFrom) { msg = strings.ReplaceAll(msg, mentionFrom, mentionTo) msg = "\x07\a" + msg } for _, r := range replacements { msg = r.From.ReplaceAllString(msg, r.To) } //nolint:errcheck fmt.Fprintf(w, "%s%18s%s [%s]%s: %s\n", escapeCodes[Blue], message.User.NUsername(), escapeCodes[Green], message.Time.Format("15:04:05"), escapeCodes[Reset], msg, ) } func displaySystemMessage(w io.Writer, message chat.SystemMessage) { //nolint:errcheck fmt.Fprintf(w, "%s* %s %s\n", escapeCodes[Green], message.Message, escapeCodes[Reset], ) } func displaySelfMessage(w io.Writer, message chat.SelfMessage) { //nolint:errcheck fmt.Fprintf(w, "%s* %s %s%s\n", escapeCodes[Blue], message.User.NUsername(), message.Message, escapeCodes[Reset], ) } func displayUserJoined(w io.Writer, presence chat.UserJoined) { //nolint:errcheck fmt.Fprintf(w, "%s* %s joined to %s chan%s\n", escapeCodes[Green], presence.User.NUsername(), presence.Chan.Name, escapeCodes[Reset], ) } func displayUserLeft(w io.Writer, presence chat.UserLeft) { //nolint:errcheck fmt.Fprintf(w, "%s* %s left %s chan%s\n", escapeCodes[Red], presence.User.NUsername(), presence.Chan.Name, escapeCodes[Reset], ) } func displayUserLogs(w io.Writer, message chat.UserLogs) { messages := make([]string, 0, len(message.Logs)) for _, m := range message.Logs { switch m.Type { case chat.TypeNone: continue case chat.TypeJoined: messages = append(messages, fmt.Sprintf("* %18s [%s]: joined", m.Username, m.Time.Format("15:04:05"))) case chat.TypeLeft: messages = append(messages, fmt.Sprintf("* %18s [%s]: left", m.Username, m.Time.Format("15:04:05"))) case chat.TypeMessage: messages = append(messages, fmt.Sprintf("%18s [%s]: %s", m.Username, m.Time.Format("15:04:05"), m.Message)) } } if len(messages) == 0 { return } //nolint:errcheck fmt.Fprintf(w, "%s* Last channel messages:\n%s%s\n", escapeCodes[Blue], strings.Join(messages, "\n"), escapeCodes[Reset], ) } type replacement struct { From regexp.Regexp To string }