mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-03-22 01:54:12 -05:00
Add files via upload
It won't let me add a commit message but I fixed parsing multiple Gamespy messages + the get profile.
This commit is contained in:
parent
231422c874
commit
eb45c1b5cc
|
|
@ -16,49 +16,54 @@ var (
|
|||
InvalidGameSpyCommand = errors.New("invalid command received")
|
||||
)
|
||||
|
||||
func ParseGameSpyMessage(msg string) (*GameSpyCommand, error) {
|
||||
g := &GameSpyCommand{
|
||||
OtherValues: map[string]string{},
|
||||
}
|
||||
|
||||
func ParseGameSpyMessage(msg string) ([]GameSpyCommand, error) {
|
||||
if !strings.Contains(msg, `\\`) || !strings.Contains(msg, `\final\`) {
|
||||
return nil, InvalidGameSpyCommand
|
||||
}
|
||||
|
||||
foundCommand := false
|
||||
for len(msg) > 0 {
|
||||
keyEnd := strings.Index(msg[1:], `\`) + 1
|
||||
key := msg[1:keyEnd]
|
||||
value := ""
|
||||
msg = msg[keyEnd+1:]
|
||||
|
||||
if key == "final" {
|
||||
// We are done.
|
||||
break
|
||||
var commands []GameSpyCommand
|
||||
for len(msg) > 0 && string(msg[0]) == `\` && strings.Contains(msg, `\final\`) {
|
||||
foundCommand := false
|
||||
g := GameSpyCommand{
|
||||
OtherValues: map[string]string{},
|
||||
}
|
||||
|
||||
if strings.Contains(msg, `\`) {
|
||||
if msg[0] != '\\' {
|
||||
valueEnd := strings.Index(msg[1:], `\`)
|
||||
value = msg[:valueEnd+1]
|
||||
msg = msg[valueEnd+1:]
|
||||
for len(msg) > 0 && string(msg[0]) == `\` {
|
||||
keyEnd := strings.Index(msg[1:], `\`) + 1
|
||||
key := msg[1:keyEnd]
|
||||
value := ""
|
||||
msg = msg[keyEnd+1:]
|
||||
|
||||
if key == "final" {
|
||||
// We are done.
|
||||
break
|
||||
}
|
||||
|
||||
if strings.Contains(msg, `\`) {
|
||||
if msg[0] != '\\' {
|
||||
valueEnd := strings.Index(msg[1:], `\`)
|
||||
value = msg[:valueEnd+1]
|
||||
msg = msg[valueEnd+1:]
|
||||
}
|
||||
} else {
|
||||
// We have most likely reached the end of the line.
|
||||
// However, we do not want to exit out without parsing the final key.
|
||||
value = msg
|
||||
}
|
||||
|
||||
if !foundCommand {
|
||||
g.Command = key
|
||||
g.CommandValue = value
|
||||
foundCommand = true
|
||||
} else {
|
||||
g.OtherValues[key] = value
|
||||
}
|
||||
} else {
|
||||
// We have most likely reached the end of the line.
|
||||
// However, we do not want to exit out without parsing the final key.
|
||||
value = msg
|
||||
}
|
||||
|
||||
if !foundCommand {
|
||||
g.Command = key
|
||||
g.CommandValue = value
|
||||
foundCommand = true
|
||||
} else {
|
||||
g.OtherValues[key] = value
|
||||
}
|
||||
commands = append(commands, g)
|
||||
}
|
||||
|
||||
return g, nil
|
||||
return commands, nil
|
||||
}
|
||||
|
||||
func CreateGameSpyMessage(command GameSpyCommand) string {
|
||||
|
|
|
|||
|
|
@ -16,3 +16,15 @@ func RandomString(n int) string {
|
|||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
var hexRunes = []rune("0123456789abcdefabcdef")
|
||||
|
||||
func RandomHexString(n int) string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letterRunes[rand.Intn(len(hexRunes))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func LoginUserToGCPM(pool *pgxpool.Pool, ctx context.Context, authToken string)
|
|||
user.CreateUser(pool, ctx)
|
||||
} else {
|
||||
// TODO get the profile ID!!!!!
|
||||
user.ProfileId = 4
|
||||
user.ProfileId = 474888031
|
||||
}
|
||||
|
||||
return user
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import (
|
|||
|
||||
const (
|
||||
InsertUser = `INSERT INTO users (user_id, gsbrcd, password, email, unique_nick) VALUES ($1, $2, $3, $4, $5) RETURNING profile_id`
|
||||
UpdateUserTable = `UPDATE users SET firstname = $1, lastname = $2 WHERE user_id = $3`
|
||||
GetUser = `SELECT user_id, gsbrcd, password, email, unique_nick, firstname, lastname FROM users WHERE profile_id = $1`
|
||||
CreateUserSession = `INSERT INTO sessions (session_key, profile_id, login_ticket) VALUES ($1, $2, $3)`
|
||||
DoesUserExist = `SELECT EXISTS(SELECT 1 FROM users WHERE user_id = $1 AND gsbrcd = $2)`
|
||||
DeleteUserSession = `DELETE FROM sessions WHERE profile_id = $1`
|
||||
|
|
@ -22,6 +24,8 @@ type User struct {
|
|||
Password string
|
||||
Email string
|
||||
UniqueNick string
|
||||
FirstName string
|
||||
LastName string
|
||||
}
|
||||
|
||||
func (user *User) CreateUser(pool *pgxpool.Pool, ctx context.Context) {
|
||||
|
|
@ -31,6 +35,16 @@ func (user *User) CreateUser(pool *pgxpool.Pool, ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func UpdateUser(pool *pgxpool.Pool, ctx context.Context, firstName string, lastName string, userId int) User {
|
||||
user := User{}
|
||||
_, err := pool.Exec(ctx, UpdateUserTable, firstName, lastName, userId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
func CreateSession(pool *pgxpool.Pool, ctx context.Context, profileId int, loginTicket string) string {
|
||||
// Delete session first.
|
||||
deleteSession(pool, ctx, profileId)
|
||||
|
|
@ -51,6 +65,13 @@ func deleteSession(pool *pgxpool.Pool, ctx context.Context, profileId int) {
|
|||
}
|
||||
}
|
||||
|
||||
func GetProfile(pool *pgxpool.Pool, ctx context.Context) {
|
||||
func GetProfile(pool *pgxpool.Pool, ctx context.Context, profileId int) User {
|
||||
user := User{}
|
||||
row := pool.QueryRow(ctx, GetUser, profileId)
|
||||
err := row.Scan(&user.UserId, &user.GsbrCode, &user.Password, &user.Email, &user.UniqueNick, &user.FirstName, &user.LastName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func generateProof(gpcmChallenge, nasChallenge, authToken, clientChallenge strin
|
|||
return generateResponse(clientChallenge, nasChallenge, authToken, gpcmChallenge)
|
||||
}
|
||||
|
||||
func login(pool *pgxpool.Pool, ctx context.Context, command *common.GameSpyCommand, challenge string) string {
|
||||
func login(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyCommand, challenge string) string {
|
||||
// TODO: Validate login token with one in database
|
||||
authToken := command.OtherValues["authtoken"]
|
||||
response := generateResponse(challenge, "0qUekMb4", authToken, command.OtherValues["challenge"])
|
||||
|
|
@ -45,7 +45,8 @@ func login(pool *pgxpool.Pool, ctx context.Context, command *common.GameSpyComma
|
|||
// Perform the login with the database.
|
||||
user := database.LoginUserToGCPM(pool, ctx, authToken)
|
||||
loginTicket := strings.Replace(base64.StdEncoding.EncodeToString([]byte(common.RandomString(16))), "=", "_", -1)
|
||||
|
||||
// TODO: REMOVE!!!!!
|
||||
userId = user.UserId
|
||||
// Now initiate the session
|
||||
_ = database.CreateSession(pool, ctx, user.ProfileId, loginTicket)
|
||||
|
||||
|
|
|
|||
41
gpcm/main.go
41
gpcm/main.go
|
|
@ -16,8 +16,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
pool *pgxpool.Pool
|
||||
ctx = context.Background()
|
||||
pool *pgxpool.Pool
|
||||
userId int
|
||||
)
|
||||
|
||||
func checkError(err error) {
|
||||
|
|
@ -89,25 +90,31 @@ func handleRequest(conn net.Conn) {
|
|||
}
|
||||
}
|
||||
|
||||
command, err := common.ParseGameSpyMessage(string(buffer))
|
||||
commands, err := common.ParseGameSpyMessage(string(buffer))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("%s: Message received. Command: %s", aurora.Green("[NOTICE]"), aurora.Yellow(command.Command))
|
||||
switch command.Command {
|
||||
case "ka":
|
||||
conn.Write([]byte(`\ka\final\`))
|
||||
break
|
||||
case "login":
|
||||
payload := login(pool, ctx, command, challenge)
|
||||
conn.Write([]byte(payload))
|
||||
break
|
||||
case "getprofile":
|
||||
payload := getProfile(pool, ctx, command)
|
||||
fmt.Println(payload)
|
||||
conn.Write([]byte(payload))
|
||||
break
|
||||
for _, command := range commands {
|
||||
log.Printf("%s: Message received. Command: %s", aurora.Green("[NOTICE]"), aurora.Yellow(command.Command))
|
||||
switch command.Command {
|
||||
case "ka":
|
||||
conn.Write([]byte(`\ka\\final\`))
|
||||
break
|
||||
case "login":
|
||||
payload := login(pool, ctx, command, challenge)
|
||||
conn.Write([]byte(payload))
|
||||
break
|
||||
case "getprofile":
|
||||
payload := getProfile(pool, ctx, command)
|
||||
fmt.Println(payload)
|
||||
conn.Write([]byte(payload))
|
||||
break
|
||||
case "updatepro":
|
||||
// Nothing is written here.
|
||||
updateProfile(pool, ctx, command)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,28 +2,31 @@ package gpcm
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"strconv"
|
||||
"wwfc/common"
|
||||
"wwfc/database"
|
||||
)
|
||||
|
||||
func getProfile(pool *pgxpool.Pool, ctx context.Context, command *common.GameSpyCommand) string {
|
||||
for k, v := range command.OtherValues {
|
||||
fmt.Println(fmt.Sprintf("%s: %s", k, v))
|
||||
}
|
||||
func getProfile(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyCommand) string {
|
||||
strProfileId := command.OtherValues["profileid"]
|
||||
profileId, _ := strconv.Atoi(strProfileId)
|
||||
|
||||
sig := hex.EncodeToString([]byte(common.RandomString(16)))
|
||||
user := database.GetProfile(pool, ctx, profileId)
|
||||
|
||||
_ = common.RandomHexString(32)
|
||||
return common.CreateGameSpyMessage(common.GameSpyCommand{
|
||||
Command: "pi",
|
||||
CommandValue: "",
|
||||
OtherValues: map[string]string{
|
||||
"profileid": command.OtherValues["profileid"],
|
||||
"nick": "7me4ijr5sRMCJ23ul711",
|
||||
"userid": "8467681766588",
|
||||
"email": "7me4ijr5sRMCJ23ul711@nds",
|
||||
"sig": sig,
|
||||
"uniquenick": "7me4ijr5sRMCJ23ul711",
|
||||
"nick": user.UniqueNick,
|
||||
"userid": strconv.Itoa(user.UserId),
|
||||
"email": user.Email,
|
||||
"sig": "b126556e5ee62d4da9629dfad0f6b2a8",
|
||||
"uniquenick": user.UniqueNick,
|
||||
"firstname": user.FirstName,
|
||||
"lastname": user.LastName,
|
||||
"pid": "11",
|
||||
"lon": "0.000000",
|
||||
"lat": "0.000000",
|
||||
|
|
@ -32,3 +35,28 @@ func getProfile(pool *pgxpool.Pool, ctx context.Context, command *common.GameSpy
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
func updateProfile(pool *pgxpool.Pool, ctx context.Context, command common.GameSpyCommand) {
|
||||
var firstName string
|
||||
var lastName string
|
||||
if v, ok := command.OtherValues["firstname"]; ok {
|
||||
firstName = v
|
||||
}
|
||||
|
||||
if v, ok := command.OtherValues["lastname"]; ok {
|
||||
lastName = v
|
||||
}
|
||||
|
||||
database.UpdateUser(pool, ctx, firstName, lastName, userId)
|
||||
}
|
||||
|
||||
func createStatus() string {
|
||||
return common.CreateGameSpyMessage(common.GameSpyCommand{
|
||||
Command: "bm",
|
||||
CommandValue: "100",
|
||||
OtherValues: map[string]string{
|
||||
"f": "5",
|
||||
"msg": "|s|0|ss|Offline",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package nas
|
|||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/logrusorgru/aurora/v3"
|
||||
"log"
|
||||
"net/http"
|
||||
|
|
@ -59,6 +60,7 @@ func (route *Route) Handle() http.Handler {
|
|||
path := strings.Replace(r.URL.Path, "/", "", -1)
|
||||
actionName, _ := base64.StdEncoding.DecodeString(strings.Replace(r.PostForm.Get("action"), "*", "=", -1))
|
||||
|
||||
fmt.Println(string(actionName))
|
||||
var action Action
|
||||
for _, _action := range route.Actions {
|
||||
if path == _action.ServiceType && string(actionName) == _action.ActionName {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user