|
|
|
@ -19,6 +19,7 @@ const (
|
|
|
|
|
AUDIO_GET_SAMPLE_RATE
|
|
|
|
|
|
|
|
|
|
CHANNEL_COMMAND_BUFFER_SIZE int = 2048
|
|
|
|
|
CHANNEL_CLOSE_BUFFER_SIZE int = 100
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type ModeID uint8
|
|
|
|
@ -27,49 +28,76 @@ type Permission string
|
|
|
|
|
|
|
|
|
|
type Channel struct {
|
|
|
|
|
Commands chan SessionChannelCommand
|
|
|
|
|
ClosedSessions chan *ServerSession
|
|
|
|
|
Modes map[ModeID]*atomic.Value
|
|
|
|
|
Members atomic.Value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func(channel *Channel) update_state() {
|
|
|
|
|
for true {
|
|
|
|
|
incoming := <-channel.Commands
|
|
|
|
|
if incoming.Packet == nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
select {
|
|
|
|
|
case session := <-channel.ClosedSessions:
|
|
|
|
|
members := channel.Members.Load().([]*ServerSession)
|
|
|
|
|
idx := slices.Index(members, session)
|
|
|
|
|
if idx != -1 {
|
|
|
|
|
new_members := make([]*ServerSession, len(members) - 1)
|
|
|
|
|
copy(new_members, members[:idx])
|
|
|
|
|
copy(new_members[idx:], members[idx+1:])
|
|
|
|
|
channel.Members.Store(new_members)
|
|
|
|
|
|
|
|
|
|
for _, mode_val := range(channel.Modes) {
|
|
|
|
|
mode := mode_val.Load().(Mode)
|
|
|
|
|
mode_val.Store(mode.Leave(session))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case incoming := <-channel.Commands:
|
|
|
|
|
if incoming.Packet == nil {
|
|
|
|
|
break
|
|
|
|
|
} else if incoming.Session.active.Load() == false {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
command := incoming.Packet
|
|
|
|
|
|
|
|
|
|
if command.Mode == MODE_CHANNEL {
|
|
|
|
|
switch command.Command {
|
|
|
|
|
case CHANNEL_COMMAND_JOIN:
|
|
|
|
|
members := channel.Members.Load().([]*ServerSession)
|
|
|
|
|
if slices.Contains(members, incoming.Session) == false {
|
|
|
|
|
new_members := make([]*ServerSession, len(members) + 1)
|
|
|
|
|
copy(new_members, members)
|
|
|
|
|
new_members[len(members)] = incoming.Session
|
|
|
|
|
channel.Members.Store(new_members)
|
|
|
|
|
fmt.Printf("New Members: %+v\n", channel.Members.Load())
|
|
|
|
|
command := incoming.Packet
|
|
|
|
|
|
|
|
|
|
if command.Mode == MODE_CHANNEL {
|
|
|
|
|
switch command.Command {
|
|
|
|
|
case CHANNEL_COMMAND_JOIN:
|
|
|
|
|
members := channel.Members.Load().([]*ServerSession)
|
|
|
|
|
if slices.Contains(members, incoming.Session) == false {
|
|
|
|
|
new_members := make([]*ServerSession, len(members) + 1)
|
|
|
|
|
copy(new_members, members)
|
|
|
|
|
new_members[len(members)] = incoming.Session
|
|
|
|
|
channel.Members.Store(new_members)
|
|
|
|
|
|
|
|
|
|
for _, mode_val := range(channel.Modes) {
|
|
|
|
|
mode := mode_val.Load().(Mode)
|
|
|
|
|
mode_val.Store(mode.Join(incoming.Session))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case CHANNEL_COMMAND_LEAVE:
|
|
|
|
|
members := channel.Members.Load().([]*ServerSession)
|
|
|
|
|
idx := slices.Index(members, incoming.Session)
|
|
|
|
|
if idx != -1 {
|
|
|
|
|
new_members := make([]*ServerSession, len(members) - 1)
|
|
|
|
|
copy(new_members, members[:idx])
|
|
|
|
|
copy(new_members[idx:], members[idx+1:])
|
|
|
|
|
channel.Members.Store(new_members)
|
|
|
|
|
|
|
|
|
|
for _, mode_val := range(channel.Modes) {
|
|
|
|
|
mode := mode_val.Load().(Mode)
|
|
|
|
|
mode_val.Store(mode.Leave(incoming.Session))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case CHANNEL_COMMAND_LEAVE:
|
|
|
|
|
members := channel.Members.Load().([]*ServerSession)
|
|
|
|
|
idx := slices.Index(members, incoming.Session)
|
|
|
|
|
if idx != -1 {
|
|
|
|
|
new_members := make([]*ServerSession, len(members) - 1)
|
|
|
|
|
copy(new_members, members[:idx])
|
|
|
|
|
copy(new_members[idx:], members[idx+1:])
|
|
|
|
|
channel.Members.Store(new_members)
|
|
|
|
|
fmt.Printf("New Members: %+v\n", channel.Members.Load())
|
|
|
|
|
} else {
|
|
|
|
|
mode, has_mode := channel.Modes[command.Mode]
|
|
|
|
|
if has_mode {
|
|
|
|
|
members := channel.Members.Load().([]*ServerSession)
|
|
|
|
|
mode_val := mode.Load().(Mode)
|
|
|
|
|
new_mode := mode_val.Command(incoming.Session, command.Command, command.ReqID, command.Channel, members, command.Data)
|
|
|
|
|
mode.Store(new_mode)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
mode, has_mode := channel.Modes[command.Mode]
|
|
|
|
|
if has_mode {
|
|
|
|
|
members := channel.Members.Load().([]*ServerSession)
|
|
|
|
|
mode_val := mode.Load().(Mode)
|
|
|
|
|
new_mode := mode_val.Command(incoming.Session, command.Command, command.ReqID, command.Channel, members, command.Data)
|
|
|
|
|
mode.CompareAndSwap(mode_val, new_mode)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -86,6 +114,7 @@ func NewChannel(modes map[ModeID]Mode) (*Channel, error) {
|
|
|
|
|
|
|
|
|
|
channel := &Channel{
|
|
|
|
|
Commands: make(chan SessionChannelCommand, CHANNEL_COMMAND_BUFFER_SIZE),
|
|
|
|
|
ClosedSessions: make(chan *ServerSession, CHANNEL_CLOSE_BUFFER_SIZE),
|
|
|
|
|
Modes: initial_modes,
|
|
|
|
|
}
|
|
|
|
|
channel.Members.Store([]*ServerSession{})
|
|
|
|
@ -96,6 +125,8 @@ func NewChannel(modes map[ModeID]Mode) (*Channel, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Mode interface {
|
|
|
|
|
Join(session *ServerSession) Mode
|
|
|
|
|
Leave(session *ServerSession) Mode
|
|
|
|
|
Command(session *ServerSession, command byte, request_id uuid.UUID, channel_id ChannelID, members []*ServerSession, data []byte) Mode
|
|
|
|
|
Data(session *ServerSession, channel_id ChannelID, members []*ServerSession, data []byte)
|
|
|
|
|
}
|
|
|
|
@ -119,6 +150,14 @@ func multiplex(packet *Packet, sessions []*ServerSession) {
|
|
|
|
|
type RawMode struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func(mode RawMode) Join(session *ServerSession) Mode {
|
|
|
|
|
return mode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func(mode RawMode) Leave(session *ServerSession) Mode {
|
|
|
|
|
return mode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func(mode RawMode) Command(session *ServerSession, command byte, request_id uuid.UUID, channel_id ChannelID, members []*ServerSession, data []byte) Mode {
|
|
|
|
|
return mode
|
|
|
|
|
}
|
|
|
|
@ -139,6 +178,14 @@ type AudioMode struct {
|
|
|
|
|
SampleRate SampleRate
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func(mode AudioMode) Join(session *ServerSession) Mode {
|
|
|
|
|
return mode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func(mode AudioMode) Leave(session *ServerSession) Mode {
|
|
|
|
|
return mode
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func(mode AudioMode) Command(session *ServerSession, command byte, request_id uuid.UUID, channel_id ChannelID, members []*ServerSession, data []byte) Mode {
|
|
|
|
|
switch command {
|
|
|
|
|
case AUDIO_SET_SAMPLE_RATE:
|
|
|
|
|