mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-13 15:34:38 +01:00
221 lines
6.1 KiB
Go
221 lines
6.1 KiB
Go
package channelserver
|
|
|
|
import (
|
|
"math"
|
|
"math/rand"
|
|
"time"
|
|
|
|
"erupe-ce/common/byteframe"
|
|
"erupe-ce/network/mhfpacket"
|
|
)
|
|
|
|
func handleMsgMhfRegisterEvent(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfRegisterEvent)
|
|
bf := byteframe.NewByteFrame()
|
|
bf.WriteUint8(pkt.Unk2)
|
|
bf.WriteUint8(pkt.Unk4)
|
|
bf.WriteUint16(0x1142)
|
|
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
|
}
|
|
|
|
func handleMsgMhfReleaseEvent(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfReleaseEvent)
|
|
|
|
// Do this ack manually because it uses a non-(0|1) error code
|
|
/*
|
|
_ACK_SUCCESS = 0
|
|
_ACK_ERROR = 1
|
|
|
|
_ACK_EINPROGRESS = 16
|
|
_ACK_ENOENT = 17
|
|
_ACK_ENOSPC = 18
|
|
_ACK_ETIMEOUT = 19
|
|
|
|
_ACK_EINVALID = 64
|
|
_ACK_EFAILED = 65
|
|
_ACK_ENOMEM = 66
|
|
_ACK_ENOTEXIT = 67
|
|
_ACK_ENOTREADY = 68
|
|
_ACK_EALREADY = 69
|
|
_ACK_DISABLE_WORK = 71
|
|
*/
|
|
s.QueueSendMHF(&mhfpacket.MsgSysAck{
|
|
AckHandle: pkt.AckHandle,
|
|
IsBufferResponse: false,
|
|
ErrorCode: 0x41,
|
|
AckData: []byte{0x00, 0x00, 0x00, 0x00},
|
|
})
|
|
}
|
|
|
|
func handleMsgMhfEnumerateEvent(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfEnumerateEvent)
|
|
stubEnumerateNoResults(s, pkt.AckHandle)
|
|
}
|
|
|
|
type activeFeature struct {
|
|
StartTime time.Time `db:"start_time"`
|
|
ActiveFeatures uint32 `db:"featured"`
|
|
}
|
|
|
|
func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfGetWeeklySchedule)
|
|
|
|
var features []activeFeature
|
|
rows, _ := s.server.db.Queryx(`SELECT start_time, featured FROM feature_weapon WHERE start_time=$1 OR start_time=$2`, TimeMidnight().Add(-24*time.Hour), TimeMidnight())
|
|
for rows.Next() {
|
|
var feature activeFeature
|
|
rows.StructScan(&feature)
|
|
features = append(features, feature)
|
|
}
|
|
|
|
if len(features) < 2 {
|
|
if len(features) == 0 {
|
|
feature := generateFeatureWeapons(s.server.erupeConfig.FeaturedWeapons)
|
|
feature.StartTime = TimeMidnight().Add(-24 * time.Hour)
|
|
features = append(features, feature)
|
|
s.server.db.Exec(`INSERT INTO feature_weapon VALUES ($1, $2)`, feature.StartTime, feature.ActiveFeatures)
|
|
}
|
|
feature := generateFeatureWeapons(s.server.erupeConfig.FeaturedWeapons)
|
|
feature.StartTime = TimeMidnight()
|
|
features = append(features, feature)
|
|
s.server.db.Exec(`INSERT INTO feature_weapon VALUES ($1, $2)`, feature.StartTime, feature.ActiveFeatures)
|
|
}
|
|
|
|
bf := byteframe.NewByteFrame()
|
|
bf.WriteUint8(2)
|
|
bf.WriteUint32(uint32(TimeAdjusted().Add(-5 * time.Minute).Unix()))
|
|
for _, feature := range features {
|
|
bf.WriteUint32(uint32(feature.StartTime.Unix()))
|
|
bf.WriteUint32(feature.ActiveFeatures)
|
|
bf.WriteUint16(0)
|
|
}
|
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
|
}
|
|
|
|
func generateFeatureWeapons(count int) activeFeature {
|
|
if count > 14 {
|
|
count = 14
|
|
}
|
|
nums := make([]int, 0)
|
|
var result int
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
for len(nums) < count {
|
|
num := r.Intn(14)
|
|
exist := false
|
|
for _, v := range nums {
|
|
if v == num {
|
|
exist = true
|
|
break
|
|
}
|
|
}
|
|
if !exist {
|
|
nums = append(nums, num)
|
|
}
|
|
}
|
|
for _, num := range nums {
|
|
result += int(math.Pow(2, float64(num)))
|
|
}
|
|
return activeFeature{ActiveFeatures: uint32(result)}
|
|
}
|
|
|
|
type loginBoost struct {
|
|
WeekReq uint8 `db:"week_req"`
|
|
WeekCount uint8
|
|
Active bool
|
|
Expiration time.Time `db:"expiration"`
|
|
Reset time.Time `db:"reset"`
|
|
}
|
|
|
|
func handleMsgMhfGetKeepLoginBoostStatus(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfGetKeepLoginBoostStatus)
|
|
|
|
bf := byteframe.NewByteFrame()
|
|
|
|
var loginBoosts []loginBoost
|
|
rows, err := s.server.db.Queryx("SELECT week_req, expiration, reset FROM login_boost WHERE char_id=$1 ORDER BY week_req", s.charID)
|
|
if err != nil {
|
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 35))
|
|
return
|
|
}
|
|
for rows.Next() {
|
|
var temp loginBoost
|
|
rows.StructScan(&temp)
|
|
loginBoosts = append(loginBoosts, temp)
|
|
}
|
|
if len(loginBoosts) == 0 {
|
|
temp := TimeWeekStart()
|
|
loginBoosts = []loginBoost{
|
|
{WeekReq: 1, Expiration: temp},
|
|
{WeekReq: 2, Expiration: temp},
|
|
{WeekReq: 3, Expiration: temp},
|
|
{WeekReq: 4, Expiration: temp},
|
|
{WeekReq: 5, Expiration: temp},
|
|
}
|
|
for _, boost := range loginBoosts {
|
|
s.server.db.Exec(`INSERT INTO login_boost VALUES ($1, $2, $3, $4)`, s.charID, boost.WeekReq, boost.Expiration, time.Time{})
|
|
}
|
|
}
|
|
|
|
for _, boost := range loginBoosts {
|
|
// Reset if next week
|
|
if !boost.Reset.IsZero() && boost.Reset.Before(TimeAdjusted()) {
|
|
boost.Expiration = TimeWeekStart()
|
|
boost.Reset = time.Time{}
|
|
s.server.db.Exec(`UPDATE login_boost SET expiration=$1, reset=$2 WHERE char_id=$3 AND week_req=$4`, boost.Expiration, boost.Reset, s.charID, boost.WeekReq)
|
|
}
|
|
|
|
boost.WeekCount = uint8((TimeAdjusted().Unix()-boost.Expiration.Unix())/604800 + 1)
|
|
|
|
if boost.WeekCount >= boost.WeekReq {
|
|
boost.Active = true
|
|
boost.WeekCount = boost.WeekReq
|
|
}
|
|
|
|
// Show reset timer on expired boosts
|
|
if boost.Reset.After(TimeAdjusted()) {
|
|
boost.Active = true
|
|
boost.WeekCount = 0
|
|
}
|
|
|
|
bf.WriteUint8(boost.WeekReq)
|
|
bf.WriteBool(boost.Active)
|
|
bf.WriteUint8(boost.WeekCount)
|
|
if !boost.Reset.IsZero() {
|
|
bf.WriteUint32(uint32(boost.Expiration.Unix()))
|
|
} else {
|
|
bf.WriteUint32(0)
|
|
}
|
|
}
|
|
|
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
|
}
|
|
|
|
func handleMsgMhfUseKeepLoginBoost(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfUseKeepLoginBoost)
|
|
var expiration time.Time
|
|
bf := byteframe.NewByteFrame()
|
|
bf.WriteUint8(0)
|
|
switch pkt.BoostWeekUsed {
|
|
case 1:
|
|
fallthrough
|
|
case 3:
|
|
expiration = TimeAdjusted().Add(120 * time.Minute)
|
|
case 4:
|
|
expiration = TimeAdjusted().Add(180 * time.Minute)
|
|
case 2:
|
|
fallthrough
|
|
case 5:
|
|
expiration = TimeAdjusted().Add(240 * time.Minute)
|
|
}
|
|
bf.WriteUint32(uint32(expiration.Unix()))
|
|
s.server.db.Exec(`UPDATE login_boost SET expiration=$1, reset=$2 WHERE char_id=$3 AND week_req=$4`, expiration, TimeWeekNext(), s.charID, pkt.BoostWeekUsed)
|
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
|
}
|
|
|
|
func handleMsgMhfGetRestrictionEvent(s *Session, p mhfpacket.MHFPacket) {}
|
|
|
|
func handleMsgMhfSetRestrictionEvent(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfSetRestrictionEvent)
|
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
|
}
|