Update client ncurses with borders

live
noah metz 2024-04-24 01:18:49 -06:00
parent 419e7857f9
commit af9fa4ab4b
4 changed files with 65 additions and 51 deletions

@ -55,6 +55,7 @@ func NewChannel(modes map[ModeID]Mode) (*Channel, error) {
} }
channel.Members.Store([]*ServerSession{}) channel.Members.Store([]*ServerSession{})
channel.BasePermissions.Store(Permissions{}) channel.BasePermissions.Store(Permissions{})
channel.RolePermissions.Store(map[Role]Permissions{}) channel.RolePermissions.Store(map[Role]Permissions{})
channel.UserPermissions.Store(map[PeerID]Permissions{}) channel.UserPermissions.Store(map[PeerID]Permissions{})

@ -271,16 +271,35 @@ func get_private_key(path string, generate bool) ed25519.PrivateKey {
} }
} }
func main_loop(client *pnyx.Client, audio_data chan []int16, window ncurses.Window, packet_chan chan pnyx.Payload, user_chan chan rune) { func print_decoration(window, channels, body ncurses.Window, top_left string) {
max_y := ncurses.GetMaxY(window) max_y := ncurses.GetMaxY(*ncurses.CurScr)
max_x := ncurses.GetMaxX(window) max_x := ncurses.GetMaxX(*ncurses.CurScr)
titlebar := ncurses.NewWin(1, max_x, 0, 0)
channels := ncurses.NewWin(max_y - 1, max_x / 3, 1, 0)
body := ncurses.NewWin(max_y - 1, max_x * 2 / 3, 1, max_x / 3)
ncurses.MvWAddStr(titlebar, 0, 0, fmt.Sprintf("pnyx client %X:%X", client.Key.Public().(ed25519.PublicKey)[:2], client.Session.ID[:2])) ncurses.WResize(channels, max_y - 2, (max_x / 4) - 1)
ncurses.MvWAddStr(body, 0, max_x-len(client.Remote()), client.Remote()) ncurses.WResize(body, max_y - 2, max_x - (max_x / 4) - 1)
ncurses.WRefresh(titlebar) ncurses.MvWin(body, 2, (max_x / 4) + 1)
ncurses.MvWAddStr(window, 0, 0, top_left)
for i := 0; i < max_x; i++ {
ncurses.MvWAddStr(window, 1, i, "═")
}
ncurses.MvWAddStr(window, 1, max_x/4, "╦")
for i := 2; i < max_y; i++ {
ncurses.MvWAddStr(window, i, max_x/4, "║")
}
ncurses.WRefresh(window)
ncurses.WRefresh(channels)
ncurses.WRefresh(body)
}
func main_loop(client *pnyx.Client, audio_data chan []int16, window ncurses.Window, packet_chan chan pnyx.Payload, user_chan chan []byte) {
channels := ncurses.NewWin(0, 0, 2, 0)
body := ncurses.NewWin(0, 0, 2, 0)
print_decoration(window, channels, body, fmt.Sprintf("pnyx client %X:%X", client.Key.Public().(ed25519.PublicKey)[:2], client.Session.ID[:2]))
for client.Active() { for client.Active() {
select { select {
@ -325,30 +344,12 @@ func main_loop(client *pnyx.Client, audio_data chan []int16, window ncurses.Wind
} }
} }
case char := <-user_chan: case char := <-user_chan:
ncurses.MvWAddStr(body, 0, 0, string(char)) ncurses.WAddStr(body, string(char))
ncurses.WRefresh(body) ncurses.WRefresh(body)
ncurses.MvWAddStr(channels, 0, 0, string(char))
ncurses.WRefresh(channels)
} }
} }
} }
func bitmatch(b byte, pattern byte, length int) bool {
mask := ^(byte(1 << (8 - length)) - 1)
return (b ^ pattern) & mask == 0
}
func ch_listen(client *pnyx.Client, user_chan chan rune) {
b := [4]byte{}
for client.Active() {
os.Stdin.Read(b[0:1])
if bitmatch(b[0], 0b00000000, 1) {
user_chan <- rune(b[0])
} // TODO: further utf-8 support
}
}
func process_mic(client *pnyx.Client, mic chan []byte) { func process_mic(client *pnyx.Client, mic chan []byte) {
for true { for true {
data := <- mic data := <- mic
@ -380,7 +381,7 @@ func main() {
defer inDevice.Stop() defer inDevice.Stop()
user_chan := make(chan rune, 1024) user_chan := make(chan []byte, 1024)
packet_chan := make(chan pnyx.Payload, 1024) packet_chan := make(chan pnyx.Payload, 1024)
key := get_private_key(os.ExpandEnv(*key_file_arg), *generate_key_arg) key := get_private_key(os.ExpandEnv(*key_file_arg), *generate_key_arg)
@ -409,15 +410,24 @@ func main() {
} }
go process_mic(client, mic) go process_mic(client, mic)
go ch_listen(client, user_chan)
locale := ncurses.SetLocale(0, "")
fmt.Printf("locale: %s\n", locale)
user_chan, stdin_active := ncurses.UTF8Listener(100, os.Stdin)
window := ncurses.InitScr() window := ncurses.InitScr()
ret := ncurses.StartColor()
if ret != 0 {
panic(ret)
}
go main_loop(client, audio_data, window, packet_chan, user_chan) go main_loop(client, audio_data, window, packet_chan, user_chan)
os_sigs := make(chan os.Signal, 1) os_sigs := make(chan os.Signal, 1)
signal.Notify(os_sigs, syscall.SIGINT, syscall.SIGABRT) signal.Notify(os_sigs, syscall.SIGINT, syscall.SIGABRT)
<-os_sigs <-os_sigs
stdin_active.Store(false)
client.Close() client.Close()
ncurses.EndWin() ncurses.EndWin()
} }

@ -1 +1 @@
Subproject commit 281f038f5f113180749d3af477311cd874208a3e Subproject commit e345e72ff0e54e5c25271223849cad34ce8620b3

@ -40,9 +40,10 @@ type Server struct {
key ed25519.PrivateKey key ed25519.PrivateKey
active atomic.Bool active atomic.Bool
connection *net.UDPConn connection *net.UDPConn
stopped chan error
commands chan Payload commands chan Payload
threads sync.WaitGroup
sessions_lock sync.Mutex sessions_lock sync.Mutex
sessions map[SessionID]*ServerSession sessions map[SessionID]*ServerSession
@ -79,7 +80,6 @@ func NewServer(listen string, key ed25519.PrivateKey, channels map[ChannelID]*Ch
key: key, key: key,
connection: connection, connection: connection,
active: atomic.Bool{}, active: atomic.Bool{},
stopped: make(chan error, 0),
commands: make(chan Payload, SERVER_COMMAND_BUFFER_SIZE), commands: make(chan Payload, SERVER_COMMAND_BUFFER_SIZE),
sessions: map[SessionID]*ServerSession{}, sessions: map[SessionID]*ServerSession{},
@ -87,6 +87,7 @@ func NewServer(listen string, key ed25519.PrivateKey, channels map[ChannelID]*Ch
peers: map[PeerID][]RoleID{}, peers: map[PeerID][]RoleID{},
} }
server.channels.Store(channels) server.channels.Store(channels)
server.BasePermissions.Store(Permissions{}) server.BasePermissions.Store(Permissions{})
@ -95,6 +96,7 @@ func NewServer(listen string, key ed25519.PrivateKey, channels map[ChannelID]*Ch
server.active.Store(true) server.active.Store(true)
server.threads.Add(2)
go server.listen_udp() go server.listen_udp()
go server.update_state() go server.update_state()
@ -107,11 +109,9 @@ func(server *Server) Log(format string, fields ...interface{}) {
func(server *Server) Stop() error { func(server *Server) Stop() error {
if server.active.CompareAndSwap(true, false) { if server.active.CompareAndSwap(true, false) {
err := server.connection.Close() close(server.commands)
if err != nil { server.threads.Wait()
return err return nil
}
return <-server.stopped
} else { } else {
return fmt.Errorf("Called stop on stopped server") return fmt.Errorf("Called stop on stopped server")
} }
@ -332,9 +332,8 @@ func(server *Server) handle_session_data(data []byte, from *net.UDPAddr) error {
} }
func(server *Server) listen_udp() { func(server *Server) listen_udp() {
server.Log("Started server on %s", server.connection.LocalAddr())
var buf [SERVER_UDP_BUFFER_SIZE]byte var buf [SERVER_UDP_BUFFER_SIZE]byte
server.Log("UDP_START: %s", server.connection.LocalAddr())
for true { for true {
read, from, err := server.connection.ReadFromUDP(buf[:]) read, from, err := server.connection.ReadFromUDP(buf[:])
if err == nil { if err == nil {
@ -374,6 +373,19 @@ func(server *Server) listen_udp() {
server.Log("UDP_READ_ERROR: %s", err) server.Log("UDP_READ_ERROR: %s", err)
} }
} }
server.threads.Done()
}
func(server *Server) update_state() {
for server.active.Load() {
select {
case command := <-server.commands:
if command == nil {
break
}
server.Log("Incoming server command %+v", command)
}
}
channels := server.channels.Load().(map[ChannelID]*Channel) channels := server.channels.Load().(map[ChannelID]*Channel)
for _, channel := range(channels) { for _, channel := range(channels) {
@ -389,10 +401,10 @@ func(server *Server) listen_udp() {
for _, session := range(sessions) { for _, session := range(sessions) {
server.close_session(session) server.close_session(session)
} }
server.connection.Close()
server.sessions_lock.Unlock() server.sessions_lock.Unlock()
server.Log("Shut down server on %s", server.connection.LocalAddr()) server.threads.Done()
server.stopped <- nil
} }
func(server *Server) close_session(session *ServerSession) { func(server *Server) close_session(session *ServerSession) {
@ -404,12 +416,3 @@ func(server *Server) close_session(session *ServerSession) {
session_closed := NewSessionTimed(SESSION_CLOSED, server.key, &session.Session, time.Now()) session_closed := NewSessionTimed(SESSION_CLOSED, server.key, &session.Session, time.Now())
server.connection.WriteToUDP(session_closed, session.remote) server.connection.WriteToUDP(session_closed, session.remote)
} }
func(server *Server) update_state() {
for server.active.Load() {
select {
case command := <-server.commands:
server.Log("Incoming server command %+v", command)
}
}
}