mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-13 15:34:38 +01:00
objects v3
This commit is contained in:
11
patch-schema/dbuserbinaries.sql
Normal file
11
patch-schema/dbuserbinaries.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE user_binaries
|
||||
(
|
||||
id int PRIMARY KEY,
|
||||
type1 bytea,
|
||||
type2 bytea,
|
||||
type3 bytea
|
||||
);
|
||||
|
||||
END;
|
||||
@@ -183,6 +183,8 @@ func handleMsgSysLogin(s *Session, p mhfpacket.MHFPacket) {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
|
||||
updateRights(s)
|
||||
|
||||
s.server.BroadcastMHF(&mhfpacket.MsgSysInsertUser{CharID: s.charID}, s)
|
||||
}
|
||||
|
||||
func handleMsgSysLogout(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
@@ -34,7 +34,7 @@ func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) {
|
||||
OwnerCharID: newObj.ownerCharID,
|
||||
}
|
||||
|
||||
s.logger.Info(fmt.Sprintf("Broadcasting new object: %s (%d)", s.Name, s.charID))
|
||||
s.logger.Info(fmt.Sprintf("Broadcasting new object: %s (%d)", s.Name, newObj.id))
|
||||
s.stage.BroadcastMHF(dupObjUpdate, s)
|
||||
}
|
||||
|
||||
@@ -63,9 +63,16 @@ func handleMsgSysDuplicateObject(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func handleMsgSysSetObjectBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgSysSetObjectBinary)
|
||||
for _, object := range s.stage.objects {
|
||||
if object.id == pkt.ObjID {
|
||||
object.binary = pkt.RawDataPayload
|
||||
for _, session := range s.server.sessions {
|
||||
if session.charID == s.charID {
|
||||
s.server.userBinaryPartsLock.Lock()
|
||||
s.server.userBinaryParts[userBinaryPartID{charID: s.charID, index: 3}] = pkt.RawDataPayload
|
||||
s.server.userBinaryPartsLock.Unlock()
|
||||
msg := &mhfpacket.MsgSysNotifyUserBinary{
|
||||
CharID: s.charID,
|
||||
BinaryType: 3,
|
||||
}
|
||||
s.server.BroadcastMHF(msg, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package channelserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
@@ -51,7 +52,7 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
||||
|
||||
// Save our new stage ID and pointer to the new stage itself.
|
||||
s.Lock()
|
||||
s.stageID = string(stageID)
|
||||
s.stageID = stageID
|
||||
s.stage = s.server.stages[stageID]
|
||||
s.Unlock()
|
||||
|
||||
@@ -61,13 +62,41 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
||||
// Confirm the stage entry.
|
||||
doAckSimpleSucceed(s, ackHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||
|
||||
var temp mhfpacket.MHFPacket
|
||||
newNotif := byteframe.NewByteFrame()
|
||||
|
||||
// Cast existing user data to new user
|
||||
if !s.userEnteredStage {
|
||||
s.userEnteredStage = true
|
||||
|
||||
for _, session := range s.server.sessions {
|
||||
if s == session {
|
||||
continue
|
||||
}
|
||||
temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID}
|
||||
newNotif.WriteUint16(uint16(temp.Opcode()))
|
||||
temp.Build(newNotif, s.clientContext)
|
||||
for i := 0; i < 3; i++ {
|
||||
temp = &mhfpacket.MsgSysNotifyUserBinary{
|
||||
CharID: session.charID,
|
||||
BinaryType: uint8(i + 1),
|
||||
}
|
||||
newNotif.WriteUint16(uint16(temp.Opcode()))
|
||||
temp.Build(newNotif, s.clientContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if s.stage != nil { // avoids lock up when using bed for dream quests
|
||||
// Notify the client to duplicate the existing objects.
|
||||
s.logger.Info("Sending existing stage objects")
|
||||
clientDupObjNotif := byteframe.NewByteFrame()
|
||||
s.logger.Info(fmt.Sprintf("Sending existing stage objects to %s", s.Name))
|
||||
s.stage.RLock()
|
||||
var temp mhfpacket.MHFPacket
|
||||
for _, obj := range s.stage.objects {
|
||||
cur := &mhfpacket.MsgSysDuplicateObject{
|
||||
if obj.ownerCharID == s.charID {
|
||||
continue
|
||||
}
|
||||
temp = &mhfpacket.MsgSysDuplicateObject{
|
||||
ObjID: obj.id,
|
||||
X: obj.x,
|
||||
Y: obj.y,
|
||||
@@ -75,14 +104,15 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
||||
Unk0: 0,
|
||||
OwnerCharID: obj.ownerCharID,
|
||||
}
|
||||
clientDupObjNotif.WriteUint16(uint16(cur.Opcode()))
|
||||
cur.Build(clientDupObjNotif, s.clientContext)
|
||||
newNotif.WriteUint16(uint16(temp.Opcode()))
|
||||
temp.Build(newNotif, s.clientContext)
|
||||
}
|
||||
s.stage.RUnlock()
|
||||
clientDupObjNotif.WriteUint16(0x0010) // End it.
|
||||
if len(clientDupObjNotif.Data()) > 2 {
|
||||
s.QueueSend(clientDupObjNotif.Data())
|
||||
}
|
||||
|
||||
newNotif.WriteUint16(0x0010) // End it.
|
||||
if len(newNotif.Data()) > 2 {
|
||||
s.QueueSend(newNotif.Data())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,68 +12,19 @@ func handleMsgSysInsertUser(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func handleMsgSysDeleteUser(s *Session, p mhfpacket.MHFPacket) {}
|
||||
|
||||
func broadcastNewUser(s *Session) {
|
||||
s.logger.Debug(fmt.Sprintf("Broadcasting new user: %s (%d)", s.Name, s.charID))
|
||||
|
||||
clientNotif := byteframe.NewByteFrame()
|
||||
var temp mhfpacket.MHFPacket
|
||||
for _, session := range s.server.sessions {
|
||||
if session == s || !session.binariesDone {
|
||||
continue
|
||||
}
|
||||
temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID}
|
||||
clientNotif.WriteUint16(uint16(temp.Opcode()))
|
||||
temp.Build(clientNotif, s.clientContext)
|
||||
for i := 0; i < 3; i++ {
|
||||
temp = &mhfpacket.MsgSysNotifyUserBinary{
|
||||
CharID: session.charID,
|
||||
BinaryType: uint8(i + 1),
|
||||
}
|
||||
clientNotif.WriteUint16(uint16(temp.Opcode()))
|
||||
temp.Build(clientNotif, s.clientContext)
|
||||
}
|
||||
}
|
||||
s.QueueSend(clientNotif.Data())
|
||||
|
||||
serverNotif := byteframe.NewByteFrame()
|
||||
temp = &mhfpacket.MsgSysInsertUser{CharID: s.charID}
|
||||
serverNotif.WriteUint16(uint16(temp.Opcode()))
|
||||
temp.Build(serverNotif, s.clientContext)
|
||||
for i := 0; i < 3; i++ {
|
||||
temp = &mhfpacket.MsgSysNotifyUserBinary{
|
||||
CharID: s.charID,
|
||||
BinaryType: uint8(i + 1),
|
||||
}
|
||||
serverNotif.WriteUint16(uint16(temp.Opcode()))
|
||||
temp.Build(serverNotif, s.clientContext)
|
||||
}
|
||||
for _, session := range s.server.sessions {
|
||||
if session == s || !session.binariesDone {
|
||||
continue
|
||||
}
|
||||
session.QueueSend(serverNotif.Data())
|
||||
}
|
||||
}
|
||||
|
||||
func handleMsgSysSetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgSysSetUserBinary)
|
||||
s.server.userBinaryPartsLock.Lock()
|
||||
s.server.userBinaryParts[userBinaryPartID{charID: s.charID, index: pkt.BinaryType}] = pkt.RawDataPayload
|
||||
s.server.userBinaryPartsLock.Unlock()
|
||||
|
||||
// Insert user once all binary parts exist
|
||||
if !s.binariesDone {
|
||||
for i := 0; i < 3; i++ {
|
||||
_, exists := s.server.userBinaryParts[userBinaryPartID{charID: s.charID, index: uint8(i + 1)}]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
}
|
||||
s.binariesDone = true
|
||||
broadcastNewUser(s)
|
||||
return
|
||||
err := s.server.db.QueryRow("SELECT type1 FROM user_binaries WHERE id=$1", s.charID)
|
||||
if err != nil {
|
||||
s.server.db.Exec("INSERT INTO user_binaries (id) VALUES ($1)", s.charID)
|
||||
}
|
||||
|
||||
s.server.db.Exec(fmt.Sprintf("UPDATE user_binaries SET type%d=$1 WHERE id=$2", pkt.BinaryType), pkt.RawDataPayload, s.charID)
|
||||
|
||||
msg := &mhfpacket.MsgSysNotifyUserBinary{
|
||||
CharID: s.charID,
|
||||
BinaryType: pkt.BinaryType,
|
||||
@@ -91,25 +42,18 @@ func handleMsgSysGetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||
data, ok := s.server.userBinaryParts[userBinaryPartID{charID: pkt.CharID, index: pkt.BinaryType}]
|
||||
resp := byteframe.NewByteFrame()
|
||||
|
||||
// If we can't get the real data, use a placeholder.
|
||||
// If we can't get the real data, try to get it from the database.
|
||||
if !ok {
|
||||
if pkt.BinaryType == 1 {
|
||||
// Stub name response with character ID
|
||||
resp.WriteBytes([]byte(fmt.Sprintf("CID%d", s.charID)))
|
||||
resp.WriteUint8(0) // NULL terminator.
|
||||
} else if pkt.BinaryType == 2 {
|
||||
data, err := base64.StdEncoding.DecodeString("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBn8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAwAAAAAAAAAAAAAABAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resp.WriteBytes(data)
|
||||
} else if pkt.BinaryType == 3 {
|
||||
data, err := base64.StdEncoding.DecodeString("AQAAA2ea5P8ATgEA/wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBn8AAAAAAAAAAAABAKAMAAAAAAAAAAAAACgAAAAAAAAAAAABAsQOAAAAAAAAAAABA6UMAAAAAAAAAAABBKAMAAAAAAAAAAABBToNAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var data []byte
|
||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("SELECT type%d FROM user_binaries WHERE id=$1", pkt.BinaryType), pkt.CharID)
|
||||
for rows.Next() {
|
||||
rows.Scan(&data)
|
||||
resp.WriteBytes(data)
|
||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||
return
|
||||
}
|
||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
} else {
|
||||
resp.WriteBytes(data)
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ func (s *Server) manageSessions() {
|
||||
func (s *Server) BroadcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session) {
|
||||
// Broadcast the data.
|
||||
for _, session := range s.sessions {
|
||||
if session == ignoredSession || !session.binariesDone {
|
||||
if session == ignoredSession {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ func (s *Server) BroadcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session)
|
||||
func (s *Server) WorldcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session) {
|
||||
for _, c := range s.Channels {
|
||||
for _, session := range c.sessions {
|
||||
if session == ignoredSession || !session.binariesDone {
|
||||
if session == ignoredSession {
|
||||
continue
|
||||
}
|
||||
bf := byteframe.NewByteFrame()
|
||||
|
||||
@@ -27,12 +27,12 @@ type Session struct {
|
||||
sendPackets chan []byte
|
||||
clientContext *clientctx.ClientContext
|
||||
|
||||
userEnteredStage bool // If the user has entered a stage before
|
||||
myseries MySeries
|
||||
stageID string
|
||||
stage *Stage
|
||||
reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet.
|
||||
stagePass string // Temporary storage
|
||||
binariesDone bool
|
||||
charID uint32
|
||||
logKey []byte
|
||||
sessionStart int64
|
||||
@@ -79,7 +79,7 @@ func NewSession(server *Server, conn net.Conn) *Session {
|
||||
Encoding: japanese.ShiftJIS,
|
||||
},
|
||||
},
|
||||
binariesDone: false,
|
||||
userEnteredStage: false,
|
||||
sessionStart: Time_Current_Adjusted().Unix(),
|
||||
stageMoveStack: stringstack.New(),
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ type Object struct {
|
||||
id uint32
|
||||
ownerCharID uint32
|
||||
x, y, z float32
|
||||
binary []byte
|
||||
}
|
||||
|
||||
// stageBinaryKey is a struct used as a map key for identifying a stage binary part.
|
||||
@@ -33,7 +32,7 @@ type Stage struct {
|
||||
|
||||
// Objects
|
||||
objects map[uint32]*Object
|
||||
objectIndex uint32
|
||||
objectIndex uint8
|
||||
|
||||
// Map of session -> charID.
|
||||
// These are clients that are CURRENTLY in the stage
|
||||
@@ -71,7 +70,7 @@ func NewStage(ID string) *Stage {
|
||||
func (s *Stage) BroadcastMHF(pkt mhfpacket.MHFPacket, ignoredSession *Session) {
|
||||
// Broadcast the data.
|
||||
for session := range s.clients {
|
||||
if session == ignoredSession || !session.binariesDone {
|
||||
if session == ignoredSession {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -130,5 +129,10 @@ func (s *Stage) GetName() string {
|
||||
|
||||
func (s *Stage) NextObjectID() uint32 {
|
||||
s.objectIndex = s.objectIndex + 1
|
||||
return s.objectIndex
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint8(0)
|
||||
bf.WriteUint8(s.objectIndex)
|
||||
bf.WriteUint16(0)
|
||||
obj := uint32(bf.Data()[3]) | uint32(bf.Data()[2])<<8 | uint32(bf.Data()[1])<<16 | uint32(bf.Data()[0])<<24
|
||||
return obj
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user