-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
109 lines (91 loc) · 2.12 KB
/
server.go
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
97
98
99
100
101
102
103
104
105
106
107
108
109
package main
import (
"errors"
"fmt"
"log"
"net"
"strings"
)
type server struct {
rooms map[string]*room
commands chan command
}
func (s *server) run() {
for cmd := range s.commands {
switch cmd.id {
case CMD_NICK:
s.nick(cmd.client, cmd.args)
case CMD_JOIN:
s.join(cmd.client, cmd.args)
case CMD_ROOMS:
s.listRooms(cmd.client, cmd.args)
case CMD_MSG:
s.msg(cmd.client, cmd.args)
case CMD_QUIT:
s.quit(cmd.client, cmd.args)
}
}
}
func (s *server) newClient(conn net.Conn) {
log.Printf("new client has connected: %s", conn.RemoteAddr().String())
c := &client{
conn: conn,
nick: "anonymous",
commands: s.commands,
}
c.readInput()
}
func (s *server) nick(c *client, args []string) {
c.nick = args[1]
c.msg(fmt.Sprintf("all rigth, I will cal you %s", c.nick))
}
func (s *server) join(c *client, args []string) {
roomName := args[1]
r, ok := s.rooms[roomName]
if !ok {
r = &room{
name: roomName,
members: make(map[net.Addr]*client),
}
s.rooms[roomName] = r
}
r.members[c.conn.RemoteAddr()] = c
if c.room != nil {
s.quitCurrentRoom(c)
}
c.room = r
r.broadcast(c, fmt.Sprintf("%s has joined the room", c.nick))
c.msg(fmt.Sprintf("welcome to %s", r.name))
}
func (s *server) listRooms(c *client, args []string) {
var rooms []string
for name := range s.rooms {
rooms = append(rooms, name)
}
c.msg(fmt.Sprintf("available rooms are: %s", strings.Join(rooms, ", ")))
}
func (s *server) msg(c *client, args []string) {
if c.room == nil {
c.err(errors.New("you must join the room first"))
return
}
c.room.broadcast(c, c.nick+": "+strings.Join(args[1:len(args)], " "))
}
func (s *server) quit(c *client, args []string) {
log.Printf("client has disconnected: %s", c.conn.RemoteAddr().String())
s.quitCurrentRoom(c)
c.msg("sad to see yo go :(")
c.conn.Close()
}
func (s *server) quitCurrentRoom(c *client) {
if c.room != nil {
delete(c.room.members, c.conn.RemoteAddr())
c.room.broadcast(c, fmt.Sprintf("%s has left the room", c.nick))
}
}
func newServer() *server {
return &server{
rooms: make(map[string]*room),
commands: make(chan command),
}
}