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
|
var verb string
|
||||||
rest := input
|
rest := input
|
||||||
if strings.HasPrefix(input, "/") {
|
if strings.HasPrefix(input, "/") {
|
||||||
|
// TODO this is def broken lol
|
||||||
input = input[1:]
|
input = input[1:]
|
||||||
parts := strings.SplitN(input, " ", 1)
|
parts := strings.SplitN(input, " ", 1)
|
||||||
verb = parts[0]
|
verb = parts[0]
|
||||||
|
@ -105,7 +106,14 @@ func (cs *ClientState) AddMessage(msg *proto.ClientMessage) {
|
||||||
// TODO look into using the SetChangedFunc thing.
|
// TODO look into using the SetChangedFunc thing.
|
||||||
cs.App.QueueUpdateDraw(func() {
|
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.
|
// 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()
|
cs.messagesView.ScrollToEnd()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,32 +110,44 @@ func (s *gameWorldServer) verbHandler(verb, rest string, sender, target db.Objec
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
sid, _ := s.db.SessionIDForAvatar(target)
|
sid, _ := s.db.SessionIDForAvatar(target)
|
||||||
tell := func(_ int, _ string) {}
|
serverAPI := witch.ServerAPI{
|
||||||
|
Show: func(_ int, _ string) {},
|
||||||
|
Tell: func(_ int, _ string) {},
|
||||||
|
}
|
||||||
if sid != "" {
|
if sid != "" {
|
||||||
send := s.msgRouter[sid]
|
send := s.msgRouter[sid]
|
||||||
tell = func(senderID int, msg string) {
|
getSenderName := func(senderID int) *string {
|
||||||
senderName := "a mysterious stranger"
|
senderName := "a mysterious stranger"
|
||||||
|
|
||||||
sender, err := s.db.GetObjectByID(senderID)
|
sender, err := s.db.GetObjectByID(senderID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Printf("%#v", sender)
|
|
||||||
senderName = sender.Data["name"]
|
senderName = sender.Data["name"]
|
||||||
} else {
|
} else {
|
||||||
log.Println(err.Error())
|
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{
|
cm := proto.ClientMessage{
|
||||||
Type: proto.ClientMessage_OVERHEARD,
|
Type: proto.ClientMessage_OVERHEARD,
|
||||||
Text: msg,
|
Text: msg,
|
||||||
Speaker: &senderName,
|
Speaker: getSenderName(senderID),
|
||||||
}
|
}
|
||||||
|
|
||||||
send(&cm)
|
send(&cm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
sc, err = witch.NewScriptContext(tell)
|
sc, err = witch.NewScriptContext(serverAPI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -161,26 +173,6 @@ func (s *gameWorldServer) HandleCmd(verb, rest string, sender *db.Object) {
|
||||||
// TODO
|
// 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 {
|
func (s *gameWorldServer) Commands(stream proto.GameWorld_CommandsServer) error {
|
||||||
var sid string
|
var sid string
|
||||||
for {
|
for {
|
||||||
|
@ -220,42 +212,6 @@ func (s *gameWorldServer) Commands(stream proto.GameWorld_CommandsServer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
//s.HandleCmd(cmd.Verb, cmd.Rest, avatar)
|
//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()
|
hears(".*", function()
|
||||||
tellMe(msg)
|
tellMe(msg)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
sees(".*", function()
|
||||||
|
showMe(msg)
|
||||||
|
end)
|
||||||
`, hasInvocation(av))
|
`, hasInvocation(av))
|
||||||
|
|
||||||
stmt = "INSERT INTO objects ( avatar, data, owner, script ) VALUES ( $1, $2, $3, $4 ) RETURNING id"
|
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 {
|
func witchHas(l *lua.LState) int {
|
||||||
lv := l.ToTable(1)
|
lv := l.ToTable(1)
|
||||||
log.Println(lv)
|
log.Println(lv)
|
||||||
|
// TODO
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO provides
|
||||||
|
|
||||||
func witchHears(l *lua.LState) int {
|
func witchHears(l *lua.LState) int {
|
||||||
// TODO register handler
|
return addHandler(l, "say")
|
||||||
handlers := l.GetGlobal("_handlers").(*lua.LTable)
|
}
|
||||||
log.Println(handlers)
|
|
||||||
pattern := l.ToString(1)
|
func witchSees(l *lua.LState) int {
|
||||||
cb := l.ToFunction(2)
|
log.Println("adding handler for emote")
|
||||||
addHandler(l, "say", pattern, cb)
|
return addHandler(l, "emote")
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func witchDoes(ls *lua.LState) int {
|
func witchDoes(ls *lua.LState) int {
|
||||||
|
@ -29,27 +31,10 @@ func witchDoes(ls *lua.LState) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func addHandler(l *lua.LState, verb string) int {
|
||||||
string -> fn does not work because there might be multiple handlers for a given verb.
|
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)
|
handlers := l.GetGlobal("_handlers").(*lua.LTable)
|
||||||
|
|
||||||
verbHandlers, ok := handlers.RawGetString(verb).(*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)
|
handlers.RawSetString(verb, verbHandlers)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("addHandler")
|
|
||||||
log.Printf("%#v", cb)
|
|
||||||
|
|
||||||
verbHandlers.RawSetString(pattern, cb)
|
verbHandlers.RawSetString(pattern, cb)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -23,6 +23,11 @@ end)
|
||||||
`
|
`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
type ServerAPI struct {
|
||||||
|
Tell func(int, string)
|
||||||
|
Show func(int, string)
|
||||||
|
}
|
||||||
|
|
||||||
type VerbContext struct {
|
type VerbContext struct {
|
||||||
Verb string
|
Verb string
|
||||||
Rest string
|
Rest string
|
||||||
|
@ -31,14 +36,14 @@ type VerbContext struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScriptContext struct {
|
type ScriptContext struct {
|
||||||
script string
|
script string
|
||||||
incoming chan VerbContext
|
incoming chan VerbContext
|
||||||
tell func(int, string)
|
serverAPI ServerAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewScriptContext(tell func(int, string)) (*ScriptContext, error) {
|
func NewScriptContext(sAPI ServerAPI) (*ScriptContext, error) {
|
||||||
sc := &ScriptContext{
|
sc := &ScriptContext{
|
||||||
tell: tell,
|
serverAPI: sAPI,
|
||||||
}
|
}
|
||||||
sc.incoming = make(chan VerbContext)
|
sc.incoming = make(chan VerbContext)
|
||||||
|
|
||||||
|
@ -53,6 +58,7 @@ func NewScriptContext(tell func(int, string)) (*ScriptContext, error) {
|
||||||
l = lua.NewState()
|
l = lua.NewState()
|
||||||
l.SetGlobal("has", l.NewFunction(witchHas))
|
l.SetGlobal("has", l.NewFunction(witchHas))
|
||||||
l.SetGlobal("hears", l.NewFunction(witchHears))
|
l.SetGlobal("hears", l.NewFunction(witchHears))
|
||||||
|
l.SetGlobal("sees", l.NewFunction(witchSees))
|
||||||
l.SetGlobal("_handlers", l.NewTable())
|
l.SetGlobal("_handlers", l.NewTable())
|
||||||
if err := l.DoString(vc.Target.Script); err != nil {
|
if err := l.DoString(vc.Target.Script); err != nil {
|
||||||
log.Printf("error parsing script %s: %s", vc.Target.Script, err.Error())
|
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 {
|
l.SetGlobal("tellMe", l.NewFunction(func(l *lua.LState) int {
|
||||||
// TODO not getting senderID properly here
|
|
||||||
sender := l.GetGlobal("sender").(*lua.LTable)
|
sender := l.GetGlobal("sender").(*lua.LTable)
|
||||||
senderID := int(lua.LVAsNumber(sender.RawGetString("ID")))
|
senderID := int(lua.LVAsNumber(sender.RawGetString("ID")))
|
||||||
msg := l.ToString(1)
|
sc.serverAPI.Tell(senderID, l.ToString(1))
|
||||||
log.Printf("%#v %s\n", sender, msg)
|
return 0
|
||||||
log.Println(senderID)
|
}))
|
||||||
sc.tell(senderID, msg)
|
|
||||||
|
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
|
return 0
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// TODO check execute permission and bail out potentially
|
// TODO check execute permission and bail out potentially
|
||||||
|
log.Printf("%#v", vc)
|
||||||
|
|
||||||
senderT := l.NewTable()
|
senderT := l.NewTable()
|
||||||
senderT.RawSetString("name", lua.LString(vc.Sender.Data["name"]))
|
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) {
|
func (sc *ScriptContext) Handle(vc VerbContext) {
|
||||||
log.Printf("%#v %#v", sc, vc)
|
|
||||||
sc.incoming <- vc
|
sc.incoming <- vc
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue