X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=client.go;h=2e475887629b76eb339c3bd6fcbd3e7e9f5d00e6;hb=a5e7fe92269e44c5cc147d316730407d67f32f8a;hp=69a4c2902795fb05b00f74e78678045419c7a030;hpb=e7841553c1c28affcb9a907ee35317754f4ca442;p=hydra-dragonfire.git diff --git a/client.go b/client.go index 69a4c29..2e47588 100644 --- a/client.go +++ b/client.go @@ -3,7 +3,7 @@ package main import ( "errors" "github.com/anon55555/mt" - "github.com/dragonfireclient/hydra-dragonfire/tolua" + "github.com/dragonfireclient/hydra-dragonfire/convert" "github.com/yuin/gopher-lua" "net" "sync" @@ -19,7 +19,7 @@ const ( type Component interface { create(client *Client, l *lua.LState) - tolua() lua.LValue + push() lua.LValue connect() process(pkt *mt.Pkt) } @@ -29,23 +29,38 @@ type Client struct { address string state clientState conn mt.Peer - queue chan *mt.Pkt - wildcard bool - subscribed map[string]struct{} + queue chan Event components map[string]Component + table *lua.LTable userdata *lua.LUserData } var clientFuncs = map[string]lua.LGFunction{ - "address": l_client_address, - "state": l_client_state, - "connect": l_client_connect, - "poll": l_client_poll, - "disconnect": l_client_disconnect, - "enable": l_client_enable, - "subscribe": l_client_subscribe, - "unsubscribe": l_client_unsubscribe, - "wildcard": l_client_wildcard, + "address": l_client_address, + "state": l_client_state, + "connect": l_client_connect, + "poll": l_client_poll, + "close": l_client_close, + "enable": l_client_enable, + "send": l_client_send, +} + +type EventError struct { + err string +} + +func (evt EventError) handle(l *lua.LState, val lua.LValue) { + l.SetField(val, "type", lua.LString("error")) + l.SetField(val, "error", lua.LString(evt.err)) +} + +type EventDisconnect struct { + client *Client +} + +func (evt EventDisconnect) handle(l *lua.LState, val lua.LValue) { + l.SetField(val, "type", lua.LString("disconnect")) + evt.client.state = csDisconnected } func getClient(l *lua.LState) *Client { @@ -64,18 +79,7 @@ func getClients(l *lua.LState) []*Client { return clients } -func getStrings(l *lua.LState) []string { - n := l.GetTop() - - strs := make([]string, 0, n-1) - for i := 2; i <= n; i++ { - strs = append(strs, l.CheckString(i)) - } - - return strs -} - -func (client *Client) disconnect() { +func (client *Client) closeConn() { client.mu.Lock() defer client.mu.Unlock() @@ -89,9 +93,8 @@ func l_client(l *lua.LState) int { client.address = l.CheckString(1) client.state = csNew - client.wildcard = false - client.subscribed = map[string]struct{}{} client.components = map[string]Component{} + client.table = l.NewTable() client.userdata = l.NewUserData() client.userdata.Value = client l.SetMetatable(client.userdata, l.GetTypeMetatable("hydra.client")) @@ -104,10 +107,12 @@ func l_client_index(l *lua.LState) int { client := getClient(l) key := l.CheckString(2) - if fun, exists := clientFuncs[key]; exists { + if key == "data" { + l.Push(client.table) + } else if fun, exists := clientFuncs[key]; exists { l.Push(l.NewFunction(fun)) } else if component, exists := client.components[key]; exists { - l.Push(component.tolua()) + l.Push(component.push()) } else { l.Push(lua.LNil) } @@ -153,7 +158,7 @@ func l_client_connect(l *lua.LState) int { client.state = csConnected client.conn = mt.Connect(conn) - client.queue = make(chan *mt.Pkt, 1024) + client.queue = make(chan Event, 1024) go func() { for { @@ -161,26 +166,22 @@ func l_client_connect(l *lua.LState) int { if err == nil { client.mu.Lock() - - for _, component := range client.components { - component.process(&pkt) + for _, comp := range client.components { + comp.process(&pkt) } - - if _, exists := client.subscribed[string(tolua.PktType(&pkt))]; exists || client.wildcard { - client.queue <- &pkt - } - client.mu.Unlock() } else if errors.Is(err, net.ErrClosed) { - close(client.queue) + client.queue <- EventDisconnect{client: client} return + } else { + client.queue <- EventError{err: err.Error()} } } }() client.mu.Lock() - for _, component := range client.components { - component.connect() + for _, comp := range client.components { + comp.connect() } client.mu.Unlock() @@ -189,85 +190,68 @@ func l_client_connect(l *lua.LState) int { func l_client_poll(l *lua.LState) int { client := getClient(l) - _, pkt, timeout := doPoll(l, []*Client{client}) - - l.Push(tolua.Pkt(l, pkt)) - l.Push(lua.LBool(timeout)) - return 2 + return doPoll(l, []*Client{client}) } -func l_client_disconnect(l *lua.LState) int { +func l_client_close(l *lua.LState) int { client := getClient(l) - client.disconnect() + client.closeConn() return 0 } func l_client_enable(l *lua.LState) int { client := getClient(l) + n := l.GetTop() + client.mu.Lock() defer client.mu.Unlock() - for _, compname := range getStrings(l) { - if component, exists := client.components[compname]; !exists { - switch compname { + for i := 2; i <= n; i++ { + name := l.CheckString(i) + + if comp, exists := client.components[name]; !exists { + switch name { case "auth": - component = &Auth{} + comp = &CompAuth{} + case "map": + comp = &CompMap{} + case "pkts": + comp = &CompPkts{} default: - panic("invalid component: " + compname) + panic("invalid component: " + name) } - client.components[compname] = component - component.create(client, l) + client.components[name] = comp + comp.create(client, l) } } return 0 } -func l_client_subscribe(l *lua.LState) int { - client := getClient(l) - client.mu.Lock() - defer client.mu.Unlock() - - for _, pkt := range getStrings(l) { - client.subscribed[pkt] = struct{}{} - } - - return 0 -} - -func l_client_unsubscribe(l *lua.LState) int { +func l_client_send(l *lua.LState) int { client := getClient(l) - client.mu.Lock() - defer client.mu.Unlock() - for _, pkt := range getStrings(l) { - delete(client.subscribed, pkt) + if client.state != csConnected { + panic("not connected") } - return 0 -} - -func l_client_wildcard(l *lua.LState) int { - client := getClient(l) - client.wildcard = l.ToBool(2) - return 0 -} - -/* - -func l_client_send(l *lua.LState) int { - client := getClient(l) - pkt := fromlua.Pkt(l.CheckTable(2)) + cmd := convert.ReadCmd(l) + doAck := l.ToBool(4) client.mu.Lock() defer client.mu.Unlock() if client.state == csConnected { - client.conn.Send(pkt) + ack, err := client.conn.SendCmd(cmd) + if err != nil && !errors.Is(err, net.ErrClosed) { + panic(err) + } + + if doAck && !cmd.DefaultPktInfo().Unrel { + <-ack + } } return 0 } - -*/