summaryrefslogtreecommitdiff
path: root/server/chat.go
blob: 8275c59a5b08b66bc261841595e5664a6ee7ea86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package server

import (
	"strings"
	"git.citrons.xyz/metronode/classic"
	"git.citrons.xyz/metronode/phony"
)

type gameChat struct {
	phony.Inbox
	members map[chatListener]bool
}

func (c *gameChat) AddMember(from phony.Actor, m chatListener) {
	c.Act(from, func() {
		c.members[m] = true
	})
}

func (c *gameChat) RemoveMember(from phony.Actor, m chatListener) {
	c.Act(from, func() {
		delete(c.members, m)
	})
}

func (c *gameChat) Send(from phony.Actor, messageSender any, message string) {
	c.Act(from, func() {
		for m := range c.members {
			m.OnChatMessage(c, messageSender, message)
		}
	})
}

type chatListener interface {
	OnChatMessage(from *gameChat, messageSender any, message string)
}

func processChatMessage(message string) []classic.Packet {
	var (
		packets []classic.Packet
		in = strings.NewReader(message)
		line strings.Builder
		word strings.Builder
		color byte = 'f'
	)
	endLine := func() {
		if line.Len() == 0 {
			return
		}
		packet := &classic.Message {
			Message: classic.PadString(line.String()),
		}
		packets = append(packets, packet)
		line.Reset()
		line.WriteString("&7> &" + string([]byte{color}))
	}
	endWord := func() {
		if line.Len() + word.Len() > 64 {
			endLine()
		}
		line.WriteString(word.String())
		word.Reset()
	}
	for in.Len() > 0 {
		b, _ := in.ReadByte()
		if b == '%' {
			b = '&'
		}
		if b == '&' {
			endWord()
			word.WriteByte(b)
			b, _ = in.ReadByte()
			if (b >= '0' && b <= '9') || (b >= 'a' && b <= 'f') {
				color = b
			}
			word.WriteByte(b)
			endWord()
			continue
		}
		if b == ' ' {
			endWord()
			if line.Len() > 0 {
				word.WriteByte(b)
				endWord()
			}
			continue
		}
		word.WriteByte(b)
		if word.Len() >= 58 {
			endWord()
		}
	}
	endWord()
	endLine()
	return packets
}