Files
Erupe/server/channelserver/handlers_event.go

253 lines
7.2 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`, Time_Current_Midnight().Add(-24*time.Hour), Time_Current_Midnight())
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 = Time_Current_Midnight().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 = Time_Current_Midnight()
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(Time_Current_Adjusted().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, WeekCount uint8
Available bool
Expiration uint32
}
func handleMsgMhfGetKeepLoginBoostStatus(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfGetKeepLoginBoostStatus)
var loginBoostStatus []loginBoost
insert := false
boostState, err := s.server.db.Query("SELECT week_req, week_count, available, end_time FROM login_boost_state WHERE char_id=$1 ORDER BY week_req ASC", s.charID)
if err != nil {
panic(err)
}
for boostState.Next() {
var boost loginBoost
err = boostState.Scan(&boost.WeekReq, &boost.WeekCount, &boost.Available, &boost.Expiration)
if err != nil {
panic(err)
}
loginBoostStatus = append(loginBoostStatus, boost)
}
if len(loginBoostStatus) == 0 {
// create default Entries (should only been week 1 with )
insert = true
loginBoostStatus = []loginBoost{
{
WeekReq: 1, // weeks needed
WeekCount: 0, // weeks passed
Available: true, // available
Expiration: 0, //uint32(t.Add(120 * time.Minute).Unix()), // uncomment to enable permanently
},
{
WeekReq: 2,
WeekCount: 0,
Available: true,
Expiration: 0,
},
{
WeekReq: 3,
WeekCount: 0,
Available: true,
Expiration: 0,
},
{
WeekReq: 4,
WeekCount: 0,
Available: true,
Expiration: 0,
},
{
WeekReq: 5,
WeekCount: 0,
Available: true,
Expiration: 0,
},
}
}
resp := byteframe.NewByteFrame()
CurrentWeek := Time_Current_Week_uint8()
for d := range loginBoostStatus {
if CurrentWeek == 1 && loginBoostStatus[d].WeekCount <= 5 {
loginBoostStatus[d].WeekCount = 0
}
if loginBoostStatus[d].WeekReq == CurrentWeek || loginBoostStatus[d].WeekCount != 0 {
loginBoostStatus[d].WeekCount = CurrentWeek
}
if !loginBoostStatus[d].Available && loginBoostStatus[d].WeekCount >= loginBoostStatus[d].WeekReq && uint32(time.Now().In(time.FixedZone("UTC+1", 1*60*60)).Unix()) >= loginBoostStatus[d].Expiration {
loginBoostStatus[d].Expiration = 1
}
if !insert {
_, err := s.server.db.Exec(`UPDATE login_boost_state SET week_count=$1, end_time=$2 WHERE char_id=$3 AND week_req=$4`, loginBoostStatus[d].WeekCount, loginBoostStatus[d].Expiration, s.charID, loginBoostStatus[d].WeekReq)
if err != nil {
panic(err)
}
}
}
for _, v := range loginBoostStatus {
if insert {
_, err := s.server.db.Exec(`INSERT INTO login_boost_state (char_id, week_req, week_count, available, end_time) VALUES ($1,$2,$3,$4,$5)`, s.charID, v.WeekReq, v.WeekCount, v.Available, v.Expiration)
if err != nil {
panic(err)
}
}
resp.WriteUint8(v.WeekReq)
resp.WriteUint8(v.WeekCount)
resp.WriteBool(v.Available)
resp.WriteUint32(v.Expiration)
}
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
}
func handleMsgMhfUseKeepLoginBoost(s *Session, p mhfpacket.MHFPacket) {
// Directly interacts with MhfGetKeepLoginBoostStatus
// TODO: make these states persistent on a per character basis
pkt := p.(*mhfpacket.MsgMhfUseKeepLoginBoost)
var t = time.Now().In(time.FixedZone("UTC+1", 1*60*60))
resp := byteframe.NewByteFrame()
resp.WriteUint8(0)
// response is end timestamp based on input
switch pkt.BoostWeekUsed {
case 1:
t = t.Add(120 * time.Minute)
resp.WriteUint32(uint32(t.Unix()))
case 2:
t = t.Add(240 * time.Minute)
resp.WriteUint32(uint32(t.Unix()))
case 3:
t = t.Add(120 * time.Minute)
resp.WriteUint32(uint32(t.Unix()))
case 4:
t = t.Add(180 * time.Minute)
resp.WriteUint32(uint32(t.Unix()))
case 5:
t = t.Add(240 * time.Minute)
resp.WriteUint32(uint32(t.Unix()))
}
_, err := s.server.db.Exec(`UPDATE login_boost_state SET available='false', end_time=$1 WHERE char_id=$2 AND week_req=$3`, uint32(t.Unix()), s.charID, pkt.BoostWeekUsed)
if err != nil {
panic(err)
}
doAckBufSucceed(s, pkt.AckHandle, resp.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))
}