func (c *ircClient) SetReal(r string) string {
	c.mu.Lock()
	defer c.mu.Unlock()
	if r == "" {
		return c.realname
	}
	old := c.realname
	c.realname = r
	return old
}
Set realname, return old. "" for get only.
package ircd
import (
	"bufio"
	"fmt"
	"log"
	"net"
	"sync"
	"github.com/PacketFire/go-ircd/parser"
)
type Client interface {
	Nick() string  
	SetNick(nick string) string
	User() string  
	SetUser(user string) string
	Real() string  
	SetReal(realname string) string
	Host() string                                       
	Prefix() string                                     
	Send(prefix, command string, args ...string) error  
	Join(c Channel)                                     
	Part(c Channel)                                     
	Channels() []Channel                                
}
type ircClient struct {
	srv Server
	in   chan parser.Message
	out  chan parser.Message
	quit chan string
	con net.Conn
	inlines *bufio.Scanner
	welcome sync.Once
	quitonce sync.Once
	mu sync.RWMutex
	nick, user, realname string
	host                 string
	modes *Modeset
	channels map[string]Channel
}
func NewClient(srv Server, c net.Conn) *ircClient {
	cl := &ircClient{
		srv:      srv,
		in:       make(chan parser.Message, 10),
		out:      make(chan parser.Message, 10),
		quit:     make(chan string),
		con:      c,
		inlines:  bufio.NewScanner(c),
		modes:    NewModeset(),
		channels: make(map[string]Channel),
	}
	if c != nil {
		if tcpa, ok := c.RemoteAddr().(*net.TCPAddr); ok {
			cl.host = tcpa.IP.String()
		}
	}
	if cl.host == "" {
		cl.host = "UNKNOWN"
	}
	go cl.readin()
	go cl.loop()
	return cl
}
func (c *ircClient) readin() {
	defer c.con.Close()
	for c.inlines.Scan() {
		var m parser.Message
		if err := m.UnmarshalText(c.inlines.Bytes()); err != nil {
			Errorf(c, "malformed message")
		}
		c.in <- m
	}
	if err := c.inlines.Err(); err != nil {
		c.quitonce.Do(func() {
			c.quit <- fmt.Sprintf("read error: %s", err)
		})
	} else {
		c.quitonce.Do(func() {
			c.quit <- "EOF"
		})
	}
}
func (c *ircClient) loop() {
	for {
		select {
		case m := <-c.in:
			if err := c.srv.Handle(c, m); err != nil {
				Errorf(c, "%s", err)
			}
		case m := <-c.out:
			b, err := m.MarshalText()
			if err != nil {
				log.Printf("MarshalText: %s failed: %s", m, err)
				break
			}
			fmt.Fprintf(c.con, "%s\r\n", b)
		case why := <-c.quit:
			log.Printf("%s QUIT: %s", c.Prefix(), why)
			for _, ch := range c.channels {
				ch.Send(c.Prefix(), "QUIT", why)
				ch.Part(c)
			}
			c.con.Close()
			c.srv.RemoveClient(c)
			return
		}
	}
}
const (
	CNick = iota
	CUser
	CReal
	CHost
)
func (c *ircClient) Str(op int, nw string) (old string) {
	c.mu.RLock()
	switch op {
	case CNick:
		old = c.nick
	case CUser:
		old = c.user
	case CReal:
		old = c.realname
	case CHost:
		old = c.host
	}
	if nw == "" {
		c.mu.RUnlock()
		return
	}
	c.mu.RUnlock()
	c.mu.Lock()
	defer c.mu.Unlock()
	switch op {
	case CNick:
		c.nick = nw
	case CUser:
		c.user = nw
	case CReal:
		c.realname = nw
	case CHost:
		c.host = nw
	}
	return
}
func (c *ircClient) Nick() string {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.nick
}
func (c *ircClient) SetNick(n string) string {
	c.mu.Lock()
	defer c.mu.Unlock()
	if n == "" {
		return c.nick
	}
	old := c.nick
	c.nick = n
	return old
}
func (c *ircClient) User() string {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.user
}
func (c *ircClient) SetUser(u string) string {
	c.mu.Lock()
	defer c.mu.Unlock()
	if u == "" {
		return c.user
	}
	old := c.user
	c.user = u
	return old
}
func (c *ircClient) Real() string {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.realname
}