mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-13 15:34:38 +01:00
repository cleanup
This commit is contained in:
163
server/signserver/session.go
Normal file
163
server/signserver/session.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package signserver
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// Session holds state for the sign server connection.
|
||||
type Session struct {
|
||||
sync.Mutex
|
||||
logger *zap.Logger
|
||||
sid int
|
||||
server *Server
|
||||
rawConn *net.Conn
|
||||
cryptConn *network.CryptConn
|
||||
}
|
||||
|
||||
func (s *Session) fail() {
|
||||
s.server.Lock()
|
||||
delete(s.server.sessions, s.sid)
|
||||
s.server.Unlock()
|
||||
|
||||
}
|
||||
|
||||
func (s *Session) work() {
|
||||
for {
|
||||
pkt, err := s.cryptConn.ReadPacket()
|
||||
if err != nil {
|
||||
s.fail()
|
||||
return
|
||||
}
|
||||
|
||||
err = s.handlePacket(pkt)
|
||||
if err != nil {
|
||||
s.fail()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) handlePacket(pkt []byte) error {
|
||||
sugar := s.logger.Sugar()
|
||||
|
||||
bf := byteframe.NewByteFrameFromBytes(pkt)
|
||||
reqType := string(bf.ReadNullTerminatedBytes())
|
||||
switch reqType {
|
||||
case "DLTSKEYSIGN:100":
|
||||
fallthrough
|
||||
case "DSGN:100":
|
||||
err := s.handleDSGNRequest(bf)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
case "DELETE:100":
|
||||
loginTokenString := string(bf.ReadNullTerminatedBytes())
|
||||
characterID := int(bf.ReadUint32())
|
||||
s.server.deleteCharacter(characterID, loginTokenString)
|
||||
sugar.Infof("Deleted character ID: %v\n", characterID)
|
||||
err := s.cryptConn.SendPacket([]byte{0x01}) // DEL_SUCCESS
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
sugar.Infof("Got unknown request type %s, data:\n%s\n", reqType, hex.Dump(bf.DataFromCurrent()))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
|
||||
|
||||
reqUsername := string(bf.ReadNullTerminatedBytes())
|
||||
reqPassword := string(bf.ReadNullTerminatedBytes())
|
||||
reqUnk := string(bf.ReadNullTerminatedBytes())
|
||||
|
||||
s.server.logger.Info(
|
||||
"Got sign in request",
|
||||
zap.String("reqUsername", reqUsername),
|
||||
zap.String("reqPassword", reqPassword),
|
||||
zap.String("reqUnk", reqUnk),
|
||||
)
|
||||
|
||||
newCharaReq := false
|
||||
|
||||
if reqUsername[len(reqUsername)-1] == 43 { // '+'
|
||||
reqUsername = reqUsername[:len(reqUsername)-1]
|
||||
newCharaReq = true
|
||||
}
|
||||
|
||||
var (
|
||||
id int
|
||||
password string
|
||||
)
|
||||
err := s.server.db.QueryRow("SELECT id, password FROM users WHERE username = $1", reqUsername).Scan(&id, &password)
|
||||
var serverRespBytes []byte
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
s.logger.Info("Account not found", zap.String("reqUsername", reqUsername))
|
||||
serverRespBytes = makeSignInFailureResp(SIGN_EAUTH)
|
||||
|
||||
// HACK(Andoryuuta): Create a new account if it doesn't exit.
|
||||
s.logger.Info("Creating account", zap.String("reqUsername", reqUsername), zap.String("reqPassword", reqPassword))
|
||||
err = s.server.registerDBAccount(reqUsername, reqPassword)
|
||||
if err != nil {
|
||||
s.logger.Info("Error on creating new account", zap.Error(err))
|
||||
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
|
||||
break
|
||||
}
|
||||
|
||||
var id int
|
||||
err = s.server.db.QueryRow("SELECT id FROM users WHERE username = $1", reqUsername).Scan(&id)
|
||||
if err != nil {
|
||||
s.logger.Info("Error on querying account id", zap.Error(err))
|
||||
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
|
||||
break
|
||||
}
|
||||
|
||||
serverRespBytes = s.makeSignInResp(id)
|
||||
break
|
||||
case err != nil:
|
||||
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
|
||||
s.logger.Warn("Got error on SQL query", zap.Error(err))
|
||||
break
|
||||
default:
|
||||
if bcrypt.CompareHashAndPassword([]byte(password), []byte(reqPassword)) == nil {
|
||||
s.logger.Info("Passwords match!")
|
||||
if newCharaReq {
|
||||
err = s.server.newUserChara(reqUsername)
|
||||
if err != nil {
|
||||
s.logger.Info("Error on adding new character to account", zap.Error(err))
|
||||
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
|
||||
break
|
||||
}
|
||||
}
|
||||
// TODO: Need to auto delete user tokens after inactivity
|
||||
// exists, err := s.server.checkToken(id)
|
||||
// if err != nil {
|
||||
// s.logger.Info("Error checking for live tokens", zap.Error(err))
|
||||
// serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
|
||||
// break
|
||||
// }
|
||||
serverRespBytes = s.makeSignInResp(id)
|
||||
} else {
|
||||
s.logger.Info("Passwords don't match!")
|
||||
serverRespBytes = makeSignInFailureResp(SIGN_EPASS)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = s.cryptConn.SendPacket(serverRespBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user