Compare commits

...

3 Commits

6 changed files with 50 additions and 53 deletions

View File

@ -17,33 +17,24 @@ type Inventory struct {
// start && end are both inclusive
func (db *DBHandler) GetPlayerInventorySlots(PlayerID int, start int, end int) ([]protocol.SItemBase, error) {
rows, err := db.Query("SELECT PlayerID, Slot, ID, Type, Opt, TimeLimit FROM Inventory WHERE Slot BETWEEN ? AND ? AND PlayerID = ?", start, end, PlayerID)
rows, err := db.Query("SELECT Slot, Type, ID, Opt, TimeLimit FROM Inventory WHERE Slot BETWEEN ? AND ? AND PlayerID = ?", start, end, PlayerID)
if err != nil {
return nil, err
}
var inven []Inventory
items := make([]protocol.SItemBase, end-start)
for rows.Next() {
item := Inventory{}
var slot int
item := protocol.SItemBase{}
if err := rows.Scan(
&item.PlayerID, &item.Slot, &item.ID, &item.Type, &item.Opt, &item.TimeLimit); err != nil {
&slot, &item.IType, &item.IID, &item.IOpt, &item.ITimeLimit); err != nil {
return nil, err
}
inven = append(inven, item)
items[slot-start] = item
}
// populate an SItemBase array
items := make([]protocol.SItemBase, end-start)
for _, item := range inven {
items[item.Slot-start] = protocol.SItemBase{
IID: int16(item.ID),
IType: int16(item.Type),
IOpt: int32(item.Opt),
ITimeLimit: int32(item.TimeLimit),
}
}
return items, nil
}
@ -51,7 +42,7 @@ func (db *DBHandler) GetPlayerInventorySlots(PlayerID int, start int, end int) (
func (db *DBHandler) SetPlayerInventorySlots(PlayerID int, start int, items []protocol.SItemBase) error {
return db.Transaction(func(tx *sql.Tx) error {
// delete inventory slots
_, err := db.Query("DELETE FROM Inventory WHERE Slot BETWEEN ? AND ? AND PlayerID = ?", start, start+len(items)-1, PlayerID)
_, err := db.Exec("DELETE FROM Inventory WHERE Slot BETWEEN ? AND ? AND PlayerID = ?", start, start+len(items)-1, PlayerID)
if err != nil {
return err
}
@ -59,7 +50,7 @@ func (db *DBHandler) SetPlayerInventorySlots(PlayerID int, start int, items []pr
// insert inventory
for i, item := range items {
if item.IID != 0 {
_, err := db.Query("INSERT INTO Inventory (PlayerID, Slot, ID, Type, Opt, TimeLimit) VALUES (?, ?, ?, ?, ?, ?)", PlayerID, start+i, item.IID, item.IType, item.IOpt, item.ITimeLimit)
_, err := db.Exec("INSERT INTO Inventory (PlayerID, Slot, ID, Type, Opt, TimeLimit) VALUES (?, ?, ?, ?, ?, ?)", PlayerID, start+i, item.IID, item.IType, item.IOpt, item.ITimeLimit)
if err != nil {
return err
}

View File

@ -17,11 +17,6 @@ type DBHandler struct {
db *sql.DB
}
type DBQuery interface {
Query(query string, args ...any) (*sql.Rows, error)
Exec(query string, args ...any) (sql.Result, error)
}
//go:embed migrations/new.sql
var createDBQuery string

View File

@ -5,7 +5,7 @@ import (
"sync"
)
var allocator = sync.Pool{
var allocator = &sync.Pool{
New: func() any { return new(bytes.Buffer) },
}

View File

@ -105,9 +105,14 @@ func (server *LoginServer) Login(peer *Peer, pkt protocol.Packet) error {
return err
}
// truncate plrs
if len(plrs) > 3 {
plrs = plrs[:4]
}
// build character list
charInfo := make([]protocol.SP_LS2CL_REP_CHAR_INFO, 0, 4)
for _, plr := range plrs {
charInfo := [4]protocol.SP_LS2CL_REP_CHAR_INFO{}
for i, plr := range plrs {
PCStyle, PCStyle2 := util.Player2PCStyle(&plr)
info := protocol.SP_LS2CL_REP_CHAR_INFO{
ISlot: int8(plr.Slot),
@ -126,10 +131,10 @@ func (server *LoginServer) Login(peer *Peer, pkt protocol.Packet) error {
}
copy(info.AEquip[:], AEquip)
charInfo = append(charInfo, info)
charInfo[i] = info
}
return server.AcceptLogin(peer, loginPkt.SzID, loginPkt.IClientVerC, 1, charInfo)
return server.AcceptLogin(peer, loginPkt.SzID, loginPkt.IClientVerC, 1, charInfo[:len(plrs)])
}
func (server *LoginServer) CheckCharacterName(peer *Peer, pkt protocol.Packet) error {
@ -191,6 +196,7 @@ func validateCharacterCreation(character *protocol.SP_CL2LS_REQ_CHAR_CREATE) boo
return false
}
// TODO: sanity check items in SOn_Item; see db.FinishPlayer()
return true
}

View File

@ -17,6 +17,8 @@ type LoginServer struct {
peersLock sync.Mutex
}
func stubbedPacket(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil }
func NewLoginServer() *LoginServer {
listener, err := net.Listen("tcp", ":23000")
if err != nil {
@ -24,25 +26,26 @@ func NewLoginServer() *LoginServer {
}
loginServer := &LoginServer{
listener: listener,
packetHandlers: make(map[uint32]PacketHandler),
peers: make(map[*Peer]bool),
listener: listener,
peers: make(map[*Peer]bool),
}
loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_LOGIN, loginServer.Login)
loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_CHECK_CHAR_NAME, loginServer.CheckCharacterName)
loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_SAVE_CHAR_NAME, loginServer.SaveCharacterName)
loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_CHAR_CREATE, loginServer.CharacterCreate)
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_CHAR_SELECT, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_CHAR_DELETE, loginServer.CharacterDelete)
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_SHARD_SELECT, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_SHARD_LIST_INFO, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_CHECK_NAME_LIST, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_SAVE_CHAR_TUTOR, loginServer.FinishTutorial)
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_PC_EXIT_DUPLICATE, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_REP_LIVE_CHECK, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_CHANGE_CHAR_NAME, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
// loginServer.RegisterPacketHandler(protocol.P_CL2LS_REQ_SERVER_SELECT, func(_ *Peer, _ protocol.Packet) error { /* stubbed */ return nil })
loginServer.packetHandlers = map[uint32]PacketHandler{
protocol.P_CL2LS_REQ_LOGIN: loginServer.Login,
protocol.P_CL2LS_REQ_CHECK_CHAR_NAME: loginServer.CheckCharacterName,
protocol.P_CL2LS_REQ_SAVE_CHAR_NAME: loginServer.SaveCharacterName,
protocol.P_CL2LS_REQ_CHAR_CREATE: loginServer.CharacterCreate,
protocol.P_CL2LS_REQ_CHAR_SELECT: stubbedPacket,
protocol.P_CL2LS_REQ_CHAR_DELETE: loginServer.CharacterDelete,
protocol.P_CL2LS_REQ_SHARD_SELECT: stubbedPacket,
protocol.P_CL2LS_REQ_SHARD_LIST_INFO: stubbedPacket,
protocol.P_CL2LS_CHECK_NAME_LIST: stubbedPacket,
protocol.P_CL2LS_REQ_SAVE_CHAR_TUTOR: loginServer.FinishTutorial,
protocol.P_CL2LS_REQ_PC_EXIT_DUPLICATE: stubbedPacket,
protocol.P_CL2LS_REP_LIVE_CHECK: stubbedPacket,
protocol.P_CL2LS_REQ_CHANGE_CHAR_NAME: stubbedPacket,
protocol.P_CL2LS_REQ_SERVER_SELECT: stubbedPacket,
}
return loginServer
}
@ -73,7 +76,7 @@ func (server *LoginServer) HandlePacket(peer *Peer, typeID uint32, pkt protocol.
return err
}
} else {
log.Printf("[WARN] unsupported packet ID: %x\n", typeID)
log.Printf("[WARN] invalid packet ID: %x\n", typeID)
}
return nil

View File

@ -24,15 +24,15 @@ type PeerHandler interface {
}
type Peer struct {
Player *db.Player
conn net.Conn
handler PeerHandler
SzID string
E_key []byte
FE_key []byte
SzID string
AccountID int
Player *db.Player
handler PeerHandler
conn net.Conn
alive bool
whichKey int
alive bool
}
func NewPeer(handler PeerHandler, conn net.Conn) *Peer {
@ -50,14 +50,15 @@ func NewPeer(handler PeerHandler, conn net.Conn) *Peer {
}
func (peer *Peer) Send(typeID uint32, data ...interface{}) error {
// grab buffer from pool
buf := pool.Get()
defer pool.Put(buf) // always return the buffer to the pool
defer pool.Put(buf)
// body start
pkt := protocol.NewPacket(buf)
// encode type id
if err := pkt.Encode(uint32(typeID)); err != nil {
if err := pkt.Encode(typeID); err != nil {
return err
}
@ -117,8 +118,9 @@ func (peer *Peer) Handler() {
return
}
// read packet body
// grab buffer && read packet body
buf := pool.Get()
defer pool.Put(buf)
if _, err := buf.ReadFrom(io.LimitReader(peer.conn, int64(sz))); err != nil {
log.Printf("[FATAL] failed to read packet body! %v", err)
return