client.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. package server
  2. import (
  3. // "fmt"
  4. "net"
  5. "time"
  6. // "errors"
  7. // "io"
  8. "github.com/beoran/woe/monolog"
  9. "github.com/beoran/woe/telnet"
  10. "github.com/beoran/woe/world"
  11. )
  12. /* Specific properties of a client. */
  13. type ClientInfo struct {
  14. w int
  15. h int
  16. mtts int
  17. naws bool
  18. compress2 bool
  19. mssp bool
  20. zmp bool
  21. msp bool
  22. msdp bool
  23. mxp bool
  24. ttype bool
  25. terminals []string
  26. terminal string
  27. }
  28. type Client struct {
  29. server *Server
  30. id int
  31. conn net.Conn
  32. alive bool
  33. timeout int
  34. datachan chan []byte
  35. errchan chan error
  36. timechan chan time.Time
  37. telnet *telnet.Telnet
  38. info ClientInfo
  39. // Account of client or nil if not yet selected.
  40. account *world.Account
  41. // Character client is plaing with or nil if not yet selected.
  42. character *world.Character
  43. // Message channels that this client is listening to once fully logged in.
  44. // Not to be confused with Go channels.
  45. channels map[string]bool
  46. }
  47. func NewClient(server *Server, id int, conn net.Conn) *Client {
  48. datachan := make(chan []byte, 1024)
  49. errchan := make(chan error, 1)
  50. timechan := make(chan time.Time, 32)
  51. telnet := telnet.New()
  52. channels := make(map[string]bool)
  53. info := ClientInfo{w: -1, h: -1, terminal: "none"}
  54. return &Client{server, id, conn, true, -1, datachan, errchan, timechan, telnet, info, nil, nil, channels}
  55. }
  56. func (me *Client) Close() {
  57. me.conn.Close()
  58. me.alive = false
  59. if me.account != nil {
  60. me.server.World.RemoveAccount(me.account.Name)
  61. }
  62. me.account = nil
  63. }
  64. /** Goroutine that does the actual reading of input data, and sends it to the
  65. * needed channels. */
  66. func (me *Client) ServeRead() {
  67. for me.alive {
  68. buffer := make([]byte, 1024, 1024)
  69. read, err := me.conn.Read(buffer)
  70. if err != nil {
  71. me.errchan <- err
  72. return
  73. }
  74. // reply will be stored in me.telnet.Events channel
  75. me.telnet.ProcessBytes(buffer[:read])
  76. }
  77. }
  78. /* Goroutine that sends any data that must be sent through the Telnet protocol
  79. * to the connected client.
  80. */
  81. func (me *Client) ServeWrite() {
  82. for me.alive {
  83. select {
  84. case data := <-me.telnet.ToClient:
  85. monolog.Log("SERVEWRITE", "Will send to client: %v", data)
  86. me.conn.Write(data)
  87. }
  88. }
  89. }
  90. func (me *Client) TryReadEvent(millis int) (event telnet.Event, timeout bool, close bool) {
  91. var timerchan <-chan (time.Time)
  92. if millis >= 0 {
  93. timerchan = time.Tick(time.Millisecond * time.Duration(millis))
  94. } else {
  95. /* If time is negative, block by using a fake time channel that never gets sent anyting */
  96. timerchan = make(<-chan (time.Time))
  97. }
  98. select {
  99. case event := <-me.telnet.Events:
  100. return event, false, false
  101. case err := <-me.errchan:
  102. monolog.Info("Connection closed: %s\n", err)
  103. me.Close()
  104. return nil, false, true
  105. case _ = <-timerchan:
  106. return nil, true, false
  107. }
  108. }
  109. func (me *Client) HandleNAWSEvent(nawsevent *telnet.NAWSEvent) {
  110. me.info.w = nawsevent.W
  111. me.info.h = nawsevent.H
  112. monolog.Info("Client %d window size #{%d}x#{%d}", me.id, me.info.w, me.info.h)
  113. me.info.naws = true
  114. }
  115. func (me *Client) TryRead(millis int) (data []byte, timeout bool, close bool) {
  116. for me.alive {
  117. event, timeout, close := me.TryReadEvent(millis)
  118. if event == nil && (timeout || close) {
  119. return nil, timeout, close
  120. }
  121. switch event := event.(type) {
  122. case *telnet.DataEvent:
  123. monolog.Log("TELNETDATAEVENT", "Telnet data event %T : %d.", event, len(event.Data))
  124. return event.Data, false, false
  125. case *telnet.NAWSEvent:
  126. monolog.Log("TELNETNAWSEVENT", "Telnet NAWS event %T.", event)
  127. me.HandleNAWSEvent(event)
  128. default:
  129. monolog.Info("Ignoring telnet event %T : %v for now.", event, event)
  130. }
  131. }
  132. return nil, false, true
  133. }
  134. func (me *Client) Serve() (err error) {
  135. // buffer := make([]byte, 1024, 1024)
  136. go me.ServeWrite()
  137. go me.ServeRead()
  138. me.SetupTelnet()
  139. if me.server.World != nil {
  140. me.Printf(me.server.World.MOTD)
  141. }
  142. if !me.AccountDialog() {
  143. time.Sleep(3)
  144. // sleep so output gets flushed, hopefully.
  145. // Also slow down brute force attacks.
  146. me.Close()
  147. return nil
  148. }
  149. if !me.CharacterDialog() {
  150. time.Sleep(3)
  151. // sleep so output gets flushed, hopefully.
  152. // Also slow down brute force attacks.
  153. me.Close()
  154. return nil
  155. }
  156. me.Printf("Welcome, %s\n", me.account.Name)
  157. for me.alive {
  158. me.HandleCommand()
  159. /*
  160. data, _, _ := me.TryRead(3000)
  161. if data == nil {
  162. // me.telnet.TelnetPrintf("Too late!\r\n")
  163. } else {
  164. me.server.Broadcast(string(data))
  165. }
  166. */
  167. }
  168. return nil
  169. }
  170. func (me *Client) Disconnect() {
  171. me.alive = false
  172. }
  173. func (me *Client) IsAlive() bool {
  174. return me.alive
  175. }
  176. func (me *Client) IsLoginFinished() bool {
  177. return me.IsAlive() && (me.account != nil) && (me.character != nil)
  178. }
  179. func (me *Client) SetChannel(channelname string, value bool) {
  180. me.channels[channelname] = value
  181. }
  182. func (me *Client) IsListeningToChannel(channelname string) bool {
  183. res, ok := me.channels[channelname]
  184. // All chanels are active by default, and must be actively disabled by the client.
  185. if ok && (!res) {
  186. return false
  187. }
  188. return true
  189. }
  190. func (me *Client) WriteString(str string) {
  191. me.conn.Write([]byte(str))
  192. }
  193. /** Accessor */
  194. func (me *Client) GetServer() *Server {
  195. return me.server
  196. }
  197. /** Accessor */
  198. func (me *Client) GetWorld() *world.World {
  199. return me.server.World
  200. }
  201. /** Accessor */
  202. func (me *Client) GetAccount() *world.Account {
  203. return me.account
  204. }