Files
Erupe/signserver/session.go
Andrew Gutekanst 501cfc2267 Add multi-region launcher support
Add custom launcher as well as support for both the original TW and JP
launchers.
2019-12-30 07:38:48 +09:00

110 lines
2.6 KiB
Go

package signserver
import (
"database/sql"
"encoding/hex"
"fmt"
"net"
"sync"
"github.com/Andoryuuta/Erupe/network"
"github.com/Andoryuuta/byteframe"
)
// Session holds state for the sign server connection.
type Session struct {
sync.Mutex
sid int
server *Server
rawConn *net.Conn
cryptConn *network.CryptConn
}
func (session *Session) fail() {
session.server.Lock()
delete(session.server.sessions, session.sid)
session.server.Unlock()
}
func (session *Session) work() {
for {
pkt, err := session.cryptConn.ReadPacket()
if err != nil {
session.fail()
return
}
err = session.handlePacket(pkt)
if err != nil {
session.fail()
return
}
}
}
func (session *Session) handlePacket(pkt []byte) error {
bf := byteframe.NewByteFrameFromBytes(pkt)
reqType := string(bf.ReadNullTerminatedBytes())
switch reqType {
case "DLTSKEYSIGN:100":
fallthrough
case "DSGN:100":
session.handleDSGNRequest(bf)
break
case "DELETE:100":
loginTokenString := string(bf.ReadNullTerminatedBytes())
_ = loginTokenString
characterID := bf.ReadUint32()
fmt.Printf("Got delete request for character ID: %v\n", characterID)
fmt.Printf("remaining unknown data:\n%s\n", hex.Dump(bf.DataFromCurrent()))
default:
fmt.Printf("Got unknown request type %s, data:\n%s\n", reqType, hex.Dump(bf.DataFromCurrent()))
}
return nil
}
func (session *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
reqUsername := string(bf.ReadNullTerminatedBytes())
reqPassword := string(bf.ReadNullTerminatedBytes())
reqUnk := string(bf.ReadNullTerminatedBytes())
fmt.Printf("Got sign in request:\n\tUsername: %s\n\tPassword %s\n\tUnk: %s\n", reqUsername, reqPassword, reqUnk)
// TODO(Andoryuuta): remove plaintext password storage if this ever becomes more than a toy project.
var (
id int
password string
)
err := session.server.db.QueryRow("SELECT id, password FROM users WHERE username = $1", reqUsername).Scan(&id, &password)
var serverRespBytes []byte
switch {
case err == sql.ErrNoRows:
fmt.Printf("No rows for username %s\n", reqUsername)
serverRespBytes = makeSignInFailureResp(SIGN_EAUTH)
break
case err != nil:
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
fmt.Println("Got error on SQL query!")
fmt.Println(err)
break
default:
if reqPassword == password {
fmt.Println("Passwords match!")
serverRespBytes = makeSignInResp(reqUsername)
} else {
fmt.Println("Passwords don't match!")
serverRespBytes = makeSignInFailureResp(SIGN_EPASS)
}
}
err = session.cryptConn.SendPacket(serverRespBytes)
if err != nil {
return err
}
return nil
}