123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838 |
- package funmow
-
- import (
- "bufio"
- "fmt"
- "log"
- "net"
- "regexp"
- "strings"
- "unicode"
- )
-
- type Client struct {
- conn net.Conn
- connectionID int
- player Object
- authenticated bool
- connected bool
- reader *bufio.Reader
- commandChan chan string
- inbound chan PlayerEvent
- outbound EventChanSet
- eventDistributor *EventDistributor
- db *DB
- factory *ObjectFactory
- }
-
- func NewClient(conn net.Conn, connectionID int, e *EventDistributor, w *DB) *Client {
- c := new(Client)
- c.conn = conn
- c.connectionID = connectionID
- c.reader = bufio.NewReader(conn)
- c.authenticated = false
- c.connected = true
- c.commandChan = make(chan string)
- c.inbound = make(chan PlayerEvent)
- c.eventDistributor = e
- c.db = w
- c.factory = NewObjectFactory(w)
-
- return c
- }
-
- func (c *Client) Run() {
-
- log.Print("Received connection from ", c.conn.RemoteAddr())
-
- go func() {
- for c.connected {
- message, err := c.reader.ReadString('\n')
- if err != nil {
- c.connected = false
- return
- }
- message = strings.TrimSpace(message)
- if len(message) > 0 {
- c.commandChan <- message
- }
- }
- }()
-
- c.splash()
-
- for c.connected {
- select {
- case m := <-c.inbound:
- inside, _ := c.db.GetParent(c.player.ID)
- switch m.messageType {
- case EventTypeEmit:
- fallthrough
- case EventTypeOEmit:
- if m.audience == inside {
- c.write("%s\n", m.message)
- }
- case EventTypePEmit:
- c.write("%s\n", m.message)
- case EventTypeWall:
- speaker, found := c.db.Fetch(m.src)
- if !found {
- break
- }
- c.write("In the distance, you hear %s bellow out \"%s\"\n", speaker.Name, m.message)
- case EventTypePage:
- speaker, found := c.db.Fetch(m.src)
- if !found {
- break
- }
- c.write("%s pages you: \"%s\"\n", speaker.Name, m.message)
- case EventTypeSay:
- if m.audience == inside {
- if m.src == c.player.ID {
- c.write("You say \"%s\"\n", m.message)
- } else {
- speaker, found := c.db.Fetch(m.src)
- if !found {
- break
- }
- c.write("%s says \"%s\"\n", speaker.Name, m.message)
- }
- }
- case EventTypePose:
- if m.audience == inside {
- if m.src == c.player.ID {
- c.write("%s %s\n", c.player.Name, m.message)
- } else {
- speaker, found := c.db.Fetch(m.src)
- if !found {
- break
- }
- c.write("%s %s\n", speaker.Name, m.message)
- }
- }
- }
- case cmd := <-c.commandChan:
- if c.authenticated {
- c.handlePlayPhase(cmd)
- } else {
- c.handleLoginPhase(cmd)
- }
- }
- }
- if c.authenticated {
- c.outbound.shutdownChan <- c.connectionID
- }
- c.conn.Close()
-
- log.Print("Lost connection from ", c.conn.RemoteAddr())
-
- }
-
- func (c *Client) splash() {
-
- c.write("Welcome to...\n")
- c.write(" ___ __ __ ___ __ __\n")
- c.write(" | __| _ _ _ _ | \\/ | / _ \\ \\ \\ / /\n")
- c.write(" | _| | || | | ' \\ | |\\/| | | (_) | \\ \\/\\/ /\n")
- c.write(" |_| \\_,_| |_||_| |_| |_| \\___/ \\_/\\_/\n\n")
- c.write("use connect <username> <password> to login.\n")
-
- }
-
- func (c *Client) handleLoginPhase(message string) {
-
- fields := strings.FieldsFunc(message, func(c rune) bool {
- return unicode.IsSpace(c)
- })
- switch fields[0] {
- case "help":
- c.write("Commands:\n\tcon[nect] <username>\n\tquit\n")
- case "con":
- fallthrough
- case "connect":
- if len(fields) == 3 {
- pID, err := c.db.GetPlayerID(fields[1])
- if err != nil {
- c.write("Bad username or password.\n")
- break
- }
- player, found := c.db.Fetch(pID)
- if !found {
- c.write("You appear to be having an existential crisis.\n")
- c.connected = false
- break
- }
-
- c.authenticated = true
- c.player = player
-
- // when a player authenticates, the ipc channels get turned on
- subReq := EventSubscribeRequest{
- connectionID: c.connectionID,
- playerID: c.player.ID,
- inbound: c.inbound,
- chanSet: make(chan EventChanSet),
- }
-
- c.outbound = c.eventDistributor.Subscribe(subReq)
-
- c.write("Welcome back, %s!\n", fields[1])
-
- c.lookCmd("")
-
- } else {
- c.write("What?\n")
- }
- case "quit":
- c.quitCmd()
- default:
- c.write("What?\n")
- }
-
- }
-
- func (c *Client) handlePlayPhase(message string) {
-
- switch {
- case message == "l":
- c.lookCmd("")
- case message == "look":
- c.lookCmd("")
- case strings.HasPrefix(message, "l "): // look at
- c.lookCmd(strings.TrimPrefix(message, "l "))
- case strings.HasPrefix(message, "look "): // look at
- c.lookCmd(strings.TrimPrefix(message, "look "))
- case strings.HasPrefix(message, "ex "):
- c.examineCmd(strings.TrimPrefix(message, "ex "))
- case strings.HasPrefix(message, "examine "):
- c.examineCmd(strings.TrimPrefix(message, "examine "))
- case strings.HasPrefix(message, "\""):
- c.sayCmd(strings.TrimPrefix(message, "\""))
- case strings.HasPrefix(message, "say "):
- c.sayCmd(strings.TrimPrefix(message, "say "))
- case strings.HasPrefix(message, ":"):
- c.poseCmd(strings.TrimPrefix(message, ":"))
- case strings.HasPrefix(message, "pose "):
- c.poseCmd(strings.TrimPrefix(message, "pose "))
- case message == "i":
- c.inventoryCmd()
- case message == "inventory":
- c.inventoryCmd()
- case strings.HasPrefix(message, "get "):
- c.getCmd(strings.TrimPrefix(message, "get "))
- case strings.HasPrefix(message, "drop "):
- c.dropCmd(strings.TrimPrefix(message, "drop "))
- case strings.HasPrefix(message, "enter "):
- c.enterCmd(strings.TrimPrefix(message, "enter "))
- case message == "leave":
- c.leaveCmd()
- case message == "quit":
- c.quitCmd()
- case message == "WHO":
- c.whoCmd()
- case strings.HasPrefix(message, "@create "):
- c.createCmd(strings.TrimPrefix(message, "@create "))
- case strings.HasPrefix(message, "@dig "):
- c.digCmd(message)
- case strings.HasPrefix(message, "@open "):
- c.openCmd(message)
- case strings.HasPrefix(message, "@name "):
- c.nameCmd(message)
- case strings.HasPrefix(message, "@desc "):
- c.descCmd(message)
- case strings.HasPrefix(message, "@tel "):
- c.telCmd(strings.TrimPrefix(message, "@tel "))
- case strings.HasPrefix(message, "@dump "):
- c.dumpCmd(strings.TrimPrefix(message, "@dump "))
- case strings.HasPrefix(message, "@destroy "):
- c.destroyCmd(strings.TrimPrefix(message, "@destroy "))
- default:
- if !c.goCmd(message) {
- c.write("What?\n")
- }
- }
-
- }
-
- func (c *Client) lookCmd(at string) {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- c.write("True Limbo (#NaN)\nThere's nothing to see here. You are inside an object that doesn't exist.\n")
- return
- }
-
- if len(at) > 0 {
- object, matchType := room.MatchLinkNames(at, c.player.ID, false).ExactlyOne()
- switch matchType {
- case MatchOne:
- c.write("%s\n%s\n", object.DetailedName(), object.Description)
- case MatchNone:
- c.write("I don't see that here.\n")
- case MatchMany:
- c.write("I don't now which one you're trying to look at.\n")
- }
- } else {
- c.write("%s\n%s\n", room.DetailedName(), room.Description)
- c.lookLinks(&room, "thing", "Things:")
- c.lookLinks(&room, "player", "Players:")
- exits := room.GetLinkNames("exit", nil)
- if len(exits) > 0 {
- c.write("Exits:\n")
- for _, e := range exits {
- aliases := strings.Split(e, ";")
- c.write("%s ", aliases[0])
- }
- c.write("\n")
- }
- }
-
- }
-
- func (c *Client) objectName(id DBRef) string {
- o, found := c.db.Fetch(id)
- if found {
- return o.DetailedName()
- } else {
- return fmt.Sprintf("MISSING OBJECT (#%d)", id)
- }
- }
-
- func (c *Client) examineCmd(at string) {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- object, matchType := room.MatchLinkNames(at, c.player.ID, false).ExactlyOne()
-
- switch matchType {
- case MatchOne:
-
- objectParentID, _ := c.db.GetParent(object.ID)
-
- c.write("%s\n", object.DetailedName())
- c.write("ID: %d\n", object.ID)
- c.write("Type: %s\n", object.Type)
- c.write("@name: %s\n", object.Name)
- c.write("@desc: %s\n", object.Description)
- c.write("Inside: %s\n", c.objectName(objectParentID))
- c.write("Next: %s\n", c.objectName(object.Next))
- c.write("Owner: %s\n", c.objectName(object.Owner))
-
- inventory := object.GetLinkNames("*", nil)
- if len(inventory) > 0 {
- c.write("Contents:\n %s\n", strings.Join(inventory, "\n "))
- }
- case MatchNone:
- c.write("I don't see that here.\n")
- case MatchMany:
- c.write("I don't know which one you're trying to examine.\n")
- }
-
- }
-
- func (c *Client) lookLinks(o *Object, linkType string, pretty string) {
-
- linknames := o.GetLinkNames(linkType, DBRefList{c.player.ID})
-
- if len(linknames) > 0 {
- c.write("%s\n %s\n", pretty, strings.Join(linknames, "\n "))
- }
-
- }
-
- func (c *Client) sayCmd(message string) {
-
- inside, _ := c.db.GetParent(c.player.ID)
- c.outbound.messageChan <- PlayerEvent{audience: inside, src: c.player.ID, message: message, messageType: EventTypeSay}
-
- }
-
- func (c *Client) poseCmd(message string) {
-
- inside, _ := c.db.GetParent(c.player.ID)
- c.outbound.messageChan <- PlayerEvent{audience: inside, src: c.player.ID, dst: c.player.ID, message: message, messageType: EventTypePose}
-
- }
-
- func (c *Client) inventoryCmd() {
-
- inventory := c.player.GetLinkNames("*", nil)
-
- if len(inventory) > 0 {
- c.write("Inventory:\n %s\n", strings.Join(inventory, "\n "))
- } else {
- c.write("You're not carrying anything.\n")
- }
-
- }
-
- func (c *Client) getCmd(message string) {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- object, matchType := room.MatchLinkNames(message, c.player.ID, true).ExactlyOne()
-
- switch matchType {
- case MatchOne:
- err := c.player.Contains(&object)
- if err != nil {
- return
- }
- c.player.Refresh()
- c.write("You pick up %s.\n", object.Name)
- c.oemit(room.ID, "%s picks up %s.", c.player.Name, object.Name)
- case MatchNone:
- c.write("I don't see that here.\n")
- case MatchMany:
- c.write("I don't know which one.\n")
- }
-
- }
-
- func (c *Client) dropCmd(message string) {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- object, matchType := c.player.MatchLinkNames(message, c.player.ID, false).ExactlyOne()
-
- switch matchType {
- case MatchOne:
- err := room.Contains(&object)
- if err != nil {
- return
- }
- inside, _ := c.db.GetParent(c.player.ID)
- c.player.Refresh()
- c.write("You drop %s.\n", object.Name)
- c.oemit(inside, "%s drops %s.", c.player.Name, object.Name)
- case MatchNone:
- c.write("You're not carrying that.\n")
- case MatchMany:
- c.write("I don't now which one.\n")
- }
-
- }
-
- func (c *Client) enterCmd(message string) {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- object, matchType := room.MatchLinkNames(message, c.player.ID, true).ExactlyOne()
-
- switch matchType {
- case MatchOne:
- err := object.Contains(&c.player)
- if err != nil {
- return
- }
- c.player.Refresh()
- c.write("You climb into %s.\n", object.Name)
- c.oemit(room.ID, "%s climbs into %s.", c.player.Name, object.Name)
- c.oemit(object.ID, "%s squeezes into %s with you.", c.player.Name, object.Name)
- case MatchNone:
- c.write("I don't see that here.\n")
- case MatchMany:
- c.write("I don't now which one.\n")
- }
- }
-
- func (c *Client) leaveCmd() {
-
- inside, _ := c.db.GetParent(c.player.ID)
- object, found := c.db.Fetch(inside)
- if !found {
- return
- }
- objectInside, _ := c.db.GetParent(inside)
- if objectInside == 0 { // probably trying to 'leave' a room
- c.write("You can't leave here.\n")
- return
- }
-
- room, found := c.db.Fetch(objectInside)
- if !found {
- return
- }
-
- err := room.Contains(&c.player)
- if err != nil {
- return
- }
-
- c.player.Refresh()
-
- c.write("You climb out of %s.\n", object.Name)
- c.oemit(object.ID, "%s climbs out of %s.", c.player.Name, object.Name)
- c.oemit(room.ID, "%s climbs out of %s.", c.player.Name, object.Name)
-
- }
-
- func (c *Client) quitCmd() {
-
- c.write("So long, it's been good to know yah.\n")
- c.connected = false
-
- }
-
- func (c *Client) whoCmd() {
- // onlinePlayers := c.eventDistributor.OnlinePlayers()
-
- c.write("Currently Online:\n")
-
- //for _, ref := range onlinePlayers {
- // c.write("%s\n", c.db.GetName(ref))
- //}
- }
-
- func (c *Client) createCmd(message string) {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- o := c.factory.NewThing()
- o.Name = strings.TrimSpace(message)
- o.Owner = c.player.ID
- o.Commit()
-
- err := room.Contains(&o)
- if err != nil {
- return
- }
-
- c.emit(room.ID, "A %s appears out of the ether.", o.Name)
- c.write("%s Created.\n", o.DetailedName())
-
- }
-
- func (c *Client) openCmd(input string) {
- // @open <in1;in2;in3;etc>=#<room>,<out1;out2;out3;etc>
-
- r, _ := regexp.Compile(`^@open\pZ+([^=]*[^=\pZ]+)\pZ*=#([0-9]+)(?:\pZ*,\pZ*([^,]*[^,\pZ]+)\pZ*)?`)
- params := r.FindStringSubmatch(input)
-
- if params == nil {
- return
- }
-
- inExit, roomIDStr, outExit := params[1], params[2], params[3]
-
- if len(inExit) == 0 || len(roomIDStr) == 0 {
- c.write("Bad command or file name.\n")
- return
- }
-
- targetID, _ := NewDBRefFromString(roomIDStr) // this will never fail, the regexp guarantees that
- targetRoom, found := c.db.Fetch(targetID)
- if !found {
- c.write("Target not found.\n")
- return
- }
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- toExit := c.factory.NewExit(inExit, targetRoom.ID, c.player.ID)
- toExit.Commit()
- err := room.Contains(&toExit)
- if err != nil {
- return
- }
- c.write("%s Created.\n", toExit.DetailedName())
-
- if len(outExit) > 0 {
- fromExit := c.factory.NewExit(outExit, room.ID, c.player.ID)
- fromExit.Commit()
- err = targetRoom.Contains(&fromExit)
- if err != nil {
- return
- }
- c.write("%s Created.\n", fromExit.DetailedName())
- }
-
- }
-
- func (c *Client) digCmd(input string) {
- // @dig <Room name>=<in1;in2;in3;etc>,<out1;out2;out3;etc>
- //@dig foo bar = <F>oo;foo;f,<B>ack;back;b
-
- r, _ := regexp.Compile(`^@dig\pZ+([^=]*[^=\pZ]+)(\pZ*=\pZ*(?:([^,]*[^,\pZ]+)\pZ*)?(?:\pZ*,\pZ*([^,]*[^,\pZ]+)\pZ*)?)?`)
- params := r.FindStringSubmatch(input)
- if params == nil {
- return
- }
-
- roomName, inExit, outExit := params[1], params[2], params[3]
-
- if len(roomName) == 0 {
- c.write("Rooms can't not have names.\n")
- return
- }
-
- newRoom := c.factory.NewRoom()
- newRoom.Name = roomName
- newRoom.Owner = c.player.ID
- newRoom.Commit()
-
- c.write("%s Created.\n", newRoom.DetailedName())
-
- if len(inExit) > 0 || len(outExit) > 0 {
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
- if len(inExit) > 0 {
- toExit := c.factory.NewExit(inExit, newRoom.ID, c.player.ID)
- toExit.Commit()
- err := room.Contains(&toExit)
- if err != nil {
- return
- }
- c.write("%s Created.\n", toExit.DetailedName())
- }
- if len(outExit) > 0 {
- fromExit := c.factory.NewExit(outExit, room.ID, c.player.ID)
- fromExit.Commit()
- err := newRoom.Contains(&fromExit)
- if err != nil {
- return
- }
- c.write("%s Created.\n", fromExit.DetailedName())
- }
- }
-
- }
-
- func (c *Client) nameCmd(input string) {
-
- r, _ := regexp.Compile(`^@name\pZ+([^=]*[^=\pZ]{1})\pZ*=\pZ*(.*)\pZ*$`)
- params := r.FindStringSubmatch(input)
- if params == nil {
- return
- }
-
- objectName, name := params[1], params[2]
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- candidate, matchType := room.MatchLinkNames(objectName, c.player.ID, false).ExactlyOne()
- switch matchType {
- case MatchOne:
- candidate.Name = name
- candidate.Commit()
- c.write("Name set.\n")
- c.player.Refresh()
- case MatchNone:
- c.write("I don't see that here.\n")
- case MatchMany:
- c.write("I don't now which one.\n")
- }
-
- }
-
- func (c *Client) descCmd(input string) {
-
- r, _ := regexp.Compile(`^@desc\pZ+([^=]*[^=\pZ]{1})\pZ*=\pZ*(.*)\pZ*$`)
- params := r.FindStringSubmatch(input)
- if params == nil {
- return
- }
-
- objectName, description := params[1], params[2]
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
-
- if !found {
- return
- }
-
- var editObject *Object
- switch objectName {
- case "here":
- editObject = &room
- case "me":
- editObject = &c.player
- default:
- candidate, matchType := room.MatchLinkNames(objectName, c.player.ID, false).ExactlyOne()
- switch matchType {
- case MatchOne:
- editObject = &candidate
- case MatchNone:
- c.write("I don't see that here.\n")
- return
- case MatchMany:
- c.write("I don't now which one.\n")
- return
- }
- }
-
- editObject.Description = description
- editObject.Commit()
- c.player.Refresh()
- c.write("Description set.\n")
-
- }
-
- func (c *Client) telCmd(destStr string) {
-
- dest, err := NewDBRefFromHashRef(destStr)
-
- if err != nil {
- c.write("That doesn't look like a DBRef.\n")
- return
- }
-
- newRoom, found := c.db.Fetch(dest)
- if !found {
- c.write("That doesn't exist.\n")
- return
- }
-
- c.write("You feel an intense wooshing sensation.\n")
- err = newRoom.Contains(&c.player)
- if err != nil {
- return
- }
-
- c.player.Refresh()
- c.lookCmd("")
-
- }
-
- func (c *Client) dumpCmd(refStr string) {
-
- ref, err := NewDBRefFromHashRef(refStr)
-
- if err != nil {
- c.write("That doesn't look like a DBRef.\n")
- return
- }
-
- obj, found := c.db.Fetch(ref)
- if !found {
- c.write("That doesn't exist.\n")
- return
- }
-
- c.write("%s\n", c.db.DumpObject(obj.ID))
-
- }
-
- func (c *Client) destroyCmd(message string) {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return
- }
-
- object, matchType := room.MatchLinkNames(message, c.player.ID, true).ExactlyOne()
-
- switch matchType {
- case MatchOne:
- name := object.DetailedName()
- err := object.Delete()
- if err == nil {
- c.player.Refresh()
- c.write("%s vanishes into thin air.\n", name)
- }
- case MatchNone:
- c.write("I don't see that here.\n")
- case MatchMany:
- c.write("I don't know which one.\n")
- }
-
- }
-
- func (c *Client) goCmd(dir string) bool {
-
- roomID, found := c.db.GetParent(c.player.ID)
- room, found := c.db.Fetch(roomID)
- if !found {
- return false
- }
-
- exit, matchType := room.MatchExitNames(dir).ExactlyOne()
- switch matchType {
- case MatchOne:
- if exit.Next.Valid() {
- newRoom, found := c.db.Fetch(exit.Next)
- if !found {
- c.write("That exit appears to be broken!\n")
- return true
- }
- err := newRoom.Contains(&c.player)
- if err != nil {
- return false
- }
- c.player.Refresh()
- c.write("You head towards %s.\n", newRoom.Name)
- c.oemit(room.ID, "%s leaves the room.", c.player.Name)
- c.oemit(newRoom.ID, "%s enters the room.", c.player.Name)
- return true
- }
- case MatchNone:
- return false
- case MatchMany:
- c.write("Ambiguous exit names are ambiguous.\n")
- return true
- }
-
- return false
-
- }
-
- func (c *Client) oemit(audience DBRef, format string, a ...interface{}) {
-
- message := fmt.Sprintf(format, a...)
- c.outbound.messageChan <- PlayerEvent{audience: audience, src: c.player.ID, dst: c.player.ID, message: message, messageType: EventTypeOEmit}
-
- }
-
- func (c *Client) write(format string, a ...interface{}) {
-
- fmt.Fprintf(c.conn, format, a...)
-
- }
-
- func (c *Client) pemit(audience DBRef, format string, a ...interface{}) {
-
- message := fmt.Sprintf(format, a...)
- c.outbound.messageChan <- PlayerEvent{audience: audience, src: c.player.ID, dst: c.player.ID, message: message, messageType: EventTypePEmit}
-
- }
-
- func (c *Client) emit(audience DBRef, format string, a ...interface{}) {
-
- message := fmt.Sprintf(format, a...)
- c.outbound.messageChan <- PlayerEvent{audience: audience, src: c.player.ID, dst: c.player.ID, message: message, messageType: EventTypeEmit}
-
- }
|