This repository has been archived by the owner on Nov 22, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
player.go
97 lines (86 loc) · 2.26 KB
/
player.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
/*
Lighthouse
Copyright (C) 2021 Nathanael Bracy
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package main
import (
"bufio"
"net"
"sync"
)
// Player describes a Player.
type Player interface {
PlayerStats
// Send sends a message to a Player.
Send(msg []byte)
// Shutdown closes the Player's connection.
Shutdown()
}
// iPlayer implements Player.
type iPlayer struct {
sync.RWMutex
iPlayerStats
// Player's network connection.
conn net.Conn
// Messages waiting to be sent to a player.
msgqueue chan []byte
}
// NewPlayer creates a new Player from a network connection,
// and serves it.
func NewPlayer(conn net.Conn, mud MUD) Player {
// Create a new Player.
p := &iPlayer{conn: conn, msgqueue: make(chan []byte)}
// Serve them.
p.Serve(mud)
// Send welcome message.
p.Send(WELCOME_MSG)
// Send welcome prompt.
p.Send(WELCOME_PROMPT)
return p
}
// Send sends a message to a Player.
func (p *iPlayer) Send(msg []byte) {
p.msgqueue <- msg
}
// Serve serves a Player.
func (p *iPlayer) Serve(mud MUD) {
// Listen for input.
go func() {
reader := bufio.NewReader(p.conn)
var str string; var err error
for {
// Read one line of input.
str, err = reader.ReadString('\n')
// Relay the input, along with any error we encountered, to the MUD for processing.
mud.Process(NewMessage(err, str, p))
// Exit if we encountered an error.
if err != nil { return }
}
}()
// Send output.
go func() {
var err error
for {
if _, err = p.conn.Write(<-p.msgqueue); err != nil {
// Relay the error to the MUD.
mud.Process(NewMessage(err, "", p))
// Exit.
return
}
}
}()
}
// Shutdown shuts a Player down.
func (p *iPlayer) Shutdown() {
go p.conn.Close()
}