package types import ( "crypto/sha256" "math" "math/rand/v2" "sync" "time" "go-socket/packages/Enums/ConnectionState" "go-socket/packages/Enums/WsEventType" "go-socket/packages/config" "github.com/coder/websocket" "github.com/google/uuid" ) type Rgba [4]uint8 type Sha256Hash [sha256.Size]byte func (r Rgba) GetRandom() Rgba { for i := range r { r[i] = uint8(rand.IntN(256)) } return r } type User struct { Mu sync.RWMutex `json:"-"` Name string `json:"name"` Pronouns string `json:"pronouns"` Description string `json:"description"` AvatarUrl string `json:"avatarUrl"` ProfileBgUrl string `json:"profileBackgroundUrl"` PasswordHash string `json:"-"` CreatedAt time.Time `json:"createdAt"` WsConn *websocket.Conn `json:"-"` Id uuid.UUID `json:"-"` Connections map[uuid.UUID]*Connection `json:"-"` Color Rgba `json:"color"` } type UserProfileUpdateList struct { Pronouns bool Description bool Color bool Avatar bool ProfileBg bool } type Connection struct { Mu sync.RWMutex `json:"-"` Id uuid.UUID `json:"id"` CreatedAt time.Time `json:"createdAt"` MessagesBuff []*Message `json:"-"` NextBuffIdx uint32 `json:"-"` RequestorId uuid.UUID `json:"requestorId"` RecipientId uuid.UUID `json:"recipientId"` UserWantingToElevate uuid.UUID `json:"userWantingToElevate"` // TODO add to database HaveOverflowed bool `json:"-"` State ConnectionState.ConnectionState `json:"state"` } func NewConn() *Connection { return &Connection{ MessagesBuff: make([]*Message, config.MaxDirectMsgCache), } } func (conn *Connection) AddMessageToBuff(message *Message) { conn.Mu.Lock() defer conn.Mu.Unlock() size := uint32(len(conn.MessagesBuff)) conn.MessagesBuff[conn.NextBuffIdx%size] = message conn.NextBuffIdx++ if conn.NextBuffIdx >= size { conn.HaveOverflowed = true } } // GetSortedMessagesBuff returns slice and its valid length. func (conn *Connection) GetSortedMessagesBuff() ([]*Message, uint32) { conn.Mu.RLock() defer conn.Mu.RUnlock() size := uint32(len(conn.MessagesBuff)) if !conn.HaveOverflowed { return conn.MessagesBuff, conn.NextBuffIdx } sorted := make([]*Message, size) for i := uint32(0); i < size; i++ { sorted[i] = conn.MessagesBuff[(conn.NextBuffIdx+i)%size] } return sorted, size } type ConnectionStatusSetData struct { Id uuid.UUID `json:"id"` NewState ConnectionState.ConnectionState `json:"newState"` } type Message struct { Id uuid.UUID `json:"id"` AttachedFile string `json:"attachedFile"` Content string `json:"content"` CreatedAt time.Time `json:"createdAt"` Sender uuid.UUID `json:"sender"` Receiver uuid.UUID `json:"receiver"` } type LoginReturn struct { Token string `json:"token"` UserId uuid.UUID `json:"userId"` } type WsEventMessage struct { Type WsEventType.WsEventType `json:"type"` Event any `json:"event"` } type WsAuthMessage struct { Success bool `json:"success"` Error string `json:"error"` } type Permissions uint32 const ( // Hub permissions PermissionSetHubName Permissions = 1 << iota PermissionSetHubIcon PermissionSetHubBg PermissionSetHubColor PermissionRemoveHub PermissionSetUserColorAllowed // User permissions PermissionAddUser PermissionRemoveUser PermissionRenameUser PermissionMuteUser // Role permissions PermissionAddRole PermissionRemoveRole PermissionChangeRoleName PermissionChangeRoleColor PermissionChangeRoleGlobals PermissionNoSelfRoleRemove PermissionOnlySelfRoleRemove // Channel group permissions PermissionAddChannelGroup PermissionRemoveChannelGroup PermissionSetChannelGroupName PermissionSetChannelGroupColor PermissionSetChannelGroupPermittedVisibleRoles // Channel permissions PermissionAddChannel PermissionRemoveChannel PermissionSetChannelName PermissionSetChannelIcon PermissionSetChannelPermittedVisibleRoles PermissionSetChannelPermittedSendMessageRoles PermissionSetChannelPermittedReadHistoryRoles ) func (p *Permissions) Grant(permissions Permissions) { *p |= permissions } func (p *Permissions) GrantMultiple(perms []Permissions) { for _, perm := range perms { *p |= perm } } func (p *Permissions) Revoke(permissions Permissions) { *p &^= permissions } func (p *Permissions) Has(permissions Permissions) bool { return *p&permissions != 0 } func PermissionAll() Permissions { return math.MaxUint32 } type BoundRoles uint64 func (b *BoundRoles) Add(id uint8) { *b |= 1 << id } func (b *BoundRoles) Remove(id uint8) { *b &^= 1 << id } func (b *BoundRoles) Has(id uint8) bool { return *b&(1<= size { conn.HaveOverflowed = true } } // GetSortedMessagesBuff returns slice and its valid length. func (conn *HubChannel) GetSortedMessagesBuff() ([]*Message, uint32) { conn.Mu.RLock() defer conn.Mu.RUnlock() size := uint32(len(conn.MessagesBuff)) if !conn.HaveOverflowed { return conn.MessagesBuff, conn.NextBuffIdx } sorted := make([]*Message, size) for i := uint32(0); i < size; i++ { sorted[i] = conn.MessagesBuff[(conn.NextBuffIdx+i)%size] } return sorted, size }