mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-16 08:55:31 +01:00
Initial chat prototype
This commit is contained in:
56
server/signserver/dbutils.go
Normal file
56
server/signserver/dbutils.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package signserver
|
||||
|
||||
import "time"
|
||||
|
||||
func (s *Server) registerDBAccount(username string, password string) error {
|
||||
_, err := s.db.Exec("INSERT INTO users (username, password) VALUES ($1, $2)", username, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var id int
|
||||
err = s.db.QueryRow("SELECT id FROM users WHERE username = $1", username).Scan(&id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create a base new character.
|
||||
_, err = s.db.Exec(`
|
||||
INSERT INTO characters (
|
||||
user_id, is_female, is_new_character, small_gr_level, gr_override_mode, name, unk_desc_string,
|
||||
gr_override_level, gr_override_unk0, gr_override_unk1, exp, weapon, last_login)
|
||||
VALUES($1, False, True, 0, True, '', '', 0, 0, 0, 0, 0, $2)`,
|
||||
id,
|
||||
uint32(time.Now().Unix()),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type character struct {
|
||||
ID uint32 `db:"id"`
|
||||
IsFemale bool `db:"is_female"`
|
||||
IsNewCharacter bool `db:"is_new_character"`
|
||||
SmallGRLevel uint8 `db:"small_gr_level"`
|
||||
GROverrideMode bool `db:"gr_override_mode"`
|
||||
Name string `db:"name"`
|
||||
UnkDescString string `db:"unk_desc_string"`
|
||||
GROverrideLevel uint16 `db:"gr_override_level"`
|
||||
GROverrideUnk0 uint8 `db:"gr_override_unk0"`
|
||||
GROverrideUnk1 uint8 `db:"gr_override_unk1"`
|
||||
Exp uint16 `db:"exp"`
|
||||
Weapon uint16 `db:"weapon"`
|
||||
LastLogin uint32 `db:"last_login"`
|
||||
}
|
||||
|
||||
func (s *Server) getCharactersForUser(uid int) ([]character, error) {
|
||||
characters := []character{}
|
||||
err := s.db.Select(&characters, "SELECT id, is_female, is_new_character, small_gr_level, gr_override_mode, name, unk_desc_string, gr_override_level, gr_override_unk0, gr_override_unk1, exp, weapon, last_login FROM characters WHERE user_id = $1", uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return characters, nil
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
package signserver
|
||||
|
||||
import "github.com/Andoryuuta/byteframe"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func paddedString(x string, size uint) []byte {
|
||||
out := make([]byte, size)
|
||||
@@ -27,91 +32,45 @@ func makeSignInFailureResp(respID RespID) []byte {
|
||||
return bf.Data()
|
||||
}
|
||||
|
||||
func (session *Session) makeSignInResp(username string) []byte {
|
||||
bf := byteframe.NewByteFrame()
|
||||
func (s *Session) makeSignInResp(uid int) []byte {
|
||||
// Get the characters from the DB.
|
||||
chars, err := s.server.getCharactersForUser(uid)
|
||||
if err != nil {
|
||||
s.logger.Warn("Error getting characters from DB", zap.Error(err))
|
||||
}
|
||||
|
||||
// delete me:
|
||||
//bf.WriteUint8(8)
|
||||
//return bf.Data()
|
||||
bf := byteframe.NewByteFrame()
|
||||
|
||||
bf.WriteUint8(1) // resp_code
|
||||
bf.WriteUint8(0) // file/patch server count
|
||||
bf.WriteUint8(4) // entrance server count
|
||||
bf.WriteUint8(1) // character count
|
||||
bf.WriteUint8(uint8(len(chars))) // character count
|
||||
bf.WriteUint32(0xFFFFFFFF) // login_token_number
|
||||
bf.WriteBytes(paddedString("logintokenstrng", 16)) // login_token (16 byte padded string)
|
||||
bf.WriteUint32(1576761190)
|
||||
|
||||
// file patch server PascalStrings here
|
||||
|
||||
// Array(this.entrance_server_count, PascalString(Byte, "utf8")),
|
||||
uint8PascalString(bf, "localhost:53310")
|
||||
uint8PascalString(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.HostIP, s.server.erupeConfig.Entrance.Port))
|
||||
uint8PascalString(bf, "")
|
||||
uint8PascalString(bf, "")
|
||||
uint8PascalString(bf, "mhf-n.capcom.com.tw")
|
||||
|
||||
///////////////////////////
|
||||
// Characters:
|
||||
|
||||
/*
|
||||
tab = '123456789ABCDEFGHJKLMNPQRTUVWXYZ'
|
||||
def make_uid_str(cid):
|
||||
out = ''
|
||||
for i in range(6):
|
||||
v = (cid>>5*i)
|
||||
out += tab[v&0x1f]
|
||||
return out
|
||||
|
||||
def make_cid_int(uid):
|
||||
v = 0
|
||||
for c in uid[::-1]:
|
||||
idx = tab.find(c)
|
||||
if idx == -1:
|
||||
raise Exception("not in tab")
|
||||
v |= idx
|
||||
v = v<<5
|
||||
return v>>5
|
||||
*/
|
||||
bf.WriteUint32(469153291) // character ID 469153291
|
||||
bf.WriteUint16(999) // Exp, HR[x] is split by 0, 1, 30, 50, 99, 299, 998, 999
|
||||
|
||||
//44.204
|
||||
|
||||
/*
|
||||
0=大劍/Big sword
|
||||
1=重弩/Heavy crossbow
|
||||
2=大錘/Sledgehammer
|
||||
3=長槍/Spear
|
||||
4=單手劍/One-handed sword
|
||||
5=輕弩/Light crossbow
|
||||
6=雙劍/Double sword
|
||||
7=太刀/Tadao
|
||||
8=狩獵笛/Hunting flute
|
||||
9=銃槍/Shotgun
|
||||
10=弓/bow
|
||||
11=穿龍棍/Wear a dragon stick
|
||||
12=斬擊斧F/Chopping Axe F
|
||||
13=---
|
||||
default=不明/unknown
|
||||
*/
|
||||
bf.WriteUint16(7) // Weapon, 0-13.
|
||||
|
||||
bf.WriteUint32(1576761172) // Last login date, unix timestamp in seconds.
|
||||
bf.WriteUint8(1) // Sex, 0=male, 1=female.
|
||||
bf.WriteUint8(0) // Is new character, 1 replaces character name with ?????.
|
||||
grMode := uint8(0)
|
||||
bf.WriteUint8(1) // GR level if grMode == 0
|
||||
bf.WriteUint8(grMode) // GR mode.
|
||||
bf.WriteBytes(paddedString(username, 16)) // Character name
|
||||
bf.WriteBytes(paddedString("0", 32)) // unk str
|
||||
if grMode == 1 {
|
||||
bf.WriteUint16(55) // GR level override.
|
||||
bf.WriteUint8(0) // unk
|
||||
bf.WriteUint8(0) // unk
|
||||
for _, char := range chars {
|
||||
bf.WriteUint32(char.ID) // character ID 469153291
|
||||
bf.WriteUint16(char.Exp) // Exp, HR[x] is split by 0, 1, 30, 50, 99, 299, 998, 999
|
||||
bf.WriteUint16(char.Weapon) // Weapon, 0-13.
|
||||
bf.WriteUint32(char.LastLogin) // Last login date, unix timestamp in seconds.
|
||||
bf.WriteBool(char.IsFemale) // Sex, 0=male, 1=female.
|
||||
bf.WriteBool(char.IsNewCharacter) // Is new character, 1 replaces character name with ?????.
|
||||
bf.WriteUint8(char.SmallGRLevel) // GR level if grMode == 0
|
||||
bf.WriteBool(char.GROverrideMode) // GR mode.
|
||||
bf.WriteBytes(paddedString(char.Name, 16)) // Character name
|
||||
bf.WriteBytes(paddedString(char.UnkDescString, 32)) // unk str
|
||||
if char.GROverrideMode {
|
||||
bf.WriteUint16(char.GROverrideLevel) // GR level override.
|
||||
bf.WriteUint8(char.GROverrideUnk0) // unk
|
||||
bf.WriteUint8(char.GROverrideUnk1) // unk
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
|
||||
bf.WriteUint8(0) // friends_list_count
|
||||
bf.WriteUint8(0) // guild_members_count
|
||||
bf.WriteUint8(0) // notice_count
|
||||
|
||||
@@ -95,6 +95,25 @@ func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
|
||||
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)
|
||||
@@ -103,7 +122,7 @@ func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
|
||||
default:
|
||||
if reqPassword == password {
|
||||
s.logger.Info("Passwords match!")
|
||||
serverRespBytes = s.makeSignInResp(reqUsername)
|
||||
serverRespBytes = s.makeSignInResp(id)
|
||||
} else {
|
||||
s.logger.Info("Passwords don't match!")
|
||||
serverRespBytes = makeSignInFailureResp(SIGN_EPASS)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package signserver
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -9,13 +8,14 @@ import (
|
||||
|
||||
"github.com/Andoryuuta/Erupe/config"
|
||||
"github.com/Andoryuuta/Erupe/network"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Config struct allows configuring the server.
|
||||
type Config struct {
|
||||
Logger *zap.Logger
|
||||
DB *sql.DB
|
||||
DB *sqlx.DB
|
||||
ErupeConfig *config.Config
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type Server struct {
|
||||
erupeConfig *config.Config
|
||||
sid int
|
||||
sessions map[int]*Session
|
||||
db *sql.DB
|
||||
db *sqlx.DB
|
||||
listener net.Listener
|
||||
isShuttingDown bool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user