430 lines
8.8 KiB
Go
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
|
|
}
|