database (#4)

Co-authored-by: Evan Burkey <dev@fputs.com>
Reviewed-on: https://git.fputs.com/fputs/protohackers/pulls/4
This commit is contained in:
Evan Burkey
2022-11-17 20:49:25 +01:00
parent 3bd3a895b5
commit 0499ea30fe
5 changed files with 205 additions and 3 deletions

55
cmd/budgetchat/main.go Normal file
View File

@ -0,0 +1,55 @@
package main
import (
"bufio"
"fmt"
"net"
"protohackers/pkg/conn"
)
func main() {
l, err := net.Listen(conn.Type, conn.Port)
if err != nil {
panic(err)
}
defer l.Close()
fmt.Println(fmt.Sprintf("Listening on port %s", conn.Port))
r := createRoom()
for {
c, err := l.Accept()
if err != nil {
break
}
go handleConn(r, c)
}
}
func handleConn(r *room, c net.Conn) {
u := newUser(c)
defer c.Close()
go u.sendMessage()
u.write("Welcome to budgetchat! What shall I call you?")
s := bufio.NewScanner(u.conn)
for s.Scan() {
input := s.Text()
if !u.online {
r.sendToRest(r.joinMsg(u), u)
u.write(r.connectMsg())
r.joinUser(u)
} else {
r.sendToRest(msgWrap(input, u), u)
}
if s.Err() != nil {
return
}
}
}
func msgWrap(msg string, u *user) string {
return fmt.Sprintf("[%s] %s", u.nick, msg)
}

59
cmd/budgetchat/room.go Normal file
View File

@ -0,0 +1,59 @@
package main
import (
"fmt"
"strings"
)
type room struct {
users []*user
}
func createRoom() *room {
return &room{
users: make([]*user, 16),
}
}
func (r *room) joinUser(u *user) {
for _, usr := range r.users {
if usr.nick == u.nick {
}
}
r.users = append(r.users, u)
u.online = true
}
func (r *room) sendToAll(msg string) {
for _, u := range r.users {
if u.online {
u.write(msg)
}
}
}
func (r *room) sendToRest(msg string, skip *user) {
for _, u := range r.users {
if u.online && u != skip {
u.write(msg)
}
}
}
func (r *room) connected() (nicks []string) {
for _, u := range r.users {
if u.online {
nicks = append(nicks, u.nick)
}
}
return nicks
}
func (r *room) joinMsg(u *user) string {
return fmt.Sprintf("* %s has joined the channel", u.nick)
}
func (r *room) connectMsg() string {
return fmt.Sprintf("* The room contains: %s", strings.Join(r.connected(), ", "))
}

27
cmd/budgetchat/user.go Normal file
View File

@ -0,0 +1,27 @@
package main
import "net"
type user struct {
conn net.Conn
nick string
online bool
output chan string
}
func newUser(conn net.Conn) *user {
return &user{
conn: conn,
output: make(chan string),
}
}
func (u *user) write(s string) {
u.output <- s + "\n"
}
func (u *user) sendMessage() {
for line := range u.output {
u.conn.Write([]byte(line))
}
}