123 lines
2.6 KiB
Go
123 lines
2.6 KiB
Go
package world
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"slices"
|
|
|
|
"git.chromaticdragon.app/pyrex/minimal-irc-server/v2/src/irc/users"
|
|
"git.chromaticdragon.app/pyrex/minimal-irc-server/v2/src/transport"
|
|
)
|
|
|
|
type World struct {
|
|
Server *transport.Server
|
|
UsersSystem *users.UsersSystem
|
|
}
|
|
|
|
type WrappedMessage struct {
|
|
World *World
|
|
Sender *users.User
|
|
Content transport.Content
|
|
}
|
|
|
|
func NewWorld(server *transport.Server) *World {
|
|
usersSystem := users.NewUsersSystem()
|
|
|
|
return &World{
|
|
Server: server,
|
|
UsersSystem: usersSystem,
|
|
}
|
|
}
|
|
|
|
func (world *World) Wrap(msg transport.IncomingMessage) WrappedMessage {
|
|
sender := world.UsersSystem.ByClientIdOrCreate(msg.Sender)
|
|
|
|
return WrappedMessage{
|
|
World: world,
|
|
Sender: sender,
|
|
Content: msg.Content,
|
|
}
|
|
}
|
|
|
|
// transmission of messages
|
|
func (world *World) RelayToVagueDestination(
|
|
msg WrappedMessage,
|
|
name string,
|
|
exclude []transport.ClientId,
|
|
) {
|
|
nick, err := users.ValidateNick(name)
|
|
if err == nil {
|
|
// so it's a nick!
|
|
world.RelayToNick(msg, nick, exclude)
|
|
return
|
|
}
|
|
|
|
channel, err := users.ValidateChannelName(name)
|
|
if err == nil {
|
|
// so it's a channel!
|
|
world.RelayToChannel(msg, channel, exclude)
|
|
return
|
|
}
|
|
|
|
log.Fatalf("not sure how to send to %s", name)
|
|
// TODO: Error response: "what is this?"
|
|
}
|
|
|
|
func (world *World) RelayToClient(
|
|
msg WrappedMessage,
|
|
client transport.ClientId,
|
|
exclude []transport.ClientId,
|
|
) {
|
|
content := createAnnotatedContent(msg)
|
|
if slices.Contains(exclude, client) {
|
|
return // don't relay
|
|
}
|
|
world.Server.SendMessage(client, content)
|
|
}
|
|
|
|
func (world *World) RelayToNick(
|
|
msg WrappedMessage,
|
|
nick users.Nick,
|
|
exclude []transport.ClientId,
|
|
) {
|
|
content := createAnnotatedContent(msg)
|
|
|
|
user := world.UsersSystem.ByNick(nick)
|
|
if user == nil {
|
|
// TODO: Send an error reply. The user didn't exist
|
|
return
|
|
}
|
|
|
|
if slices.Contains(exclude, user.GetClientId()) {
|
|
return // don't relay
|
|
}
|
|
|
|
world.Server.SendMessage(user.GetClientId(), content)
|
|
}
|
|
|
|
func (world *World) RelayToChannel(
|
|
msg WrappedMessage,
|
|
channelName users.ChannelName,
|
|
exclude []transport.ClientId,
|
|
) {
|
|
content := createAnnotatedContent(msg)
|
|
|
|
members := world.UsersSystem.ByChannel(channelName)
|
|
log.Printf("Members of %s: %v\n", channelName, members)
|
|
for member := range members {
|
|
if slices.Contains(exclude, member.GetClientId()) {
|
|
return // don't relay
|
|
}
|
|
world.Server.SendMessage(member.GetClientId(), content)
|
|
}
|
|
}
|
|
|
|
func createAnnotatedContent(
|
|
msg WrappedMessage,
|
|
) transport.Content {
|
|
content := msg.Content
|
|
fullSource := fmt.Sprintf("%s!clients/%d", msg.Sender.GetNick().Value, msg.Sender.GetClientId())
|
|
content.Source = &fullSource
|
|
return content
|
|
}
|