parsec/parsec_manager.go
2023-06-02 15:41:51 +08:00

430 lines
8.8 KiB
Go

package main
import (
"github.com/gorilla/websocket"
"math/rand"
"strconv"
"sync"
"time"
)
type UserInfo struct {
UserId int
Email string
Password string
}
type PeerInfo struct {
PeerId string
Owner string
Assign []string
Online bool `json:"-"`
Build string
Name string
Players int
Public bool
Secret string
External string
}
type SessionInfo struct {
SessionId string
Email string
UserId int
HostPeerId string
Role string
AttemptId string
Guid string
WsConn *websocket.Conn `json:"-"`
}
type ParsecService struct {
sessionLock sync.Mutex
wsSessionLock sync.Mutex
peerLock sync.Mutex
userLock sync.Mutex
Sessions []*SessionInfo `json:"sessions"`
WsSessions []*SessionInfo `json:"wsSessions"`
Users []*UserInfo `json:"users"`
Peers []*PeerInfo `json:"peers"`
}
func (p *ParsecService) LoadConfig(config *ConfigData) {
p.sessionLock.Lock()
p.userLock.Lock()
p.peerLock.Lock()
defer p.sessionLock.Unlock()
defer p.userLock.Unlock()
defer p.peerLock.Unlock()
p.Peers = config.Peers
p.Users = config.Users
p.Sessions = config.Sessions
}
func (p *ParsecService) Login(email string, password string) *UserInfo {
p.userLock.Lock()
defer p.userLock.Unlock()
for _, user := range p.Users {
if user.Email == email && user.Password == password {
return user
}
}
return nil
}
func (p *ParsecService) AddUser(email string, password string) *UserInfo {
p.userLock.Lock()
defer p.userLock.Unlock()
for _, user := range p.Users {
if user.Email == email {
return user
}
}
newUserId := 0
for i := LastUserId + 1; i < 10000; i++ {
exist := false
for _, user := range p.Users {
if user.UserId == i {
exist = true
break
}
}
if !exist {
newUserId = i
LastUserId = i
break
}
}
tmp := &UserInfo{
UserId: newUserId,
Email: email,
Password: password,
}
p.Users = append(p.Users, tmp)
return tmp
}
func (p *ParsecService) GetUserByEmail(email string) *UserInfo {
p.userLock.Lock()
defer p.userLock.Unlock()
for _, user := range p.Users {
if user.Email == email {
return user
}
}
return nil
}
func (p *ParsecService) CheckUserExist(email string) bool {
p.userLock.Lock()
defer p.userLock.Unlock()
for _, user := range p.Users {
if user.Email == email {
return true
}
}
return false
}
func (p *ParsecService) AddPeer(email string) *PeerInfo {
p.peerLock.Lock()
defer p.peerLock.Unlock()
newPeerId := GetRandomString(27)
for {
exist := false
for _, peer := range p.Peers {
if peer.PeerId == newPeerId {
exist = true
break
}
}
if exist {
newPeerId = GetRandomString(27)
} else {
break
}
}
peer := &PeerInfo{
PeerId: newPeerId,
Owner: email,
Assign: []string{},
}
p.Peers = append(p.Peers, peer)
return peer
}
func (p *ParsecService) GetPeer(peerId string) *PeerInfo {
p.peerLock.Lock()
defer p.peerLock.Unlock()
for _, peer := range p.Peers {
if peer.PeerId == peerId {
return peer
}
}
return nil
}
func (p *ParsecService) NewSession(email string, userId int, PeerId string) *SessionInfo {
p.sessionLock.Lock()
defer p.sessionLock.Unlock()
r := rand.New(rand.NewSource(time.Now().UnixNano()))
sessionId := GetSHA256HashCode([]byte(strconv.Itoa(r.Intn(999999))))
for {
exist := false
for _, session := range p.Sessions {
if session.SessionId == sessionId {
exist = true
break
}
}
if exist {
sessionId = GetSHA256HashCode([]byte(strconv.Itoa(r.Intn(999999))))
} else {
break
}
}
session := &SessionInfo{
SessionId: sessionId,
Email: email,
UserId: userId,
HostPeerId: PeerId,
}
p.Sessions = append(p.Sessions, session)
return session
}
func (p *ParsecService) NewWsSession(sessionId string, role string, guid string, wsConn *websocket.Conn) *SessionInfo {
p.wsSessionLock.Lock()
defer p.wsSessionLock.Unlock()
session := p.GetSession(sessionId)
if session != nil {
for _, wsSession := range p.WsSessions {
if wsSession.SessionId == sessionId && wsSession.Role == role {
wsSession.WsConn = wsConn
wsSession.Guid = guid
return wsSession
}
}
wsSession := &SessionInfo{
SessionId: session.SessionId,
Email: session.Email,
UserId: session.UserId,
HostPeerId: session.HostPeerId,
Role: role,
Guid: guid,
WsConn: wsConn,
}
p.WsSessions = append(p.WsSessions, wsSession)
return wsSession
}
return nil
}
func (p *ParsecService) RemoveWsSession(sessionId string, role string, sessionGuid string) {
p.wsSessionLock.Lock()
defer p.wsSessionLock.Unlock()
var tmp []*SessionInfo
for _, session := range p.WsSessions {
if !(session.SessionId == sessionId && session.Role == role && session.Guid == sessionGuid) {
tmp = append(tmp, session)
}
}
p.WsSessions = tmp
}
func (p *ParsecService) SetupOnlineStatus(hostPeer *PeerInfo) {
p.wsSessionLock.Lock()
defer p.wsSessionLock.Unlock()
for _, session := range p.WsSessions {
if session.HostPeerId == hostPeer.PeerId {
return
}
}
hostPeer.Online = false
}
func (p *ParsecService) GetWsSessionByPeerId(role string, peerId string) *SessionInfo {
p.wsSessionLock.Lock()
defer p.wsSessionLock.Unlock()
for _, session := range p.WsSessions {
if session.Role == role && session.HostPeerId == peerId {
return session
}
}
return nil
}
func (p *ParsecService) GetWsSessionByAttemptId(peerId string, attemptId string) *SessionInfo {
p.wsSessionLock.Lock()
defer p.wsSessionLock.Unlock()
for _, session := range p.WsSessions {
if session.AttemptId == attemptId && session.HostPeerId == peerId {
return session
}
}
return nil
}
func (p *ParsecService) GetSession(sessionId string) *SessionInfo {
p.sessionLock.Lock()
defer p.sessionLock.Unlock()
for _, session := range p.Sessions {
if session.SessionId == sessionId {
return session
}
}
return nil
}
func (p *ParsecService) GetPeersByEmail(email string) []*PeerInfo {
p.peerLock.Lock()
defer p.peerLock.Unlock()
var peers []*PeerInfo
for _, peer := range p.Peers {
if peer.Owner == email || StringListContain(peer.Assign, email) {
peers = append(peers, peer)
}
}
return peers
}
func (p *ParsecService) RemoveUser(email string) {
p.userLock.Lock()
defer p.userLock.Unlock()
var tmp []*UserInfo
for _, user := range p.Users {
if user.Email != email {
tmp = append(tmp, user)
}
}
p.Users = tmp
}
func (p *ParsecService) RemovePeerByUser(email string) {
p.peerLock.Lock()
defer p.peerLock.Unlock()
var tmp []*PeerInfo
for _, peer := range p.Peers {
if peer.Owner != email {
tmp = append(tmp, peer)
}
}
p.Peers = tmp
}
func (p *ParsecService) RemoveSessionByUser(email string) {
p.sessionLock.Lock()
defer p.sessionLock.Unlock()
var tmp []*SessionInfo
for _, session := range p.Sessions {
if session.Email != email {
tmp = append(tmp, session)
} else {
if session.WsConn != nil {
session.WsConn.Close()
}
}
}
p.Sessions = tmp
}
func (p *ParsecService) RemoveWsSessionByUser(email string) {
p.wsSessionLock.Lock()
defer p.wsSessionLock.Unlock()
var tmp []*SessionInfo
for _, session := range p.WsSessions {
if session.Email != email {
tmp = append(tmp, session)
} else {
if session.WsConn != nil {
session.WsConn.Close()
}
}
}
p.WsSessions = tmp
}
func (p *ParsecService) RemoveSessionByPeerId(peerId string) {
p.sessionLock.Lock()
defer p.sessionLock.Unlock()
var tmp []*SessionInfo
for _, session := range p.Sessions {
if session.HostPeerId != peerId {
tmp = append(tmp, session)
} else {
if session.WsConn != nil {
session.WsConn.Close()
}
}
}
p.Sessions = tmp
}
func (p *ParsecService) RemoveWsSessionByPeerId(peerId string) {
p.wsSessionLock.Lock()
defer p.wsSessionLock.Unlock()
var tmp []*SessionInfo
for _, session := range p.WsSessions {
if session.HostPeerId != peerId {
tmp = append(tmp, session)
} else {
if session.WsConn != nil {
session.WsConn.Close()
}
}
}
p.WsSessions = tmp
}
func (p *ParsecService) AssignAdd(peerId string, email string) {
peer := p.GetPeer(peerId)
if peer != nil {
if !StringListContain(peer.Assign, email) {
peer.Assign = append(peer.Assign, email)
}
}
}
func (p *ParsecService) AssignClear(peerId string) {
peer := p.GetPeer(peerId)
if peer != nil {
peer.Assign = []string{}
}
}
func (p *ParsecService) AssignRemove(peerId string, email string) {
peer := p.GetPeer(peerId)
if peer != nil {
var tmp []string
for _, s := range peer.Assign {
if s != email {
tmp = append(tmp, s)
}
}
peer.Assign = tmp
}
}
func (p *ParsecService) RemoveOfflinePeers() {
p.peerLock.Lock()
defer p.peerLock.Unlock()
var tmp []*PeerInfo
for _, peer := range p.Peers {
if peer.Online {
tmp = append(tmp, peer)
} else {
p.RemoveSessionByPeerId(peer.PeerId)
p.RemoveWsSessionByPeerId(peer.PeerId)
}
}
p.Peers = tmp
}