client.go 5.4 KB

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