diff --git a/client/cmd/main.go b/client/cmd/main.go index e333d2e..a203456 100644 --- a/client/cmd/main.go +++ b/client/cmd/main.go @@ -60,6 +60,7 @@ func (cs *ClientState) HandleInput(input string) error { var verb string rest := input if strings.HasPrefix(input, "/") { + // TODO this is def broken lol input = input[1:] parts := strings.SplitN(input, " ", 1) verb = parts[0] @@ -105,7 +106,14 @@ func (cs *ClientState) AddMessage(msg *proto.ClientMessage) { // TODO look into using the SetChangedFunc thing. cs.App.QueueUpdateDraw(func() { // TODO trim content of messagesView /or/ see if tview has a buffer size that does it for me. use cs.messages to re-constitute. - fmt.Fprintf(cs.messagesView, "%s: %s\n", msg.GetSpeaker(), msg.GetText()) + switch msg.Type { + case proto.ClientMessage_OVERHEARD: + fmt.Fprintf(cs.messagesView, "%s: %s\n", msg.GetSpeaker(), msg.GetText()) + case proto.ClientMessage_EMOTE: + fmt.Fprintf(cs.messagesView, "%s %s\n", msg.GetSpeaker(), msg.GetText()) + default: + fmt.Fprintf(cs.messagesView, "%#v\n", msg) + } cs.messagesView.ScrollToEnd() }) } diff --git a/server/cmd/main.go b/server/cmd/main.go index b62c02f..92d55d4 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -110,32 +110,44 @@ func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Objec var err error sid, _ := s.db.SessionIDForAvatar(target) - tell := func(_ int, _ string) {} + serverAPI := witch.ServerAPI{ + Show: func(_ int, _ string) {}, + Tell: func(_ int, _ string) {}, + } if sid != "" { send := s.msgRouter[sid] - tell = func(senderID int, msg string) { + getSenderName := func(senderID int) *string { senderName := "a mysterious stranger" sender, err := s.db.GetObjectByID(senderID) if err == nil { - log.Printf("%#v", sender) senderName = sender.Data["name"] } else { log.Println(err.Error()) } + return &senderName + } + serverAPI.Show = func(senderID int, msg string) { + cm := proto.ClientMessage{ + Type: proto.ClientMessage_EMOTE, + Text: msg, + Speaker: getSenderName(senderID), + } + send(&cm) + } + serverAPI.Tell = func(senderID int, msg string) { cm := proto.ClientMessage{ Type: proto.ClientMessage_OVERHEARD, Text: msg, - Speaker: &senderName, + Speaker: getSenderName(senderID), } - send(&cm) } } if !ok { - sc, err = witch.NewScriptContext(tell) + sc, err = witch.NewScriptContext(serverAPI) if err != nil { return err } @@ -161,26 +173,6 @@ func (s *gameWorldServer) HandleCmd(verb, rest string, sender *db.Object) { // TODO } -/* - what's the flow for when i'm at a computer and type /say hi ? - - - server gets "SAY hi" from vilmibm - - server gets all objects in earshot (including vilmibm's avatar) - - for each object: - - call whatever handler it has for "hears" - - and then that's it, right? over in witch land: - - - hears handler for an avatar has: - - tellMe(sender.get("name") + " says " + msg) - - - tellMe somehow calls a method on the gameWorldServer that can look up a - session ID and thus use the msgRouter to send a message. I'm going to sleep - on this so I can think about the right way to structure those dependencies. - -*/ - func (s *gameWorldServer) Commands(stream proto.GameWorld_CommandsServer) error { var sid string for { @@ -220,42 +212,6 @@ func (s *gameWorldServer) Commands(stream proto.GameWorld_CommandsServer) error } //s.HandleCmd(cmd.Verb, cmd.Rest, avatar) - - /* - - switch cmd.Verb { - case "say": - if err = s.HandleSay(avatar, cmd.Rest); err != nil { - s.HandleError(func(_ *proto.ClientMessage) error { return nil }, err) - } - default: - msg := &proto.ClientMessage{ - Type: proto.ClientMessage_WHISPER, - Text: fmt.Sprintf("unknown verb: %s", cmd.Verb), - } - if err = send(msg); err != nil { - s.HandleError(send, err) - } - } - - */ - - /* - - msg := &proto.ClientMessage{ - Type: proto.ClientMessage_OVERHEARD, - Text: fmt.Sprintf("%s sent command %s with args %s", - sid, cmd.Verb, cmd.Rest), - } - - speaker := "ECHO" - msg.Speaker = &speaker - - err = send(msg) - if err != nil { - log.Printf("failed to send %v to %s: %s", msg, sid, err) - } - */ } } diff --git a/server/db/db.go b/server/db/db.go index 0b5a604..fcb0973 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -184,6 +184,10 @@ func (db *pgDB) createAccount(account *Account) (err error) { hears(".*", function() tellMe(msg) end) + +sees(".*", function() + showMe(msg) +end) `, hasInvocation(av)) stmt = "INSERT INTO objects ( avatar, data, owner, script ) VALUES ( $1, $2, $3, $4 ) RETURNING id" diff --git a/server/witch/header.go b/server/witch/header.go index ab1ba13..9a63386 100644 --- a/server/witch/header.go +++ b/server/witch/header.go @@ -9,17 +9,19 @@ import ( func witchHas(l *lua.LState) int { lv := l.ToTable(1) log.Println(lv) + // TODO return 0 } +// TODO provides + func witchHears(l *lua.LState) int { - // TODO register handler - handlers := l.GetGlobal("_handlers").(*lua.LTable) - log.Println(handlers) - pattern := l.ToString(1) - cb := l.ToFunction(2) - addHandler(l, "say", pattern, cb) - return 0 + return addHandler(l, "say") +} + +func witchSees(l *lua.LState) int { + log.Println("adding handler for emote") + return addHandler(l, "emote") } func witchDoes(ls *lua.LState) int { @@ -29,27 +31,10 @@ func witchDoes(ls *lua.LState) int { return 0 } -/* - string -> fn does not work because there might be multiple handlers for a given verb. +func addHandler(l *lua.LState, verb string) int { + pattern := l.ToString(1) + cb := l.ToFunction(2) - i can: - - have a list of handlers. call each one. it is the handler's - responsibility to decide if it's a match or not. - - store string -> map[string]fn. do the matching in Go. - - handlers = { - "hear" = { - "*eat*" = cbfn0 - "*slurp*" = cbfn1 - } - - "see" = { - "*fork*" = cbfn2 - } - } -*/ - -func addHandler(l *lua.LState, verb, pattern string, cb *lua.LFunction) int { handlers := l.GetGlobal("_handlers").(*lua.LTable) verbHandlers, ok := handlers.RawGetString(verb).(*lua.LTable) @@ -58,9 +43,6 @@ func addHandler(l *lua.LState, verb, pattern string, cb *lua.LFunction) int { handlers.RawSetString(verb, verbHandlers) } - log.Println("addHandler") - log.Printf("%#v", cb) - verbHandlers.RawSetString(pattern, cb) return 0 diff --git a/server/witch/witch.go b/server/witch/witch.go index ee6b82f..ea4d26e 100644 --- a/server/witch/witch.go +++ b/server/witch/witch.go @@ -23,6 +23,11 @@ end) ` */ +type ServerAPI struct { + Tell func(int, string) + Show func(int, string) +} + type VerbContext struct { Verb string Rest string @@ -31,14 +36,14 @@ type VerbContext struct { } type ScriptContext struct { - script string - incoming chan VerbContext - tell func(int, string) + script string + incoming chan VerbContext + serverAPI ServerAPI } -func NewScriptContext(tell func(int, string)) (*ScriptContext, error) { +func NewScriptContext(sAPI ServerAPI) (*ScriptContext, error) { sc := &ScriptContext{ - tell: tell, + serverAPI: sAPI, } sc.incoming = make(chan VerbContext) @@ -53,6 +58,7 @@ func NewScriptContext(tell func(int, string)) (*ScriptContext, error) { l = lua.NewState() l.SetGlobal("has", l.NewFunction(witchHas)) l.SetGlobal("hears", l.NewFunction(witchHears)) + l.SetGlobal("sees", l.NewFunction(witchSees)) l.SetGlobal("_handlers", l.NewTable()) if err := l.DoString(vc.Target.Script); err != nil { log.Printf("error parsing script %s: %s", vc.Target.Script, err.Error()) @@ -60,17 +66,22 @@ func NewScriptContext(tell func(int, string)) (*ScriptContext, error) { } l.SetGlobal("tellMe", l.NewFunction(func(l *lua.LState) int { - // TODO not getting senderID properly here sender := l.GetGlobal("sender").(*lua.LTable) senderID := int(lua.LVAsNumber(sender.RawGetString("ID"))) - msg := l.ToString(1) - log.Printf("%#v %s\n", sender, msg) - log.Println(senderID) - sc.tell(senderID, msg) + sc.serverAPI.Tell(senderID, l.ToString(1)) + return 0 + })) + + l.SetGlobal("showMe", l.NewFunction(func(l *lua.LState) int { + log.Println("showMe called") + sender := l.GetGlobal("sender").(*lua.LTable) + senderID := int(lua.LVAsNumber(sender.RawGetString("ID"))) + sc.serverAPI.Show(senderID, l.ToString(1)) return 0 })) // TODO check execute permission and bail out potentially + log.Printf("%#v", vc) senderT := l.NewTable() senderT.RawSetString("name", lua.LString(vc.Sender.Data["name"])) @@ -103,6 +114,5 @@ func NewScriptContext(tell func(int, string)) (*ScriptContext, error) { } func (sc *ScriptContext) Handle(vc VerbContext) { - log.Printf("%#v %#v", sc, vc) sc.incoming <- vc }