9 Commits

Author SHA1 Message Date
wish
e9bd0b2ddb Merge pull request #151 from Mezeporta/test/aobp 2025-12-17 09:27:56 +11:00
wish
5f265ee291 Merge pull request #144 from gab3-dev/patch-1
Fix typos in Docker README
2025-10-29 00:00:32 +11:00
Gabriel Henrique
2a297e693f Fix typos in Docker README
"soruce" to "source"
2025-10-28 09:33:52 -03:00
wish
ce364720de alpelo object system backport test commit 2025-10-05 16:19:34 +11:00
wish
c4ec2efde5 alpelo object system backport test commit 2025-10-05 16:18:22 +11:00
wish
aad3b088b9 alpelo object system backport test commit 2025-10-05 16:14:39 +11:00
wish
dd36f367a9 alpelo object system backport test commit 2025-10-05 16:10:47 +11:00
wish
531b3d2fa6 Remove unused import 'math' from handlers_guild.go
Removed unused 'math' import from handlers_guild.go
2025-08-29 22:56:46 +10:00
wish
7459dede49 fix guild poogie outfit unlock 2025-08-28 23:27:56 +10:00
7 changed files with 37 additions and 50 deletions

View File

@@ -1,7 +1,7 @@
# Docker for erupe # Docker for erupe
## Building the container ## Building the container
Run the following from the route of the soruce folder. In this example we give it the tag of dev to seperate it from any other container verions. Run the following from the route of the source folder. In this example we give it the tag of dev to seperate it from any other container verions.
```bash ```bash
docker build . -t erupe:dev docker build . -t erupe:dev
``` ```
@@ -67,4 +67,4 @@ docker-compose up
# Troubleshooting # Troubleshooting
Q: My Postgres will not populate. A: You're setup.sh is maybe saved as CRLF it needs to be saved as LF. Q: My Postgres will not populate. A: You're setup.sh is maybe saved as CRLF it needs to be saved as LF.

View File

@@ -183,7 +183,6 @@ func logoutPlayer(s *Session) {
delete(s.server.sessions, s.rawConn) delete(s.server.sessions, s.rawConn)
} }
s.rawConn.Close() s.rawConn.Close()
delete(s.server.objectIDs, s)
s.server.Unlock() s.server.Unlock()
for _, stage := range s.server.stages { for _, stage := range s.server.stages {

View File

@@ -8,7 +8,6 @@ import (
"erupe-ce/common/mhfitem" "erupe-ce/common/mhfitem"
_config "erupe-ce/config" _config "erupe-ce/config"
"fmt" "fmt"
"math"
"sort" "sort"
"strings" "strings"
"time" "time"
@@ -748,8 +747,7 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
case mhfpacket.OperateGuildChangePugi3: case mhfpacket.OperateGuildChangePugi3:
handleChangePugi(s, uint8(pkt.Data1.ReadUint32()), guild, 3) handleChangePugi(s, uint8(pkt.Data1.ReadUint32()), guild, 3)
case mhfpacket.OperateGuildUnlockOutfit: case mhfpacket.OperateGuildUnlockOutfit:
// TODO: This doesn't implement blocking, if someone unlocked the same outfit at the same time s.server.db.Exec(`UPDATE guilds SET pugi_outfits=$1 WHERE id=$2`, pkt.Data1.ReadUint32(), guild.ID)
s.server.db.Exec(`UPDATE guilds SET pugi_outfits=pugi_outfits+$1 WHERE id=$2`, int(math.Pow(float64(pkt.Data1.ReadUint32()), 2)), guild.ID)
case mhfpacket.OperateGuildDonateRoom: case mhfpacket.OperateGuildDonateRoom:
quantity := uint16(pkt.Data1.ReadUint32()) quantity := uint16(pkt.Data1.ReadUint32())
bf.WriteBytes(handleDonateRP(s, quantity, guild, 2)) bf.WriteBytes(handleDonateRP(s, quantity, guild, 2))

View File

@@ -12,7 +12,7 @@ func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) {
s.stage.Lock() s.stage.Lock()
newObj := &Object{ newObj := &Object{
id: s.NextObjectID(), id: s.getObjectId(),
ownerCharID: s.charID, ownerCharID: s.charID,
x: pkt.X, x: pkt.X,
y: pkt.Y, y: pkt.Y,

View File

@@ -8,6 +8,7 @@ import (
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
ps "erupe-ce/common/pascalstring" ps "erupe-ce/common/pascalstring"
"erupe-ce/network/mhfpacket" "erupe-ce/network/mhfpacket"
"go.uber.org/zap" "go.uber.org/zap"
) )
@@ -64,28 +65,24 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
// Confirm the stage entry. // Confirm the stage entry.
doAckSimpleSucceed(s, ackHandle, []byte{0x00, 0x00, 0x00, 0x00}) doAckSimpleSucceed(s, ackHandle, []byte{0x00, 0x00, 0x00, 0x00})
var temp mhfpacket.MHFPacket
newNotif := byteframe.NewByteFrame() newNotif := byteframe.NewByteFrame()
// Cast existing user data to new user // Cast existing user data to new user
if !s.userEnteredStage { if !s.loaded {
s.userEnteredStage = true s.loaded = true
for _, session := range s.server.sessions { for _, session := range s.server.sessions {
if s == session { if s == session || !session.loaded {
continue continue
} }
temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID} session.QueueSendMHF(&mhfpacket.MsgSysInsertUser{CharID: s.charID})
newNotif.WriteUint16(uint16(temp.Opcode())) session.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: s.charID, BinaryType: 1})
temp.Build(newNotif, s.clientContext) session.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: s.charID, BinaryType: 2})
for i := 0; i < 3; i++ { session.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: s.charID, BinaryType: 3})
temp = &mhfpacket.MsgSysNotifyUserBinary{ s.QueueSendMHF(&mhfpacket.MsgSysInsertUser{CharID: session.charID})
CharID: session.charID, s.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: session.charID, BinaryType: 1})
BinaryType: uint8(i + 1), s.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: session.charID, BinaryType: 2})
} s.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: session.charID, BinaryType: 3})
newNotif.WriteUint16(uint16(temp.Opcode()))
temp.Build(newNotif, s.clientContext)
}
} }
} }

