mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-21 19:34:45 +01:00
enumerate friends list across characters
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package stringsupport
|
package stringsupport
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
"strconv"
|
||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
@@ -114,6 +116,35 @@ func PaddedString(x string, size uint, t bool) []byte {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CSVAdd(csv string, v int) string {
|
||||||
|
if len(csv) == 0 {
|
||||||
|
return strconv.Itoa(v)
|
||||||
|
}
|
||||||
|
return csv + "," + strconv.Itoa(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CSVRemove(csv string, v int) string {
|
||||||
|
s := strings.Split(csv, ",")
|
||||||
|
for i, e := range s {
|
||||||
|
if e == strconv.Itoa(v) {
|
||||||
|
s[i] = s[len(s) - 1]
|
||||||
|
s = s[:len(s) - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(s, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func CSVContains(csv string, v int) bool {
|
||||||
|
s := strings.Split(csv, ",")
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
j, _ := strconv.ParseInt(s[i], 10, 64)
|
||||||
|
if int(j) == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ConvertUTF8ToShiftJIS converts a UTF8 string to a Shift-JIS []byte.
|
// ConvertUTF8ToShiftJIS converts a UTF8 string to a Shift-JIS []byte.
|
||||||
func ConvertUTF8ToShiftJIS(text string) ([]byte, error) {
|
func ConvertUTF8ToShiftJIS(text string) ([]byte, error) {
|
||||||
r := bytes.NewBuffer([]byte(text))
|
r := bytes.NewBuffer([]byte(text))
|
||||||
|
|||||||
@@ -9,7 +9,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfOprMember represents the MSG_MHF_OPR_MEMBER
|
// MsgMhfOprMember represents the MSG_MHF_OPR_MEMBER
|
||||||
type MsgMhfOprMember struct{}
|
type MsgMhfOprMember struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Blacklist bool
|
||||||
|
Operation bool
|
||||||
|
Unk uint16
|
||||||
|
CharID uint32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfOprMember) Opcode() network.PacketID {
|
func (m *MsgMhfOprMember) Opcode() network.PacketID {
|
||||||
@@ -18,7 +24,12 @@ func (m *MsgMhfOprMember) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfOprMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfOprMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Blacklist = bf.ReadBool()
|
||||||
|
m.Operation = bf.ReadBool()
|
||||||
|
m.Unk = bf.ReadUint16()
|
||||||
|
m.CharID = bf.ReadUint32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"erupe-ce/common/stringsupport"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@@ -60,8 +61,26 @@ func handleMsgMhfListMember(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfOprMember(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfOprMember(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfListMember)
|
pkt := p.(*mhfpacket.MsgMhfOprMember)
|
||||||
// TODO: add targetid(uint32) to charid(uint32)'s database under new field
|
var csv string
|
||||||
|
if pkt.Blacklist {
|
||||||
|
if pkt.Operation {
|
||||||
|
// remove from blacklist
|
||||||
|
} else {
|
||||||
|
// add to blacklist
|
||||||
|
}
|
||||||
|
} else { // Friendlist
|
||||||
|
err := s.server.db.QueryRow("SELECT friends FROM characters WHERE id=$1", s.charID).Scan(&csv)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if pkt.Operation {
|
||||||
|
csv = stringsupport.CSVRemove(csv, int(pkt.CharID))
|
||||||
|
} else {
|
||||||
|
csv = stringsupport.CSVAdd(csv, int(pkt.CharID))
|
||||||
|
}
|
||||||
|
_, _ = s.server.db.Exec("UPDATE characters SET friends=$1 WHERE id=$2", csv, s.charID)
|
||||||
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ type character struct {
|
|||||||
|
|
||||||
func (s *Server) getCharactersForUser(uid int) ([]character, error) {
|
func (s *Server) getCharactersForUser(uid int) ([]character, error) {
|
||||||
characters := []character{}
|
characters := []character{}
|
||||||
err := s.db.Select(&characters, "SELECT id, is_female, is_new_character, name, unk_desc_string, hrp, gr, weapon_type, last_login FROM characters WHERE user_id = $1 AND deleted = false ORDER BY last_login DESC", uid)
|
err := s.db.Select(&characters, "SELECT id, is_female, is_new_character, name, unk_desc_string, hrp, gr, weapon_type, last_login FROM characters WHERE user_id = $1 AND deleted = false", uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -96,28 +96,36 @@ func (s *Server) getCharactersForUser(uid int) ([]character, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type members struct {
|
type members struct {
|
||||||
|
CID uint32 // Local character ID
|
||||||
ID uint32 `db:"id"`
|
ID uint32 `db:"id"`
|
||||||
Name string `db:"name"`
|
Name string `db:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getFriendsForCharacter(cid uint32) ([]members, error) {
|
func (s *Server) getFriendsForCharacters(chars []character) ([]members, error) {
|
||||||
friends := []members{}
|
friends := make([]members, 0)
|
||||||
var friendsCSV string
|
for _, char := range chars {
|
||||||
err := s.db.QueryRow("SELECT friends FROM characters WHERE id=$1", cid).Scan(&friendsCSV)
|
friendsCSV := ""
|
||||||
friendsSlice := strings.Split(friendsCSV, ",")
|
err := s.db.QueryRow("SELECT friends FROM characters WHERE id=$1", char.ID).Scan(&friendsCSV)
|
||||||
if friendsSlice[0] == "" {
|
friendsSlice := strings.Split(friendsCSV, ",")
|
||||||
return nil, nil
|
friendQuery := "SELECT id, name FROM characters WHERE id="
|
||||||
}
|
for i := 0; i < len(friendsSlice); i++ {
|
||||||
friendQuery := "SELECT id, name FROM characters WHERE id="
|
friendQuery += friendsSlice[i]
|
||||||
for i := 0; i < len(friendsSlice); i++ {
|
if i + 1 != len(friendsSlice) {
|
||||||
friendQuery += friendsSlice[i]
|
friendQuery += " OR id="
|
||||||
if i + 1 != len(friendsSlice) {
|
}
|
||||||
friendQuery += " OR id="
|
|
||||||
}
|
}
|
||||||
|
charFriends := []members{}
|
||||||
|
err = s.db.Select(&charFriends, friendQuery)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for i, _ := range charFriends {
|
||||||
|
charFriends[i].CID = char.ID
|
||||||
|
}
|
||||||
|
friends = append(friends, charFriends...)
|
||||||
}
|
}
|
||||||
err = s.db.Select(&friends, friendQuery)
|
if len(friends) > 255 { // Uint8
|
||||||
if err != nil {
|
friends = friends[:255]
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return friends, nil
|
return friends, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,13 +75,13 @@ func (s *Session) makeSignInResp(uid int) []byte {
|
|||||||
bf.WriteUint16(0) // Unk
|
bf.WriteUint16(0) // Unk
|
||||||
}
|
}
|
||||||
|
|
||||||
friends, err := s.server.getFriendsForCharacter(lastPlayed)
|
friends, err := s.server.getFriendsForCharacters(chars)
|
||||||
if err != nil || friends == nil {
|
if err != nil || len(friends) == 0 {
|
||||||
bf.WriteUint8(0)
|
bf.WriteUint8(0)
|
||||||
} else {
|
} else {
|
||||||
bf.WriteUint8(uint8(len(friends)))
|
bf.WriteUint8(uint8(len(friends)))
|
||||||
for _, friend := range friends {
|
for _, friend := range friends {
|
||||||
bf.WriteUint32(lastPlayed)
|
bf.WriteUint32(friend.CID)
|
||||||
bf.WriteUint32(friend.ID)
|
bf.WriteUint32(friend.ID)
|
||||||
ps.Uint8(bf, friend.Name, true)
|
ps.Uint8(bf, friend.Name, true)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user