mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-13 23:44:52 +01:00
rework guild operations
This commit is contained in:
@@ -3,9 +3,9 @@ package mhfpacket
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"erupe-ce/network/clientctx"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/common/byteframe"
|
||||
"erupe-ce/network"
|
||||
"erupe-ce/network/clientctx"
|
||||
)
|
||||
|
||||
type OperateGuildAction uint8
|
||||
@@ -30,7 +30,7 @@ const (
|
||||
OPERATE_GUILD_CHANGE_PUGI_3 = 0x11
|
||||
// pugi something
|
||||
OPERATE_GUILD_DONATE_EVENT = 0x15
|
||||
// pugi something
|
||||
OPERATE_GUILD_EVENT_EXCHANGE = 0x16
|
||||
OPERATE_GUILD_CHANGE_DIVA_PUGI_1 = 0x19
|
||||
OPERATE_GUILD_CHANGE_DIVA_PUGI_2 = 0x1a
|
||||
OPERATE_GUILD_CHANGE_DIVA_PUGI_3 = 0x1b
|
||||
@@ -41,7 +41,8 @@ type MsgMhfOperateGuild struct {
|
||||
AckHandle uint32
|
||||
GuildID uint32
|
||||
Action OperateGuildAction
|
||||
UnkData []byte
|
||||
Data1 *byteframe.ByteFrame
|
||||
Data2 *byteframe.ByteFrame
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
@@ -54,8 +55,9 @@ func (m *MsgMhfOperateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.GuildID = bf.ReadUint32()
|
||||
m.Action = OperateGuildAction(bf.ReadUint8())
|
||||
m.UnkData = bf.DataFromCurrent()
|
||||
bf.Seek(int64(len(bf.Data()) - 2), 0)
|
||||
dataLen := uint(bf.ReadUint8())
|
||||
m.Data1 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(4))
|
||||
m.Data2 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(dataLen))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -634,11 +634,8 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
|
||||
bf.WriteUint32(uint32(response))
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
return
|
||||
case mhfpacket.OPERATE_GUILD_RESIGN:
|
||||
guildMembers, err := GetGuildMembers(s, guild.ID, false)
|
||||
success := false
|
||||
if err == nil {
|
||||
sort.Slice(guildMembers[:], func(i, j int) bool {
|
||||
return guildMembers[i].OrderIndex < guildMembers[j].OrderIndex
|
||||
@@ -651,29 +648,17 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
guildMembers[0].Save(s)
|
||||
guildMembers[i].Save(s)
|
||||
bf.WriteUint32(guildMembers[i].CharID)
|
||||
success = true
|
||||
break
|
||||
}
|
||||
}
|
||||
guild.Save(s)
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
if !success {
|
||||
bf.WriteUint32(0)
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
return
|
||||
case mhfpacket.OPERATE_GUILD_APPLY:
|
||||
err = guild.CreateApplication(s, s.charID, GuildApplicationTypeApplied, nil)
|
||||
|
||||
if err != nil {
|
||||
// All successful acks return 0x01, assuming 0x00 is failure
|
||||
bf.WriteUint32(0x00)
|
||||
} else {
|
||||
if err == nil {
|
||||
bf.WriteUint32(guild.LeaderCharID)
|
||||
}
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
return
|
||||
case mhfpacket.OPERATE_GUILD_LEAVE:
|
||||
var err error
|
||||
|
||||
@@ -698,10 +683,8 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
|
||||
bf.WriteUint32(uint32(response))
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
return
|
||||
case mhfpacket.OPERATE_GUILD_DONATE_RANK:
|
||||
handleDonateRP(s, pkt, bf, guild, false)
|
||||
bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, false))
|
||||
case mhfpacket.OPERATE_GUILD_SET_APPLICATION_DENY:
|
||||
s.server.db.Exec("UPDATE guilds SET recruiting=false WHERE id=$1", guild.ID)
|
||||
case mhfpacket.OPERATE_GUILD_SET_APPLICATION_ALLOW:
|
||||
@@ -711,46 +694,55 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
||||
case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE:
|
||||
handleAvoidLeadershipUpdate(s, pkt, false)
|
||||
case mhfpacket.OPERATE_GUILD_UPDATE_COMMENT:
|
||||
pbf := byteframe.NewByteFrameFromBytes(pkt.UnkData)
|
||||
if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() {
|
||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
_ = pbf.ReadUint8() // len
|
||||
_ = pbf.ReadUint32()
|
||||
guild.Comment = stringsupport.SJISToUTF8(pbf.ReadNullTerminatedBytes())
|
||||
guild.Comment = stringsupport.SJISToUTF8(pkt.Data2.ReadNullTerminatedBytes())
|
||||
guild.Save(s)
|
||||
case mhfpacket.OPERATE_GUILD_UPDATE_MOTTO:
|
||||
if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() {
|
||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||
return
|
||||
}
|
||||
guild.SubMotto = pkt.UnkData[3]
|
||||
guild.MainMotto = pkt.UnkData[4]
|
||||
_ = pkt.Data1.ReadUint16()
|
||||
guild.SubMotto = pkt.Data1.ReadUint8()
|
||||
guild.MainMotto = pkt.Data1.ReadUint8()
|
||||
guild.Save(s)
|
||||
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_1:
|
||||
handleRenamePugi(s, pkt.UnkData, guild, 1)
|
||||
handleRenamePugi(s, pkt.Data2, guild, 1)
|
||||
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_2:
|
||||
handleRenamePugi(s, pkt.UnkData, guild, 2)
|
||||
handleRenamePugi(s, pkt.Data2, guild, 2)
|
||||
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_3:
|
||||
handleRenamePugi(s, pkt.UnkData, guild, 3)
|
||||
handleRenamePugi(s, pkt.Data2, guild, 3)
|
||||
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_1:
|
||||
// TODO: decode guild poogie outfits
|
||||
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_2:
|
||||
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_3:
|
||||
case mhfpacket.OPERATE_GUILD_DONATE_EVENT:
|
||||
handleDonateRP(s, pkt, bf, guild, true)
|
||||
bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, true))
|
||||
case mhfpacket.OPERATE_GUILD_EVENT_EXCHANGE:
|
||||
rp := uint16(pkt.Data1.ReadUint32())
|
||||
saveData, _ := GetCharacterSaveData(s, s.charID)
|
||||
saveData.RP -= rp
|
||||
transaction, err := s.server.db.Begin()
|
||||
err = saveData.Save(s, transaction)
|
||||
if err != nil {
|
||||
transaction.Rollback()
|
||||
}
|
||||
bf.WriteUint32(uint32(saveData.RP))
|
||||
default:
|
||||
panic(fmt.Sprintf("unhandled operate guild action '%d'", pkt.Action))
|
||||
}
|
||||
|
||||
if len(bf.Data()) > 0 {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||
} else {
|
||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||
}
|
||||
}
|
||||
|
||||
func handleRenamePugi(s *Session, data []byte, guild *Guild, num int) {
|
||||
bf := byteframe.NewByteFrameFromBytes(data)
|
||||
_ = bf.ReadUint8() // len
|
||||
_ = bf.ReadUint32() // unk
|
||||
func handleRenamePugi(s *Session, bf *byteframe.ByteFrame, guild *Guild, num int) {
|
||||
name := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
||||
switch num {
|
||||
case 1:
|
||||
@@ -763,33 +755,30 @@ func handleRenamePugi(s *Session, data []byte, guild *Guild, num int) {
|
||||
guild.Save(s)
|
||||
}
|
||||
|
||||
func handleDonateRP(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, bf *byteframe.ByteFrame, guild *Guild, isEvent bool) error {
|
||||
rp := binary.BigEndian.Uint16(pkt.UnkData[3:5])
|
||||
func handleDonateRP(s *Session, amount uint16, guild *Guild, isEvent bool) []byte {
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint32(0)
|
||||
saveData, err := GetCharacterSaveData(s, s.charID)
|
||||
if err != nil {
|
||||
return err
|
||||
return bf.Data()
|
||||
}
|
||||
saveData.RP -= rp
|
||||
saveData.RP -= amount
|
||||
transaction, err := s.server.db.Begin()
|
||||
err = saveData.Save(s, transaction)
|
||||
if err != nil {
|
||||
transaction.Rollback()
|
||||
return err
|
||||
return bf.Data()
|
||||
} else {
|
||||
transaction.Commit()
|
||||
}
|
||||
updateSQL := "UPDATE guilds SET rank_rp = rank_rp + $1 WHERE id = $2"
|
||||
if isEvent {
|
||||
updateSQL = "UPDATE guilds SET event_rp = event_rp + $1 WHERE id = $2"
|
||||
}
|
||||
_, err = s.server.db.Exec(updateSQL, rp, guild.ID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to donate rank RP to guild", zap.Error(err), zap.Uint32("guildID", guild.ID))
|
||||
transaction.Rollback()
|
||||
return err
|
||||
} else {
|
||||
transaction.Commit()
|
||||
}
|
||||
s.server.db.Exec(updateSQL, amount, guild.ID)
|
||||
bf.Seek(0, 0)
|
||||
bf.WriteUint32(uint32(saveData.RP))
|
||||
return nil
|
||||
return bf.Data()
|
||||
}
|
||||
|
||||
func handleAvoidLeadershipUpdate(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, avoidLeadership bool) {
|
||||
@@ -1712,9 +1701,11 @@ func handleMsgMhfGetGuildWeeklyBonusMaster(s *Session, p mhfpacket.MHFPacket) {
|
||||
}
|
||||
func handleMsgMhfGetGuildWeeklyBonusActiveCount(s *Session, p mhfpacket.MHFPacket) {
|
||||
pkt := p.(*mhfpacket.MsgMhfGetGuildWeeklyBonusActiveCount)
|
||||
|
||||
// Values taken from brand new guild capture
|
||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 0x03))
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteUint8(0x3C) // Active count
|
||||
bf.WriteUint8(0x3C) // Current active count
|
||||
bf.WriteUint8(0x00) // New active count
|
||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||
}
|
||||
|
||||
func handleMsgMhfGuildHuntdata(s *Session, p mhfpacket.MHFPacket) {
|
||||
|
||||
Reference in New Issue
Block a user