mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-17 09:24:50 +01:00
major rewrite
This commit is contained in:
@@ -10,10 +10,8 @@ import (
|
|||||||
|
|
||||||
// MsgMhfAcquireItem represents the MSG_MHF_ACQUIRE_ITEM
|
// MsgMhfAcquireItem represents the MSG_MHF_ACQUIRE_ITEM
|
||||||
type MsgMhfAcquireItem struct {
|
type MsgMhfAcquireItem struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
NullPadding uint16 //0 in Z2
|
RewardIDs []uint32
|
||||||
Length uint16
|
|
||||||
Unk1 []uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -24,10 +22,10 @@ func (m *MsgMhfAcquireItem) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfAcquireItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfAcquireItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.NullPadding = bf.ReadUint16()
|
bf.ReadUint16() // Zeroed
|
||||||
m.Length = bf.ReadUint16()
|
ids := bf.ReadUint16()
|
||||||
for i := 0; i < int(m.Length); i++ {
|
for i := uint16(0); i < ids; i++ {
|
||||||
m.Unk1 = append(m.Unk1, bf.ReadUint32())
|
m.RewardIDs = append(m.RewardIDs, bf.ReadUint32())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,18 +2,17 @@ package mhfpacket
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"erupe-ce/common/bfutil"
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/common/stringsupport"
|
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
"erupe-ce/network/clientctx"
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfApplyCampaign represents the MSG_MHF_APPLY_CAMPAIGN
|
// MsgMhfApplyCampaign represents the MSG_MHF_APPLY_CAMPAIGN
|
||||||
type MsgMhfApplyCampaign struct {
|
type MsgMhfApplyCampaign struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
CampaignID uint32
|
CampaignID uint32
|
||||||
NullPadding uint16 // set as 0 in z2
|
Code string
|
||||||
CodeString string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -25,9 +24,8 @@ func (m *MsgMhfApplyCampaign) Opcode() network.PacketID {
|
|||||||
func (m *MsgMhfApplyCampaign) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfApplyCampaign) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.CampaignID = bf.ReadUint32()
|
m.CampaignID = bf.ReadUint32()
|
||||||
m.NullPadding = bf.ReadUint16()
|
bf.ReadUint16() // Zeroed
|
||||||
m.CodeString = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
m.Code = string(bfutil.UpToNull(bf.ReadBytes(16)))
|
||||||
bf.ReadInt8()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,8 @@ import (
|
|||||||
|
|
||||||
// MsgMhfEnumerateItem represents the MSG_MHF_ENUMERATE_ITEM
|
// MsgMhfEnumerateItem represents the MSG_MHF_ENUMERATE_ITEM
|
||||||
type MsgMhfEnumerateItem struct {
|
type MsgMhfEnumerateItem struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
NullPadding uint16 // 0 in Z2
|
CampaignID uint32
|
||||||
Unk1 uint16 //0002
|
|
||||||
CampaignID uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -24,8 +22,8 @@ func (m *MsgMhfEnumerateItem) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfEnumerateItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfEnumerateItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.NullPadding = bf.ReadUint16()
|
bf.ReadUint16() // Zeroed
|
||||||
m.Unk1 = bf.ReadUint16()
|
bf.ReadUint16() // Always 2
|
||||||
m.CampaignID = bf.ReadUint32()
|
m.CampaignID = bf.ReadUint32()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,9 @@ import (
|
|||||||
// MsgMhfTransferItem represents the MSG_MHF_TRANSFER_ITEM
|
// MsgMhfTransferItem represents the MSG_MHF_TRANSFER_ITEM
|
||||||
type MsgMhfTransferItem struct {
|
type MsgMhfTransferItem struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
// looking at packets, these were static across sessions and did not actually
|
QuestID uint32
|
||||||
// correlate with any item IDs that would make sense to get after quests so
|
ItemType uint8
|
||||||
// I have no idea what this actually does
|
Quantity uint16
|
||||||
Unk0 uint32
|
|
||||||
Unk1 uint8
|
|
||||||
Unk2 uint16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -27,10 +24,10 @@ func (m *MsgMhfTransferItem) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfTransferItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfTransferItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint32()
|
m.QuestID = bf.ReadUint32()
|
||||||
m.Unk1 = bf.ReadUint8()
|
m.ItemType = bf.ReadUint8()
|
||||||
bf.ReadUint8() // Zeroed
|
bf.ReadUint8() // Zeroed
|
||||||
m.Unk2 = bf.ReadUint16()
|
m.Quantity = bf.ReadUint16()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,27 +8,23 @@ CREATE TABLE IF NOT EXISTS public.campaigns (
|
|||||||
max_sr INTEGER,
|
max_sr INTEGER,
|
||||||
min_gr INTEGER,
|
min_gr INTEGER,
|
||||||
max_gr INTEGER,
|
max_gr INTEGER,
|
||||||
recieve_type INTEGER,
|
reward_type INTEGER,
|
||||||
stamp_amount INTEGER,
|
stamps INTEGER,
|
||||||
hide INTEGER,
|
unk INTEGER,
|
||||||
background_id INTEGER,
|
background_id INTEGER,
|
||||||
hide_npc BOOLEAN,
|
|
||||||
start_time TIMESTAMP WITH TIME ZONE,
|
start_time TIMESTAMP WITH TIME ZONE,
|
||||||
end_time TIMESTAMP WITH TIME ZONE,
|
end_time TIMESTAMP WITH TIME ZONE,
|
||||||
period_ended BOOLEAN,
|
title TEXT,
|
||||||
string0 TEXT,
|
reward TEXT,
|
||||||
string1 TEXT,
|
|
||||||
string2 TEXT,
|
|
||||||
string3 TEXT,
|
|
||||||
link TEXT,
|
link TEXT,
|
||||||
code_prefix TEXT
|
code_prefix TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.campaign_categories (
|
CREATE TABLE IF NOT EXISTS public.campaign_categories (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
cat_type INTEGER,
|
type INTEGER,
|
||||||
title TEXT,
|
title TEXT,
|
||||||
description_text TEXT
|
description TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.campaign_category_links (
|
CREATE TABLE IF NOT EXISTS public.campaign_category_links (
|
||||||
@@ -37,14 +33,17 @@ CREATE TABLE IF NOT EXISTS public.campaign_category_links (
|
|||||||
category_id INTEGER
|
category_id INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.campaign_entries (
|
CREATE TABLE IF NOT EXISTS public.campaign_rewards (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
campaign_id INTEGER,
|
campaign_id INTEGER,
|
||||||
hide BOOLEAN,
|
|
||||||
item_type INTEGER,
|
item_type INTEGER,
|
||||||
item_amount INTEGER,
|
quantity INTEGER,
|
||||||
item_no INTEGER,
|
item_id INTEGER
|
||||||
deadline TIMESTAMP WITH TIME ZONE
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.campaign_rewards_claimed (
|
||||||
|
character_id INTEGER,
|
||||||
|
reward_id INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.campaign_state (
|
CREATE TABLE IF NOT EXISTS public.campaign_state (
|
||||||
@@ -54,4 +53,14 @@ CREATE TABLE IF NOT EXISTS public.campaign_state (
|
|||||||
code TEXT
|
code TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.campaign_codes (
|
||||||
|
code TEXT,
|
||||||
|
multi BOOLEAN
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.campaign_quest (
|
||||||
|
campaign_id INTEGER,
|
||||||
|
character_id INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
END;
|
END;
|
||||||
@@ -641,11 +641,6 @@ func handleMsgSysInfokyserver(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
|
|
||||||
func handleMsgMhfGetCaUniqueID(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfGetCaUniqueID(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgMhfTransferItem(s *Session, p mhfpacket.MHFPacket) {
|
|
||||||
pkt := p.(*mhfpacket.MsgMhfTransferItem)
|
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleMsgMhfEnumeratePrice(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumeratePrice(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumeratePrice)
|
pkt := p.(*mhfpacket.MsgMhfEnumeratePrice)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
ps "erupe-ce/common/pascalstring"
|
ps "erupe-ce/common/pascalstring"
|
||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
_config "erupe-ce/config"
|
_config "erupe-ce/config"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,42 +17,36 @@ type CampaignEvent struct {
|
|||||||
MaxSR int16 `db:"max_sr"`
|
MaxSR int16 `db:"max_sr"`
|
||||||
MinGR int16 `db:"min_gr"`
|
MinGR int16 `db:"min_gr"`
|
||||||
MaxGR int16 `db:"max_gr"`
|
MaxGR int16 `db:"max_gr"`
|
||||||
RecieveType uint16 `db:"recieve_type"` //1 Item/Weapon //2 Event Quest //3 Item/Weapon
|
RewardType uint16 `db:"reward_type"`
|
||||||
StampAmount uint8 `db:"stamp_amount"`
|
Stamps uint8 `db:"stamps"`
|
||||||
Hide uint8 `db:"hide"` //1 hides // 10 and 0 seem to be visible ?? is 10 overhang?
|
Unk uint8 `db:"unk"`
|
||||||
BackgroundID uint16 `db:"background_id"`
|
BackgroundID uint16 `db:"background_id"`
|
||||||
HideNPC uint16 `db:"hide_npc"` //TODO: giving this the value 1 or above made the NPC glitch / hide
|
|
||||||
Start time.Time `db:"start_time"`
|
Start time.Time `db:"start_time"`
|
||||||
End time.Time `db:"end_time"`
|
End time.Time `db:"end_time"`
|
||||||
PeriodEnded bool `db:"period_ended"`
|
Title string `db:"title"`
|
||||||
String0 string `db:"string0"`
|
Reward string `db:"reward"`
|
||||||
String1 string `db:"string1"`
|
|
||||||
String2 string `db:"string2"`
|
|
||||||
String3 string `db:"string3"`
|
|
||||||
Link string `db:"link"`
|
Link string `db:"link"`
|
||||||
Prefix string `db:"code_prefix"`
|
Prefix string `db:"code_prefix"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CampaignCategory struct {
|
type CampaignCategory struct {
|
||||||
ID uint16 `db:"id"`
|
ID uint16 `db:"id"`
|
||||||
Type uint8 `db:"cat_type"`
|
Type uint8 `db:"type"`
|
||||||
Title string `db:"title"`
|
Title string `db:"title"`
|
||||||
Description string `db:"description_text"`
|
Description string `db:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CampaignLink struct {
|
type CampaignLink struct {
|
||||||
CategoryID uint16 `db:"category_id"`
|
CategoryID uint16 `db:"category_id"`
|
||||||
CampaignID uint32 `db:"campaign_id"`
|
CampaignID uint32 `db:"campaign_id"`
|
||||||
}
|
}
|
||||||
type CampaignEntry struct {
|
|
||||||
|
type CampaignReward struct {
|
||||||
ID uint32 `db:"id"`
|
ID uint32 `db:"id"`
|
||||||
Hide bool `db:"hide"`
|
ItemType uint16 `db:"item_type"`
|
||||||
ItemType uint8 `db:"item_type"`
|
Quantity uint16 `db:"quantity"`
|
||||||
Amount uint16 `db:"item_amount"`
|
ItemID uint16 `db:"item_id"`
|
||||||
ItemNo uint16 `db:"item_no"`
|
Deadline time.Time `db:"deadline"`
|
||||||
Unk4 uint16 `db:"unk1"`
|
|
||||||
Unk5 uint32 `db:"unk2"`
|
|
||||||
DeadLine time.Time `db:"deadline"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
||||||
@@ -64,15 +55,14 @@ func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
var events []CampaignEvent
|
var events []CampaignEvent
|
||||||
var categories []CampaignCategory
|
var categories []CampaignCategory
|
||||||
|
|
||||||
var campaignLinks []CampaignLink
|
var campaignLinks []CampaignLink
|
||||||
|
|
||||||
err := s.server.db.Select(&events, "SELECT id,min_hr,max_hr,min_sr,max_sr,min_gr,max_gr,recieve_type,stamp_amount,hide,background_id,hide_npc,start_time,end_time,period_ended,string0,string1,string2,string3,link,code_prefix FROM campaigns")
|
err := s.server.db.Select(&events, "SELECT id,min_hr,max_hr,min_sr,max_sr,min_gr,max_gr,reward_type,stamps,unk,background_id,start_time,end_time,title,reward,link,code_prefix FROM campaigns")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = s.server.db.Select(&categories, "SELECT id, cat_type, title, description_text FROM campaign_categories")
|
err = s.server.db.Select(&categories, "SELECT id, type, title, description FROM campaign_categories")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
@@ -90,7 +80,7 @@ func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
bf.WriteUint32(event.ID)
|
bf.WriteUint32(event.ID)
|
||||||
bf.WriteUint32(0) // always 0 in reference
|
bf.WriteUint32(0)
|
||||||
bf.WriteInt16(event.MinHR)
|
bf.WriteInt16(event.MinHR)
|
||||||
bf.WriteInt16(event.MaxHR)
|
bf.WriteInt16(event.MaxHR)
|
||||||
bf.WriteInt16(event.MinSR)
|
bf.WriteInt16(event.MinSR)
|
||||||
@@ -99,20 +89,23 @@ func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
bf.WriteInt16(event.MinGR)
|
bf.WriteInt16(event.MinGR)
|
||||||
bf.WriteInt16(event.MaxGR)
|
bf.WriteInt16(event.MaxGR)
|
||||||
}
|
}
|
||||||
bf.WriteUint16(event.RecieveType)
|
bf.WriteUint16(event.RewardType)
|
||||||
bf.WriteUint8(event.StampAmount)
|
bf.WriteUint8(event.Stamps)
|
||||||
bf.WriteUint8(event.Hide)
|
bf.WriteUint8(event.Unk) // Related to stamp count
|
||||||
bf.WriteUint16(event.BackgroundID)
|
bf.WriteUint16(event.BackgroundID)
|
||||||
bf.WriteUint16(event.HideNPC)
|
bf.WriteUint16(0)
|
||||||
bf.WriteUint32(uint32(event.Start.Unix()))
|
bf.WriteUint32(uint32(event.Start.Unix()))
|
||||||
bf.WriteUint32(uint32(event.End.Unix()))
|
bf.WriteUint32(uint32(event.End.Unix()))
|
||||||
bf.WriteBool(event.PeriodEnded)
|
if event.End.After(time.Now()) {
|
||||||
ps.Uint8(bf, event.String0, true)
|
bf.WriteBool(true)
|
||||||
ps.Uint8(bf, event.String1, true)
|
} else {
|
||||||
ps.Uint8(bf, event.String2, true)
|
bf.WriteBool(false)
|
||||||
ps.Uint8(bf, event.String3, true)
|
}
|
||||||
|
ps.Uint8(bf, event.Title, true)
|
||||||
|
ps.Uint8(bf, event.Reward, true)
|
||||||
|
ps.Uint8(bf, "", false)
|
||||||
|
ps.Uint8(bf, "", false)
|
||||||
ps.Uint8(bf, event.Link, true)
|
ps.Uint8(bf, event.Link, true)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(events) > 255 {
|
if len(events) > 255 {
|
||||||
@@ -123,7 +116,7 @@ func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
bf.WriteUint32(event.ID)
|
bf.WriteUint32(event.ID)
|
||||||
bf.WriteUint8(1) //StampAmount * This Amount = Stamps Shown
|
bf.WriteUint8(1) // Related to stamp count
|
||||||
bf.WriteBytes([]byte(event.Prefix))
|
bf.WriteBytes([]byte(event.Prefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,29 +153,30 @@ func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
func handleMsgMhfStateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfStateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfStateCampaign)
|
pkt := p.(*mhfpacket.MsgMhfStateCampaign)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
var stamps, amount int
|
var required int
|
||||||
var period_ended bool
|
var deadline time.Time
|
||||||
err := s.server.db.QueryRow(`SELECT COUNT(*) FROM campaign_state WHERE campaign_id = $1 AND character_id = $2`, pkt.CampaignID, s.charID).Scan(&stamps)
|
var stamps []uint32
|
||||||
|
|
||||||
|
err := s.server.db.Select(&stamps, "SELECT id FROM campaign_state WHERE campaign_id = $1 AND character_id = $2", pkt.CampaignID, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = s.server.db.QueryRow(`SELECT stamp_amount,period_ended FROM campaigns WHERE id = $1`, pkt.CampaignID).Scan(&amount, &period_ended)
|
err = s.server.db.QueryRow(`SELECT stamps, end_time FROM campaigns WHERE id = $1`, pkt.CampaignID).Scan(&required, &deadline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var unkArray = []uint32{1, 2, 3, 4, 5, 6} //Not figured out what this does yet....?
|
bf.WriteUint16(uint16(len(stamps) + 1))
|
||||||
bf.WriteUint16(uint16(stamps + 1)) // game client seems to -1
|
|
||||||
if amount == 1 {
|
if len(stamps) < required {
|
||||||
bf.WriteUint16(1)
|
bf.WriteUint16(0)
|
||||||
} else if stamps >= amount || period_ended {
|
} else if len(stamps) >= required || deadline.After(time.Now()) {
|
||||||
bf.WriteUint16(2)
|
bf.WriteUint16(2)
|
||||||
} else if amount > 1 {
|
|
||||||
bf.WriteUint16(3)
|
|
||||||
}
|
}
|
||||||
for _, value := range unkArray {
|
|
||||||
bf.WriteUint32(value)
|
for _, v := range stamps {
|
||||||
|
bf.WriteUint32(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
@@ -191,67 +185,89 @@ func handleMsgMhfStateCampaign(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
func handleMsgMhfApplyCampaign(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfApplyCampaign(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfApplyCampaign)
|
pkt := p.(*mhfpacket.MsgMhfApplyCampaign)
|
||||||
|
|
||||||
var code string
|
// Check if the code exists and check if it's a multi-code
|
||||||
// Query to check if the event code exists in the database
|
var multi bool
|
||||||
err := s.server.db.QueryRow("SELECT code FROM public.campaign_state WHERE code = $1", pkt.CodeString).Scan(&code)
|
err := s.server.db.QueryRow(`SELECT multi FROM public.campaign_codes WHERE code = $1 GROUP BY multi`, pkt.Code).Scan(&multi)
|
||||||
|
if err != nil {
|
||||||
switch {
|
|
||||||
case err == sql.ErrNoRows:
|
|
||||||
fmt.Println("Event code does not exist in the database.")
|
|
||||||
s.server.db.Exec(`INSERT INTO public.campaign_state ( code, campaign_id ,character_id) VALUES ($1,$2,$3)`, pkt.CodeString, pkt.CampaignID, s.charID)
|
|
||||||
|
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
|
||||||
case err != nil:
|
|
||||||
log.Fatal(err)
|
|
||||||
default:
|
|
||||||
fmt.Printf("Event code '%s' exists in the database.\n", code)
|
|
||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the code is already used
|
||||||
|
var exists bool
|
||||||
|
if multi {
|
||||||
|
s.server.db.QueryRow(`SELECT COUNT(*) FROM public.campaign_state WHERE code = $1 AND character_id = $2`, pkt.Code, s.charID).Scan(&exists)
|
||||||
|
} else {
|
||||||
|
s.server.db.QueryRow(`SELECT COUNT(*) FROM public.campaign_state WHERE code = $1`, pkt.Code).Scan(&exists)
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.server.db.Exec(`INSERT INTO public.campaign_state (code, campaign_id, character_id) VALUES ($1, $2, $3)`, pkt.Code, pkt.CampaignID, s.charID)
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfEnumerateItem(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateItem(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateItem)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateItem)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
var stamps, amount uint16
|
var stamps, required, rewardType uint16
|
||||||
|
var deadline time.Time
|
||||||
err := s.server.db.QueryRow(`SELECT COUNT(*) FROM campaign_state WHERE campaign_id = $1 AND character_id = $2`, pkt.CampaignID, s.charID).Scan(&stamps)
|
err := s.server.db.QueryRow(`SELECT COUNT(*) FROM campaign_state WHERE campaign_id = $1 AND character_id = $2`, pkt.CampaignID, s.charID).Scan(&stamps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = s.server.db.QueryRow(`SELECT stamp_amount FROM campaigns WHERE id = $1`, pkt.CampaignID).Scan(&amount)
|
err = s.server.db.QueryRow(`SELECT stamps, reward_type, end_time FROM campaigns WHERE id = $1`, pkt.CampaignID).Scan(&required, &rewardType, &deadline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if stamps >= amount {
|
if stamps >= required {
|
||||||
|
var items []CampaignReward
|
||||||
var items []CampaignEntry
|
if rewardType == 2 {
|
||||||
err = s.server.db.Select(&items, `SELECT id,hide,item_type,item_amount,item_no,unk1,unk2,deadline FROM campaign_entries WHERE campaign_id = $1`, pkt.CampaignID)
|
var exists int
|
||||||
|
s.server.db.QueryRow(`SELECT COUNT(*) FROM campaign_quest WHERE campaign_id = $1 AND character_id = $2`, pkt.CampaignID, s.charID).Scan(&exists)
|
||||||
|
if exists > 0 {
|
||||||
|
err = s.server.db.Select(&items, `
|
||||||
|
SELECT id, item_type, quantity, item_id, TO_TIMESTAMP(0) AS deadline FROM campaign_rewards
|
||||||
|
WHERE campaign_id = $1 AND item_type != 9
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM campaign_rewards_claimed WHERE reward_id = campaign_rewards.id AND character_id = $2)
|
||||||
|
`, pkt.CampaignID, s.charID)
|
||||||
|
} else {
|
||||||
|
err = s.server.db.Select(&items, `
|
||||||
|
SELECT cr.id, cr.item_type, cr.quantity, cr.item_id, COALESCE(c.end_time, TO_TIMESTAMP(0)) AS deadline FROM campaign_rewards cr
|
||||||
|
JOIN campaigns c ON cr.campaign_id = c.id
|
||||||
|
WHERE campaign_id = $1 AND item_type = 9`, pkt.CampaignID)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = s.server.db.Select(&items, `
|
||||||
|
SELECT id, item_type, quantity, item_id, TO_TIMESTAMP(0) AS deadline FROM campaign_rewards
|
||||||
|
WHERE campaign_id = $1
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM campaign_rewards_claimed WHERE reward_id = campaign_rewards.id AND character_id = $2)
|
||||||
|
`, pkt.CampaignID, s.charID)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bf.WriteUint16(uint16(len(items)))
|
bf.WriteUint16(uint16(len(items)))
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
bf.WriteUint32(item.ID)
|
bf.WriteUint32(item.ID)
|
||||||
bf.WriteBool(item.Hide)
|
bf.WriteUint16(item.ItemType)
|
||||||
bf.WriteUint8(item.ItemType)
|
bf.WriteUint16(item.Quantity)
|
||||||
bf.WriteUint16(item.Amount)
|
bf.WriteUint16(item.ItemID) //HACK:placed quest id in this field to fit with Item No pattern. however it could be another field... possibly the other unks.
|
||||||
bf.WriteUint16(item.ItemNo) //HACK:placed quest id in this field to fit with Item No pattern. however it could be another field... possibly the other unks.
|
bf.WriteUint16(0) //Unk4, gets cast to uint8
|
||||||
bf.WriteUint16(0) //Unk4
|
|
||||||
bf.WriteUint32(0) //Unk5
|
bf.WriteUint32(0) //Unk5
|
||||||
bf.WriteUint32(uint32(item.DeadLine.Unix()))
|
bf.WriteUint32(uint32(deadline.Unix()))
|
||||||
}
|
}
|
||||||
if len(items) == 0 {
|
if len(items) == 0 {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
@@ -260,6 +276,24 @@ func handleMsgMhfEnumerateItem(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfAcquireItem(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfAcquireItem(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfAcquireItem)
|
pkt := p.(*mhfpacket.MsgMhfAcquireItem)
|
||||||
|
for _, id := range pkt.RewardIDs {
|
||||||
|
s.server.db.Exec(`INSERT INTO campaign_rewards_claimed (reward_id, character_id) VALUES ($1, $2)`, id, s.charID)
|
||||||
|
}
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfTransferItem(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfTransferItem)
|
||||||
|
if pkt.ItemType == 9 {
|
||||||
|
var campaignID uint32
|
||||||
|
err := s.server.db.QueryRow(`
|
||||||
|
SELECT ce.campaign_id FROM campaign_rewards ce
|
||||||
|
JOIN event_quests eq ON ce.item_id = eq.quest_id
|
||||||
|
WHERE eq.id = $1
|
||||||
|
`, pkt.QuestID, s.charID).Scan(&campaignID)
|
||||||
|
if err == nil {
|
||||||
|
s.server.db.Exec(`INSERT INTO campaign_quest (campaign_id, character_id) VALUES ($1, $2)`, campaignID, s.charID)
|
||||||
|
}
|
||||||
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -276,33 +276,27 @@ func makeEventQuest(s *Session, rows *sql.Rows) ([]byte, error) {
|
|||||||
bf.WriteUint8(questType)
|
bf.WriteUint8(questType)
|
||||||
if questType == 9 {
|
if questType == 9 {
|
||||||
var stamps int
|
var stamps int
|
||||||
var amount int = 1
|
var amount = 1
|
||||||
var deadline time.Time
|
var deadline time.Time
|
||||||
err := s.server.db.QueryRow(`SELECT COUNT(*) FROM campaign_state WHERE campaign_id = (
|
err := s.server.db.QueryRow(`SELECT COUNT(*) FROM campaign_state WHERE campaign_id = (
|
||||||
SELECT campaign_id
|
SELECT campaign_id
|
||||||
FROM campaign_entries
|
FROM campaign_rewards
|
||||||
WHERE item_type = 9
|
WHERE item_type = 9
|
||||||
AND item_no = $1
|
AND item_id = $1
|
||||||
) AND character_id = $2`, questId, s.charID).Scan(&stamps)
|
) AND character_id = $2`, questId, s.charID).Scan(&stamps)
|
||||||
err2 := s.server.db.QueryRow(`SELECT stamp_amount, (
|
err2 := s.server.db.QueryRow(`SELECT stamps, end_time
|
||||||
SELECT deadline
|
|
||||||
FROM campaign_entries
|
|
||||||
WHERE item_type = 9
|
|
||||||
AND campaign_id = campaigns.id
|
|
||||||
) AS deadline
|
|
||||||
FROM campaigns
|
FROM campaigns
|
||||||
WHERE id = (
|
WHERE id = (
|
||||||
SELECT campaign_id
|
SELECT campaign_id
|
||||||
FROM campaign_entries
|
FROM campaign_rewards
|
||||||
WHERE item_type = 9
|
WHERE item_type = 9
|
||||||
AND item_no = $1
|
AND item_id = $1
|
||||||
)`, questId).Scan(&amount, &deadline)
|
)`, questId).Scan(&amount, &deadline)
|
||||||
// Check if there are enough stamps to activate the quest, the deadline hasn't passed, and there are no errors
|
// Check if there are enough stamps to activate the quest, the deadline hasn't passed, and there are no errors
|
||||||
if stamps >= amount && deadline.After(time.Now()) && err == nil && err2 == nil {
|
if stamps >= amount && deadline.After(time.Now()) && err == nil && err2 == nil {
|
||||||
bf.WriteBool(true)
|
bf.WriteBool(true)
|
||||||
} else {
|
} else {
|
||||||
bf.WriteBool(false)
|
bf.WriteBool(false)
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bf.WriteBool(true)
|
bf.WriteBool(true)
|
||||||
|
|||||||
Reference in New Issue
Block a user