View File

@@ -49,7 +49,6 @@ type Server struct {
acceptConns chan net.Conn acceptConns chan net.Conn
deleteConns chan net.Conn deleteConns chan net.Conn
sessions map[net.Conn]*Session sessions map[net.Conn]*Session
objectIDs map[*Session]uint16
listener net.Listener // Listener that is created when Server.Start is called. listener net.Listener // Listener that is created when Server.Start is called.
isShuttingDown bool isShuttingDown bool
@@ -155,7 +154,6 @@ func NewServer(config *Config) *Server {
acceptConns: make(chan net.Conn), acceptConns: make(chan net.Conn),
deleteConns: make(chan net.Conn), deleteConns: make(chan net.Conn),
sessions: make(map[net.Conn]*Session), sessions: make(map[net.Conn]*Session),
objectIDs: make(map[*Session]uint16),
stages: make(map[string]*Stage), stages: make(map[string]*Stage),
userBinaryParts: make(map[userBinaryPartID][]byte), userBinaryParts: make(map[userBinaryPartID][]byte),
semaphore: make(map[string]*Semaphore), semaphore: make(map[string]*Semaphore),
@@ -280,6 +278,20 @@ func (s *Server) manageSessions() {
} }
} }
func (s *Server) getObjectId() uint16 {
ids := make(map[uint16]struct{})
for _, sess := range s.sessions {
ids[sess.objectID] = struct{}{}
}
for i := uint16(1); i < 100; i++ {
if _, ok := ids[i]; !ok {
return i
}
}
s.logger.Warn("object ids overflowed", zap.Int("sessions", len(s.sessions)))
return 0
}
func (s *Server) invalidateSessions() { func (s *Server) invalidateSessions() {
for { for {
if s.isShuttingDown { if s.isShuttingDown {

View File

@@ -36,8 +36,10 @@ type Session struct {
clientContext *clientctx.ClientContext clientContext *clientctx.ClientContext
lastPacket time.Time lastPacket time.Time
objectIndex uint16 objectID uint16
userEnteredStage bool // If the user has entered a stage before objectIndex uint16
loaded bool
stage *Stage stage *Stage
reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet. reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet.
stagePass string // Temporary storage stagePass string // Temporary storage
@@ -83,12 +85,12 @@ func NewSession(server *Server, conn net.Conn) *Session {
sendPackets: make(chan packet, 20), sendPackets: make(chan packet, 20),
clientContext: &clientctx.ClientContext{}, // Unused clientContext: &clientctx.ClientContext{}, // Unused
lastPacket: time.Now(), lastPacket: time.Now(),
objectID: server.getObjectId(),
sessionStart: TimeAdjusted().Unix(), sessionStart: TimeAdjusted().Unix(),
stageMoveStack: stringstack.New(), stageMoveStack: stringstack.New(),
ackStart: make(map[uint32]time.Time), ackStart: make(map[uint32]time.Time),
semaphoreID: make([]uint16, 2), semaphoreID: make([]uint16, 2),
} }
s.SetObjectID()
return s return s
} }
@@ -292,30 +294,9 @@ func (s *Session) logMessage(opcode uint16, data []byte, sender string, recipien
} }
} }
func (s *Session) SetObjectID() { func (s *Session) getObjectId() uint32 {
for i := uint16(1); i < 127; i++ {
exists := false
for _, j := range s.server.objectIDs {
if i == j {
exists = true
break
}
}
if !exists {
s.server.objectIDs[s] = i
return
}
}
s.server.objectIDs[s] = 0
}
func (s *Session) NextObjectID() uint32 {
bf := byteframe.NewByteFrame()
bf.WriteUint16(s.server.objectIDs[s])
s.objectIndex++ s.objectIndex++
bf.WriteUint16(s.objectIndex) return uint32(s.objectID)<<16 | uint32(s.objectIndex)
bf.Seek(0, 0)
return bf.ReadUint32()
} }
func (s *Session) GetSemaphoreID() uint32 { func (s *Session) GetSemaphoreID() uint32 {