generated from ElnuDev/go-project
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.9 KiB
77 lines
1.9 KiB
package clients
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.elnu.com/ElnuDev/jichanorg/httputils"
|
|
)
|
|
|
|
type Client = chan []httputils.SseEvent
|
|
|
|
const EventWord = "word"
|
|
const EventPlayerCount = "players"
|
|
const EventNavigate = "navigate"
|
|
|
|
type ClientSet struct {
|
|
clients map[Client]bool
|
|
}
|
|
|
|
func NewClientSet() ClientSet {
|
|
return ClientSet{make(map[Client]bool)}
|
|
}
|
|
|
|
func (clients ClientSet) Broadcast(events ...httputils.SseEvent) {
|
|
for client := range clients.clients {
|
|
client <- events
|
|
}
|
|
}
|
|
|
|
func (clients ClientSet) PlayerCount() int {
|
|
return len(clients.clients)
|
|
}
|
|
|
|
func (clients ClientSet) PlayerCountEvent(offset int) httputils.SseEvent {
|
|
playerCount := clients.PlayerCount() + offset
|
|
var data string
|
|
if playerCount == 0 {
|
|
data = "No players online."
|
|
} else {
|
|
data = fmt.Sprintf("%d player%s online.", playerCount, map[bool]string{true: "", false: "s"}[playerCount == 1])
|
|
}
|
|
return httputils.SseEvent{EventName: EventPlayerCount, Data: data}
|
|
}
|
|
|
|
func (clients ClientSet) BroadcastPlayerCount(offset int) {
|
|
clients.Broadcast(clients.PlayerCountEvent(offset))
|
|
}
|
|
|
|
func (clients ClientSet) BroadcastWord(word string) {
|
|
clients.Broadcast(
|
|
httputils.SseEvent{
|
|
EventName: EventWord,
|
|
Data: fmt.Sprintf("<div>%s</div>", word),
|
|
},
|
|
httputils.SseEvent{
|
|
EventName: EventNavigate,
|
|
Data: fmt.Sprintf("https://jisho.org/search/%s", word),
|
|
},
|
|
)
|
|
}
|
|
|
|
func (clients ClientSet) Connect(client Client) {
|
|
// Channels are blocking.
|
|
// Client initialization is waiting for connect() to complete.
|
|
// If we try to braodcast to it before connect() is done,
|
|
// the channel handling logic wouldn't have started yet,
|
|
// and broadcast() would be freeze.
|
|
// Therefore, we must broadcast an offset player count first,
|
|
// then actually add the client.
|
|
clients.BroadcastPlayerCount(1)
|
|
clients.clients[client] = true
|
|
}
|
|
|
|
func (clients ClientSet) Disconnect(client Client) {
|
|
delete(clients.clients, client)
|
|
clients.BroadcastPlayerCount(0)
|
|
}
|