Enforce unique usernames
This commit is contained in:
parent
edeb5806d9
commit
16fce188d3
2 changed files with 65 additions and 12 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.rocket9labs.com/tslocum/bgammon"
|
||||
)
|
||||
|
@ -19,6 +20,7 @@ type serverClient struct {
|
|||
lastPing int64
|
||||
commands <-chan []byte
|
||||
playerNumber int
|
||||
terminating bool
|
||||
bgammon.Client
|
||||
}
|
||||
|
||||
|
@ -133,3 +135,21 @@ func (c *serverClient) label() string {
|
|||
}
|
||||
return strconv.Itoa(c.id)
|
||||
}
|
||||
|
||||
func (c *serverClient) Terminate(reason string) {
|
||||
if c.Terminated() || c.terminating {
|
||||
return
|
||||
}
|
||||
c.terminating = true
|
||||
|
||||
var extra string
|
||||
if reason != "" {
|
||||
extra = ": " + reason
|
||||
}
|
||||
c.sendNotice("Connection terminated" + extra)
|
||||
|
||||
go func() {
|
||||
time.Sleep(time.Second)
|
||||
c.Client.Terminate(reason)
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -67,6 +67,16 @@ func (s *server) handleListener(listener net.Listener) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *server) nameAvailable(username []byte) bool {
|
||||
lower := bytes.ToLower(username)
|
||||
for _, c := range s.clients {
|
||||
if bytes.Equal(bytes.ToLower(c.name), lower) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *server) addClient(c *serverClient) {
|
||||
s.clientsLock.Lock()
|
||||
defer s.clientsLock.Unlock()
|
||||
|
@ -197,9 +207,14 @@ func (s *server) handleNewClientIDs() {
|
|||
}
|
||||
|
||||
func (s *server) randomUsername() []byte {
|
||||
// TODO check if username is available
|
||||
i := 100 + rand.Intn(900)
|
||||
return []byte(fmt.Sprintf("Guest%d", i))
|
||||
for {
|
||||
i := 100 + rand.Intn(900)
|
||||
name := []byte(fmt.Sprintf("Guest%d", i))
|
||||
|
||||
if s.nameAvailable(name) {
|
||||
return name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) sendHello(c *serverClient) {
|
||||
|
@ -250,18 +265,40 @@ COMMANDS:
|
|||
// Require users to send login command first.
|
||||
if cmd.client.account == -1 {
|
||||
if keyword == bgammon.CommandLogin || keyword == bgammon.CommandLoginJSON || keyword == "l" || keyword == "lj" {
|
||||
if keyword == bgammon.CommandLoginJSON || keyword == "lj" {
|
||||
cmd.client.json = true
|
||||
}
|
||||
|
||||
s.clientsLock.Lock()
|
||||
|
||||
var username []byte
|
||||
var password []byte
|
||||
readUsername := func() bool {
|
||||
username = params[0]
|
||||
if !s.nameAvailable(username) {
|
||||
cmd.client.Terminate("Username unavailable.")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
switch len(params) {
|
||||
case 0:
|
||||
username = s.randomUsername()
|
||||
case 1:
|
||||
username = params[0]
|
||||
if !readUsername() {
|
||||
s.clientsLock.Unlock()
|
||||
continue
|
||||
}
|
||||
default:
|
||||
username = params[0]
|
||||
if !readUsername() {
|
||||
s.clientsLock.Unlock()
|
||||
continue
|
||||
}
|
||||
password = bytes.Join(params[1:], []byte(" "))
|
||||
}
|
||||
|
||||
s.clientsLock.Unlock()
|
||||
|
||||
if len(password) > 0 {
|
||||
cmd.client.account = 1
|
||||
} else {
|
||||
|
@ -269,10 +306,6 @@ COMMANDS:
|
|||
}
|
||||
cmd.client.name = username
|
||||
|
||||
if keyword == bgammon.CommandLoginJSON || keyword == "lj" {
|
||||
cmd.client.json = true
|
||||
}
|
||||
|
||||
cmd.client.sendEvent(&bgammon.EventWelcome{
|
||||
PlayerName: string(cmd.client.name),
|
||||
Clients: len(s.clients),
|
||||
|
@ -281,10 +314,10 @@ COMMANDS:
|
|||
|
||||
log.Printf("Client %d logged in as %s", cmd.client.id, cmd.client.name)
|
||||
continue
|
||||
} else {
|
||||
cmd.client.Terminate("You must login before using other commands.")
|
||||
continue
|
||||
}
|
||||
|
||||
cmd.client.Terminate("You must login before using other commands.")
|
||||
continue
|
||||
}
|
||||
|
||||
clientGame := s.gameByClient(cmd.client)
|
||||
|
|
Loading…
Reference in a new issue