5 changed files with 205 additions and 3 deletions
@ -0,0 +1,55 @@
@@ -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) |
||||
} |
@ -0,0 +1,59 @@
@@ -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(), ", ")) |
||||
} |
@ -0,0 +1,27 @@
@@ -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)) |
||||
} |
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"log" |
||||
"net" |
||||
"strings" |
||||
|
||||
"protohackers/pkg/conn" |
||||
) |
||||
|
||||
var ( |
||||
db map[string]string |
||||
) |
||||
|
||||
func init() { |
||||
db = make(map[string]string) |
||||
db["version"] = "0.1.1" |
||||
} |
||||
|
||||
func main() { |
||||
err := conn.StartSimpleUDP(handler, 1024) |
||||
if err != nil { |
||||
log.Fatalln(err) |
||||
} |
||||
} |
||||
|
||||
func handler(c *net.UDPConn, addr *net.UDPAddr, data []byte) { |
||||
if strings.Contains(string(data), "version=") { |
||||
return |
||||
} else if strings.Contains(string(data), "=") { |
||||
sp := strings.SplitN(string(data), "=", 2) |
||||
db[sp[0]] = sp[1] |
||||
} else { |
||||
out := fmt.Sprintf("%s=", string(data)) |
||||
if v, ok := db[string(data)]; ok { |
||||
out += v |
||||
} |
||||
c.WriteTo([]byte(out), addr) |
||||
} |
||||
} |
Loading…
Reference in new issue