WIP on emotes; need to fix client side / command verb parsing
parent
e085fa0fd1
commit
6d6e6d5726
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue