diff --git a/common/stringsupport/string_convert.go b/common/stringsupport/string_convert.go index 53ed2ec69..452c85321 100644 --- a/common/stringsupport/string_convert.go +++ b/common/stringsupport/string_convert.go @@ -2,6 +2,7 @@ package stringsupport import ( "bytes" + "fmt" "io" "strconv" "strings" @@ -96,3 +97,23 @@ func CSVElems(csv string) []int { } return r } + +func CSVGetIndex(csv string, i int) int { + s := CSVElems(csv) + if i < len(s) { + return s[i] + } + return 0 +} + +func CSVSetIndex(csv string, i int, v int) string { + s := CSVElems(csv) + if i < len(s) { + s[i] = v + } + var r []string + for j := 0; j < len(s); j++ { + r = append(r, fmt.Sprintf(`%d`, s[j])) + } + return strings.Join(r, ",") +} diff --git a/config.json b/config.json index f76b172f4..1e09daddd 100644 --- a/config.json +++ b/config.json @@ -11,6 +11,7 @@ "PatchServerFile": "", "ScreenshotAPIURL": "", "DeleteOnSaveCorruption": false, + "ClientMode": "ZZ", "DevMode": true, "DevModeOptions": { "AutoCreateAccount": true, @@ -27,6 +28,8 @@ "DisableTokenCheck": false, "QuestDebugTools": false, "EarthStatusOverride": 0, + "EarthIDOverride": 0, + "EarthMonsterOverride": 0, "SaveDumps": { "Enabled": true, "OutputDir": "savedata" @@ -43,7 +46,18 @@ "BonusQuestAllowance": 3, "DailyQuestAllowance": 1, "MezfesSoloTickets": 10, - "MezfesGroupTickets": 4 + "MezfesGroupTickets": 4, + "GUrgentRate": 10, + "GCPMultiplier": 1.00, + "GRPMultiplier": 1.00, + "GSRPMultiplier": 1.00, + "GZennyMultiplier": 1.00, + "MaterialMultiplier": 1.00, + "ExtraCarves": 0, + "DisableHunterNavi": false, + "EnableHiganjimaEvent": false, + "EnableNierEvent": false, + "DisableRoad": false }, "Discord": { "Enabled": false, diff --git a/config/config.go b/config/config.go index 6ca3b431e..9e96031a8 100644 --- a/config/config.go +++ b/config/config.go @@ -1,15 +1,28 @@ -package config +package _config import ( "fmt" "log" "net" "os" + "strings" "time" "github.com/spf13/viper" ) +type Mode string + +const ( + ZZ Mode = "ZZ" + Z2 Mode = "Z2" + Z1 Mode = "Z1" +) + +func (m Mode) String() string { + return string(m) +} + // Config holds the global server-wide config. type Config struct { Host string `mapstructure:"Host"` @@ -22,6 +35,7 @@ type Config struct { PatchServerFile string // File patch server override ScreenshotAPIURL string // Destination for screenshots uploaded to BBS DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion + ClientMode Mode DevMode bool DevModeOptions DevModeOptions @@ -38,21 +52,23 @@ type Config struct { // DevModeOptions holds various debug/temporary options for use while developing Erupe. type DevModeOptions struct { - AutoCreateAccount bool // Automatically create accounts if they don't exist - CleanDB bool // Automatically wipes the DB on server reset. - MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds. - LogInboundMessages bool // Log all messages sent to the server - LogOutboundMessages bool // Log all messages sent to the clients - MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled - DivaEvent int // Diva Defense event status - FestaEvent int // Hunter's Festa event status - TournamentEvent int // VS Tournament event status - MezFesEvent bool // MezFes status - MezFesAlt bool // Swaps out Volpakkun for Tokotoko - DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!) - QuestDebugTools bool // Enable various quest debug logs - EarthStatusOverride int32 - SaveDumps SaveDumpOptions + AutoCreateAccount bool // Automatically create accounts if they don't exist + CleanDB bool // Automatically wipes the DB on server reset. + MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds. + LogInboundMessages bool // Log all messages sent to the server + LogOutboundMessages bool // Log all messages sent to the clients + MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled + DivaEvent int // Diva Defense event status + FestaEvent int // Hunter's Festa event status + TournamentEvent int // VS Tournament event status + MezFesEvent bool // MezFes status + MezFesAlt bool // Swaps out Volpakkun for Tokotoko + DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!) + QuestDebugTools bool // Enable various quest debug logs + EarthStatusOverride int32 + EarthIDOverride int32 + EarthMonsterOverride int32 + SaveDumps SaveDumpOptions } type SaveDumpOptions struct { @@ -62,17 +78,28 @@ type SaveDumpOptions struct { // GameplayOptions has various gameplay modifiers type GameplayOptions struct { - FeaturedWeapons int // Number of Active Feature weapons to generate daily - MaximumNP int // Maximum number of NP held by a player - MaximumRP uint16 // Maximum number of RP held by a player - DisableLoginBoost bool // Disables the Login Boost system - DisableBoostTime bool // Disables the daily NetCafe Boost Time - BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for - GuildMealDuration int // The number of minutes a Guild Meal can be activated for after cooking - BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily - DailyQuestAllowance uint32 // Number of Daily Quests to allow daily - MezfesSoloTickets uint32 // Number of solo tickets given weekly - MezfesGroupTickets uint32 // Number of group tickets given weekly + FeaturedWeapons int // Number of Active Feature weapons to generate daily + MaximumNP int // Maximum number of NP held by a player + MaximumRP uint16 // Maximum number of RP held by a player + DisableLoginBoost bool // Disables the Login Boost system + DisableBoostTime bool // Disables the daily NetCafe Boost Time + BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for + GuildMealDuration int // The number of minutes a Guild Meal can be activated for after cooking + BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily + DailyQuestAllowance uint32 // Number of Daily Quests to allow daily + MezfesSoloTickets uint32 // Number of solo tickets given weekly + MezfesGroupTickets uint32 // Number of group tickets given weekly + GUrgentRate uint16 // Adjusts the rate of G Urgent quests spawning + GCPMultiplier float32 // Adjusts the multiplier of GCP rewarded for quest completion + GRPMultiplier float32 // Adjusts the multiplier of G Rank Points rewarded for quest completion + GSRPMultiplier float32 // Adjusts the multiplier of G Skill Rank Points rewarded for quest completion + GZennyMultiplier float32 // Adjusts the multiplier of G Zenny rewarded for quest completion + MaterialMultiplier float32 // Adjusts the multiplier of Monster Materials rewarded for quest completion + ExtraCarves uint16 // Grant n extra chances to carve ALL carcasses + DisableHunterNavi bool // Disables the Hunter Navi + EnableHiganjimaEvent bool // Enables the Higanjima event in the Rasta Bar + EnableNierEvent bool // Enables the Nier event in the Rasta Bar + DisableRoad bool // Disables the Hunting Road } // Discord holds the discord integration config. @@ -157,7 +184,6 @@ func init() { if err != nil { preventClose(fmt.Sprintf("Failed to load config: %s", err.Error())) } - } // getOutboundIP4 gets the preferred outbound ip4 of this machine @@ -199,6 +225,15 @@ func LoadConfig() (*Config, error) { c.Host = getOutboundIP4().To4().String() } + switch strings.ToUpper(c.ClientMode.String()) { + case "Z1": + c.ClientMode = Z1 + case "Z2": + c.ClientMode = Z2 + default: + c.ClientMode = ZZ + } + return c, nil } diff --git a/main.go b/main.go index 0f104eccf..6f1abc011 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + _config "erupe-ce/config" "fmt" "net" "os" @@ -9,7 +10,6 @@ import ( "syscall" "time" - "erupe-ce/config" "erupe-ce/server/channelserver" "erupe-ce/server/discordbot" "erupe-ce/server/entranceserver" @@ -45,7 +45,8 @@ func main() { var err error var zapLogger *zap.Logger - if config.ErupeConfig.DevMode { + config := _config.ErupeConfig + if config.DevMode { zapLogger, _ = zap.NewDevelopment() } else { zapLogger, _ = zap.NewProduction() @@ -55,20 +56,21 @@ func main() { logger := zapLogger.Named("main") logger.Info(fmt.Sprintf("Starting Erupe (9.3b-%s)", Commit())) + logger.Info(fmt.Sprintf("Client Mode: %s", config.ClientMode.String())) - if config.ErupeConfig.Database.Password == "" { + if config.Database.Password == "" { preventClose("Database password is blank") } - if net.ParseIP(config.ErupeConfig.Host) == nil { - ips, _ := net.LookupIP(config.ErupeConfig.Host) + if net.ParseIP(config.Host) == nil { + ips, _ := net.LookupIP(config.Host) for _, ip := range ips { if ip != nil { - config.ErupeConfig.Host = ip.String() + config.Host = ip.String() break } } - if net.ParseIP(config.ErupeConfig.Host) == nil { + if net.ParseIP(config.Host) == nil { preventClose("Invalid host address") } } @@ -76,10 +78,10 @@ func main() { // Discord bot var discordBot *discordbot.DiscordBot = nil - if config.ErupeConfig.Discord.Enabled { + if config.Discord.Enabled { bot, err := discordbot.NewDiscordBot(discordbot.Options{ Logger: logger, - Config: config.ErupeConfig, + Config: _config.ErupeConfig, }) if err != nil { @@ -102,11 +104,11 @@ func main() { // Create the postgres DB pool. connectString := fmt.Sprintf( "host='%s' port='%d' user='%s' password='%s' dbname='%s' sslmode=disable", - config.ErupeConfig.Database.Host, - config.ErupeConfig.Database.Port, - config.ErupeConfig.Database.User, - config.ErupeConfig.Database.Password, - config.ErupeConfig.Database.Database, + config.Database.Host, + config.Database.Port, + config.Database.User, + config.Database.Password, + config.Database.Database, ) db, err := sqlx.Open("postgres", connectString) @@ -126,7 +128,7 @@ func main() { _ = db.MustExec("DELETE FROM servers") // Clean the DB if the option is on. - if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.CleanDB { + if config.DevMode && config.DevModeOptions.CleanDB { logger.Info("Database: Started clearing...") cleanDB(db) logger.Info("Database: Finished clearing") @@ -139,11 +141,11 @@ func main() { // Entrance server. var entranceServer *entranceserver.Server - if config.ErupeConfig.Entrance.Enabled { + if config.Entrance.Enabled { entranceServer = entranceserver.NewServer( &entranceserver.Config{ Logger: logger.Named("entrance"), - ErupeConfig: config.ErupeConfig, + ErupeConfig: _config.ErupeConfig, DB: db, }) err = entranceServer.Start() @@ -158,11 +160,11 @@ func main() { // Sign server. var signServer *signserver.Server - if config.ErupeConfig.Sign.Enabled { + if config.Sign.Enabled { signServer = signserver.NewServer( &signserver.Config{ Logger: logger.Named("sign"), - ErupeConfig: config.ErupeConfig, + ErupeConfig: _config.ErupeConfig, DB: db, }) err = signServer.Start() @@ -176,11 +178,11 @@ func main() { // New Sign server var newSignServer *signv2server.Server - if config.ErupeConfig.SignV2.Enabled { + if config.SignV2.Enabled { newSignServer = signv2server.NewServer( &signv2server.Config{ Logger: logger.Named("sign"), - ErupeConfig: config.ErupeConfig, + ErupeConfig: _config.ErupeConfig, DB: db, }) err = newSignServer.Start() @@ -194,23 +196,23 @@ func main() { var channels []*channelserver.Server - if config.ErupeConfig.Channel.Enabled { + if config.Channel.Enabled { channelQuery := "" si := 0 ci := 0 count := 1 - for j, ee := range config.ErupeConfig.Entrance.Entries { + for j, ee := range config.Entrance.Entries { for i, ce := range ee.Channels { sid := (4096 + si*256) + (16 + ci) c := *channelserver.NewServer(&channelserver.Config{ ID: uint16(sid), Logger: logger.Named("channel-" + fmt.Sprint(count)), - ErupeConfig: config.ErupeConfig, + ErupeConfig: _config.ErupeConfig, DB: db, DiscordBot: discordBot, }) if ee.IP == "" { - c.IP = config.ErupeConfig.Host + c.IP = config.Host } else { c.IP = ee.IP } @@ -246,7 +248,7 @@ func main() { signal.Notify(c, os.Interrupt, syscall.SIGTERM) <-c - if !config.ErupeConfig.DisableSoftCrash { + if !config.DisableSoftCrash { for i := 0; i < 10; i++ { message := fmt.Sprintf("Shutting down in %d...", 10-i) for _, c := range channels { @@ -257,21 +259,21 @@ func main() { } } - if config.ErupeConfig.Channel.Enabled { + if config.Channel.Enabled { for _, c := range channels { c.Shutdown() } } - if config.ErupeConfig.Sign.Enabled { + if config.Sign.Enabled { signServer.Shutdown() } - if config.ErupeConfig.SignV2.Enabled { + if config.SignV2.Enabled { newSignServer.Shutdown() } - if config.ErupeConfig.Entrance.Enabled { + if config.Entrance.Enabled { entranceServer.Shutdown() } @@ -285,7 +287,7 @@ func wait() { } func preventClose(text string) { - if config.ErupeConfig.DisableSoftCrash { + if _config.ErupeConfig.DisableSoftCrash { os.Exit(0) } fmt.Println("\nFailed to start Erupe:\n" + text) diff --git a/network/mhfpacket/msg_mhf_caravan_my_rank.go b/network/mhfpacket/msg_mhf_caravan_my_rank.go index 3eb0074d4..d3e261caa 100644 --- a/network/mhfpacket/msg_mhf_caravan_my_rank.go +++ b/network/mhfpacket/msg_mhf_caravan_my_rank.go @@ -1,15 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfCaravanMyRank represents the MSG_MHF_CARAVAN_MY_RANK -type MsgMhfCaravanMyRank struct{} +type MsgMhfCaravanMyRank struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 uint32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfCaravanMyRank) Opcode() network.PacketID { @@ -18,7 +23,11 @@ func (m *MsgMhfCaravanMyRank) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfCaravanMyRank) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadUint32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_caravan_my_score.go b/network/mhfpacket/msg_mhf_caravan_my_score.go index bb83d0992..dfa2333b4 100644 --- a/network/mhfpacket/msg_mhf_caravan_my_score.go +++ b/network/mhfpacket/msg_mhf_caravan_my_score.go @@ -1,15 +1,24 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfCaravanMyScore represents the MSG_MHF_CARAVAN_MY_SCORE -type MsgMhfCaravanMyScore struct{} +type MsgMhfCaravanMyScore struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 int32 + Unk3 int32 + Unk4 uint32 + Unk5 int32 + Unk6 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfCaravanMyScore) Opcode() network.PacketID { @@ -18,7 +27,15 @@ func (m *MsgMhfCaravanMyScore) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfCaravanMyScore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadInt32() + m.Unk3 = bf.ReadInt32() + m.Unk4 = bf.ReadUint32() + m.Unk5 = bf.ReadInt32() + m.Unk6 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_caravan_ranking.go b/network/mhfpacket/msg_mhf_caravan_ranking.go index 7b5564bb6..1f86771af 100644 --- a/network/mhfpacket/msg_mhf_caravan_ranking.go +++ b/network/mhfpacket/msg_mhf_caravan_ranking.go @@ -1,15 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfCaravanRanking represents the MSG_MHF_CARAVAN_RANKING -type MsgMhfCaravanRanking struct{} +type MsgMhfCaravanRanking struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfCaravanRanking) Opcode() network.PacketID { @@ -18,7 +23,11 @@ func (m *MsgMhfCaravanRanking) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfCaravanRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_enumerate_quest.go b/network/mhfpacket/msg_mhf_enumerate_quest.go index 7bf1e1355..5961cf152 100644 --- a/network/mhfpacket/msg_mhf_enumerate_quest.go +++ b/network/mhfpacket/msg_mhf_enumerate_quest.go @@ -2,6 +2,7 @@ package mhfpacket import ( "errors" + _config "erupe-ce/config" "erupe-ce/common/byteframe" "erupe-ce/network" @@ -30,7 +31,9 @@ func (m *MsgMhfEnumerateQuest) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli m.World = bf.ReadUint8() m.Counter = bf.ReadUint16() m.Offset = bf.ReadUint16() - m.Unk4 = bf.ReadUint8() + if _config.ErupeConfig.ClientMode != _config.Z1 { + m.Unk4 = bf.ReadUint8() + } return nil } diff --git a/network/mhfpacket/msg_mhf_get_break_seibatu_level_reward.go b/network/mhfpacket/msg_mhf_get_break_seibatu_level_reward.go index e6f0e9a56..601dd5cb2 100644 --- a/network/mhfpacket/msg_mhf_get_break_seibatu_level_reward.go +++ b/network/mhfpacket/msg_mhf_get_break_seibatu_level_reward.go @@ -1,15 +1,19 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfGetBreakSeibatuLevelReward represents the MSG_MHF_GET_BREAK_SEIBATU_LEVEL_REWARD -type MsgMhfGetBreakSeibatuLevelReward struct{} +type MsgMhfGetBreakSeibatuLevelReward struct { + AckHandle uint32 + Unk0 uint32 + Unk1 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfGetBreakSeibatuLevelReward) Opcode() network.PacketID { @@ -18,7 +22,10 @@ func (m *MsgMhfGetBreakSeibatuLevelReward) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetBreakSeibatuLevelReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_get_fixed_seibatu_ranking_table.go b/network/mhfpacket/msg_mhf_get_fixed_seibatu_ranking_table.go index 52651c9d2..2d7cbbac4 100644 --- a/network/mhfpacket/msg_mhf_get_fixed_seibatu_ranking_table.go +++ b/network/mhfpacket/msg_mhf_get_fixed_seibatu_ranking_table.go @@ -1,15 +1,22 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfGetFixedSeibatuRankingTable represents the MSG_MHF_GET_FIXED_SEIBATU_RANKING_TABLE -type MsgMhfGetFixedSeibatuRankingTable struct{} +type MsgMhfGetFixedSeibatuRankingTable struct { + AckHandle uint32 + Unk0 uint32 + Unk1 int32 + Unk2 int32 + Unk3 int32 + Unk4 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfGetFixedSeibatuRankingTable) Opcode() network.PacketID { @@ -18,7 +25,13 @@ func (m *MsgMhfGetFixedSeibatuRankingTable) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetFixedSeibatuRankingTable) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadInt32() + m.Unk2 = bf.ReadInt32() + m.Unk3 = bf.ReadInt32() + m.Unk4 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_get_gem_info.go b/network/mhfpacket/msg_mhf_get_gem_info.go index 36eb7948e..28638bfd2 100644 --- a/network/mhfpacket/msg_mhf_get_gem_info.go +++ b/network/mhfpacket/msg_mhf_get_gem_info.go @@ -11,8 +11,13 @@ import ( // MsgMhfGetGemInfo represents the MSG_MHF_GET_GEM_INFO type MsgMhfGetGemInfo struct { AckHandle uint32 - Unk uint32 - Unk1 []byte + Unk0 uint32 + Unk1 uint32 + Unk2 int32 + Unk3 int32 + Unk4 int32 + Unk5 int32 + Unk6 int32 } // Opcode returns the ID associated with this packet type. @@ -23,8 +28,13 @@ func (m *MsgMhfGetGemInfo) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk = bf.ReadUint32() - m.Unk1 = bf.ReadBytes(24) + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadInt32() + m.Unk3 = bf.ReadInt32() + m.Unk4 = bf.ReadInt32() + m.Unk5 = bf.ReadInt32() + m.Unk6 = bf.ReadInt32() return nil } diff --git a/network/mhfpacket/msg_mhf_get_notice.go b/network/mhfpacket/msg_mhf_get_notice.go index 75e18d9d5..843e71ddc 100644 --- a/network/mhfpacket/msg_mhf_get_notice.go +++ b/network/mhfpacket/msg_mhf_get_notice.go @@ -1,15 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfGetNotice represents the MSG_MHF_GET_NOTICE -type MsgMhfGetNotice struct{} +type MsgMhfGetNotice struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfGetNotice) Opcode() network.PacketID { @@ -18,7 +23,11 @@ func (m *MsgMhfGetNotice) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetNotice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_get_ryoudama.go b/network/mhfpacket/msg_mhf_get_ryoudama.go index 2cffc3bdc..91d1566af 100644 --- a/network/mhfpacket/msg_mhf_get_ryoudama.go +++ b/network/mhfpacket/msg_mhf_get_ryoudama.go @@ -11,8 +11,8 @@ import ( // MsgMhfGetRyoudama represents the MSG_MHF_GET_RYOUDAMA type MsgMhfGetRyoudama struct { AckHandle uint32 - Unk0 uint8 - Unk1 uint8 + Request1 uint8 + Request2 uint8 GuildID uint32 Unk3 uint8 } @@ -25,8 +25,8 @@ func (m *MsgMhfGetRyoudama) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetRyoudama) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint8() - m.Unk1 = bf.ReadUint8() + m.Request1 = bf.ReadUint8() + m.Request2 = bf.ReadUint8() m.GuildID = bf.ReadUint32() m.Unk3 = bf.ReadUint8() return nil diff --git a/network/mhfpacket/msg_mhf_get_seibattle.go b/network/mhfpacket/msg_mhf_get_seibattle.go index 6a7a80380..1398b477d 100644 --- a/network/mhfpacket/msg_mhf_get_seibattle.go +++ b/network/mhfpacket/msg_mhf_get_seibattle.go @@ -1,20 +1,19 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfGetSeibattle represents the MSG_MHF_GET_SEIBATTLE type MsgMhfGetSeibattle struct { - // Communicator type, multi-format. This might be valid for only one type. AckHandle uint32 Unk0 uint8 - Unk1 uint8 - Unk2 uint32 // Some shared ID with MSG_SYS_RECORD_LOG, world ID? + Type uint8 + GuildID uint32 Unk3 uint8 Unk4 uint16 } @@ -28,8 +27,8 @@ func (m *MsgMhfGetSeibattle) Opcode() network.PacketID { func (m *MsgMhfGetSeibattle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.Unk0 = bf.ReadUint8() - m.Unk1 = bf.ReadUint8() - m.Unk2 = bf.ReadUint32() + m.Type = bf.ReadUint8() + m.GuildID = bf.ReadUint32() m.Unk3 = bf.ReadUint8() m.Unk4 = bf.ReadUint16() return nil diff --git a/network/mhfpacket/msg_mhf_get_tenrouirai.go b/network/mhfpacket/msg_mhf_get_tenrouirai.go index da460add9..a4784e39b 100644 --- a/network/mhfpacket/msg_mhf_get_tenrouirai.go +++ b/network/mhfpacket/msg_mhf_get_tenrouirai.go @@ -1,20 +1,21 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfGetTenrouirai represents the MSG_MHF_GET_TENROUIRAI type MsgMhfGetTenrouirai struct { - // Communicator type, multi-format. This might be valid for only one type. AckHandle uint32 - Unk0 uint16 - Unk1 uint32 - Unk2 uint16 + Unk0 uint8 + Unk1 uint8 + GuildID uint32 + Unk3 uint8 + Unk4 uint8 } // Opcode returns the ID associated with this packet type. @@ -25,9 +26,11 @@ func (m *MsgMhfGetTenrouirai) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint16() - m.Unk1 = bf.ReadUint32() - m.Unk2 = bf.ReadUint16() + m.Unk0 = bf.ReadUint8() + m.Unk1 = bf.ReadUint8() + m.GuildID = bf.ReadUint32() + m.Unk3 = bf.ReadUint8() + m.Unk4 = bf.ReadUint8() return nil } diff --git a/network/mhfpacket/msg_mhf_get_tiny_bin.go b/network/mhfpacket/msg_mhf_get_tiny_bin.go index 8f76eb1a1..4db9b05b9 100644 --- a/network/mhfpacket/msg_mhf_get_tiny_bin.go +++ b/network/mhfpacket/msg_mhf_get_tiny_bin.go @@ -1,19 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfGetTinyBin represents the MSG_MHF_GET_TINY_BIN type MsgMhfGetTinyBin struct { // Communicator type, multi-format. This might be valid for only one type. AckHandle uint32 - Unk0 uint16 + Unk0 uint8 Unk1 uint8 + Unk2 uint8 } // Opcode returns the ID associated with this packet type. @@ -24,8 +25,9 @@ func (m *MsgMhfGetTinyBin) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfGetTinyBin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint16() + m.Unk0 = bf.ReadUint8() m.Unk1 = bf.ReadUint8() + m.Unk2 = bf.ReadUint8() return nil } diff --git a/network/mhfpacket/msg_mhf_get_tower_info.go b/network/mhfpacket/msg_mhf_get_tower_info.go index a0b686485..4041e26e4 100644 --- a/network/mhfpacket/msg_mhf_get_tower_info.go +++ b/network/mhfpacket/msg_mhf_get_tower_info.go @@ -8,19 +8,8 @@ import ( "erupe-ce/network/clientctx" ) -// The server sends different responses based on these values. -const ( - TowerInfoTypeUnk0 = iota - TowerInfoTypeTowerRankPoint - TowerInfoTypeGetOwnTowerSkill - TowerInfoTypeGetOwnTowerLevelV3 - TowerInfoTypeTowerTouhaHistory - TowerInfoTypeUnk5 -) - // MsgMhfGetTowerInfo represents the MSG_MHF_GET_TOWER_INFO type MsgMhfGetTowerInfo struct { - // Communicator type, multi-format. This might be valid for only one type. AckHandle uint32 InfoType uint32 // Requested response type Unk0 uint32 diff --git a/network/mhfpacket/msg_mhf_post_gem_info.go b/network/mhfpacket/msg_mhf_post_gem_info.go index 13a0a9a0d..d487670fc 100644 --- a/network/mhfpacket/msg_mhf_post_gem_info.go +++ b/network/mhfpacket/msg_mhf_post_gem_info.go @@ -1,15 +1,24 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfPostGemInfo represents the MSG_MHF_POST_GEM_INFO -type MsgMhfPostGemInfo struct{} +type MsgMhfPostGemInfo struct { + AckHandle uint32 + Op uint32 + Unk1 uint32 + Gem int32 + Quantity int32 + CID int32 + Message int32 + Unk6 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfPostGemInfo) Opcode() network.PacketID { @@ -18,7 +27,15 @@ func (m *MsgMhfPostGemInfo) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPostGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Op = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Gem = bf.ReadInt32() + m.Quantity = bf.ReadInt32() + m.CID = bf.ReadInt32() + m.Message = bf.ReadInt32() + m.Unk6 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_post_notice.go b/network/mhfpacket/msg_mhf_post_notice.go index c599d2afc..51eb945fa 100644 --- a/network/mhfpacket/msg_mhf_post_notice.go +++ b/network/mhfpacket/msg_mhf_post_notice.go @@ -1,15 +1,21 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfPostNotice represents the MSG_MHF_POST_NOTICE -type MsgMhfPostNotice struct{} +type MsgMhfPostNotice struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 int32 + Unk3 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfPostNotice) Opcode() network.PacketID { @@ -18,7 +24,12 @@ func (m *MsgMhfPostNotice) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPostNotice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + m.Unk2 = bf.ReadInt32() + m.Unk3 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_post_tenrouirai.go b/network/mhfpacket/msg_mhf_post_tenrouirai.go index d4b4fdc71..bc91279b4 100644 --- a/network/mhfpacket/msg_mhf_post_tenrouirai.go +++ b/network/mhfpacket/msg_mhf_post_tenrouirai.go @@ -1,22 +1,34 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfPostTenrouirai represents the MSG_MHF_POST_TENROUIRAI -type MsgMhfPostTenrouirai struct{ - AckHandle uint32 - Unk0 uint16 - Unk1 uint32 - Unk2 uint32 - Unk3 uint32 - Unk4 uint32 - Unk5 uint8 +type MsgMhfPostTenrouirai struct { + AckHandle uint32 + Unk0 uint8 + Op uint8 + GuildID uint32 + Unk1 uint8 + + Floors uint16 + Antiques uint16 + Chests uint16 + Cats uint16 + TRP uint16 + Slays uint16 + + DonatedRP uint16 + PreviousRP uint16 + Unk2_0 uint16 + Unk2_1 uint16 + Unk2_2 uint16 + Unk2_3 uint16 } // Opcode returns the ID associated with this packet type. @@ -27,12 +39,28 @@ func (m *MsgMhfPostTenrouirai) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPostTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint16() - m.Unk1 = bf.ReadUint32() - m.Unk2 = bf.ReadUint32() - m.Unk3 = bf.ReadUint32() - m.Unk4 = bf.ReadUint32() - m.Unk5 = bf.ReadUint8() + m.Unk0 = bf.ReadUint8() + m.Op = bf.ReadUint8() + m.GuildID = bf.ReadUint32() + m.Unk1 = bf.ReadUint8() + + switch m.Op { + case 1: + m.Floors = bf.ReadUint16() + m.Antiques = bf.ReadUint16() + m.Chests = bf.ReadUint16() + m.Cats = bf.ReadUint16() + m.TRP = bf.ReadUint16() + m.Slays = bf.ReadUint16() + case 2: + m.DonatedRP = bf.ReadUint16() + m.PreviousRP = bf.ReadUint16() + m.Unk2_0 = bf.ReadUint16() + m.Unk2_1 = bf.ReadUint16() + m.Unk2_2 = bf.ReadUint16() + m.Unk2_3 = bf.ReadUint16() + } + return nil } diff --git a/network/mhfpacket/msg_mhf_post_tiny_bin.go b/network/mhfpacket/msg_mhf_post_tiny_bin.go index 7c709d1e4..dd464d18d 100644 --- a/network/mhfpacket/msg_mhf_post_tiny_bin.go +++ b/network/mhfpacket/msg_mhf_post_tiny_bin.go @@ -11,9 +11,10 @@ import ( // MsgMhfPostTinyBin represents the MSG_MHF_POST_TINY_BIN type MsgMhfPostTinyBin struct { AckHandle uint32 - Unk0 uint16 + Unk0 uint8 Unk1 uint8 Unk2 uint8 + Unk3 uint8 Data []byte } @@ -25,9 +26,10 @@ func (m *MsgMhfPostTinyBin) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPostTinyBin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint16() + m.Unk0 = bf.ReadUint8() m.Unk1 = bf.ReadUint8() m.Unk2 = bf.ReadUint8() + m.Unk3 = bf.ReadUint8() m.Data = bf.ReadBytes(uint(bf.ReadUint16())) return nil } diff --git a/network/mhfpacket/msg_mhf_post_tower_info.go b/network/mhfpacket/msg_mhf_post_tower_info.go index 7719086ff..3808777e5 100644 --- a/network/mhfpacket/msg_mhf_post_tower_info.go +++ b/network/mhfpacket/msg_mhf_post_tower_info.go @@ -1,28 +1,26 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfPostTowerInfo represents the MSG_MHF_POST_TOWER_INFO type MsgMhfPostTowerInfo struct { - // Communicator type, multi-format. This might be valid for only one type. AckHandle uint32 - Unk0 uint32 + InfoType uint32 Unk1 uint32 - Unk2 uint32 - Unk3 uint32 - Unk4 uint32 - Unk5 uint32 - Unk6 uint32 - Unk7 uint32 - Unk8 uint32 - Unk9 uint32 - Unk10 uint32 + Skill int32 + TR int32 + TRP int32 + Cost int32 + Unk6 int32 + Unk7 int32 + Block1 int32 + Unk9 int64 } // Opcode returns the ID associated with this packet type. @@ -33,17 +31,16 @@ func (m *MsgMhfPostTowerInfo) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPostTowerInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint32() + m.InfoType = bf.ReadUint32() m.Unk1 = bf.ReadUint32() - m.Unk2 = bf.ReadUint32() - m.Unk3 = bf.ReadUint32() - m.Unk4 = bf.ReadUint32() - m.Unk5 = bf.ReadUint32() - m.Unk6 = bf.ReadUint32() - m.Unk7 = bf.ReadUint32() - m.Unk8 = bf.ReadUint32() - m.Unk9 = bf.ReadUint32() - m.Unk10 = bf.ReadUint32() + m.Skill = bf.ReadInt32() + m.TR = bf.ReadInt32() + m.TRP = bf.ReadInt32() + m.Cost = bf.ReadInt32() + m.Unk6 = bf.ReadInt32() + m.Unk7 = bf.ReadInt32() + m.Block1 = bf.ReadInt32() + m.Unk9 = bf.ReadInt64() return nil } diff --git a/network/mhfpacket/msg_mhf_present_box.go b/network/mhfpacket/msg_mhf_present_box.go index c3da92e31..d0064799c 100644 --- a/network/mhfpacket/msg_mhf_present_box.go +++ b/network/mhfpacket/msg_mhf_present_box.go @@ -18,8 +18,7 @@ type MsgMhfPresentBox struct { Unk4 uint32 Unk5 uint32 Unk6 uint32 - Unk7 uint32 - Unk8 uint32 + Unk7 []uint32 } // Opcode returns the ID associated with this packet type. @@ -37,8 +36,9 @@ func (m *MsgMhfPresentBox) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientC m.Unk4 = bf.ReadUint32() m.Unk5 = bf.ReadUint32() m.Unk6 = bf.ReadUint32() - m.Unk7 = bf.ReadUint32() - m.Unk8 = bf.ReadUint32() + for i := uint32(0); i < m.Unk2; i++ { + m.Unk7 = append(m.Unk7, bf.ReadUint32()) + } return nil } diff --git a/network/mhfpacket/msg_mhf_read_beat_level_all_ranking.go b/network/mhfpacket/msg_mhf_read_beat_level_all_ranking.go index 4d97df0d5..d9bf48a2c 100644 --- a/network/mhfpacket/msg_mhf_read_beat_level_all_ranking.go +++ b/network/mhfpacket/msg_mhf_read_beat_level_all_ranking.go @@ -1,15 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfReadBeatLevelAllRanking represents the MSG_MHF_READ_BEAT_LEVEL_ALL_RANKING -type MsgMhfReadBeatLevelAllRanking struct{} +type MsgMhfReadBeatLevelAllRanking struct { + AckHandle uint32 + Unk0 uint32 + GuildID int32 + Unk2 int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfReadBeatLevelAllRanking) Opcode() network.PacketID { @@ -18,7 +23,11 @@ func (m *MsgMhfReadBeatLevelAllRanking) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfReadBeatLevelAllRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.GuildID = bf.ReadInt32() + m.Unk2 = bf.ReadInt32() + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_read_beat_level_my_ranking.go b/network/mhfpacket/msg_mhf_read_beat_level_my_ranking.go index 4b713e8e7..e51bba318 100644 --- a/network/mhfpacket/msg_mhf_read_beat_level_my_ranking.go +++ b/network/mhfpacket/msg_mhf_read_beat_level_my_ranking.go @@ -1,15 +1,20 @@ package mhfpacket -import ( - "errors" +import ( + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfReadBeatLevelMyRanking represents the MSG_MHF_READ_BEAT_LEVEL_MY_RANKING -type MsgMhfReadBeatLevelMyRanking struct{} +type MsgMhfReadBeatLevelMyRanking struct { + AckHandle uint32 + Unk0 uint32 + Unk1 uint32 + Unk2 []int32 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfReadBeatLevelMyRanking) Opcode() network.PacketID { @@ -18,7 +23,13 @@ func (m *MsgMhfReadBeatLevelMyRanking) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfReadBeatLevelMyRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint32() + m.Unk1 = bf.ReadUint32() + for i := 0; i < 16; i++ { + m.Unk2 = append(m.Unk2, bf.ReadInt32()) + } + return nil } // Build builds a binary packet from the current data. diff --git a/network/mhfpacket/msg_mhf_stampcard_stamp.go b/network/mhfpacket/msg_mhf_stampcard_stamp.go index 8d18ae971..ec6dac6db 100644 --- a/network/mhfpacket/msg_mhf_stampcard_stamp.go +++ b/network/mhfpacket/msg_mhf_stampcard_stamp.go @@ -2,6 +2,7 @@ package mhfpacket import ( "errors" + _config "erupe-ce/config" "erupe-ce/common/byteframe" "erupe-ce/network" @@ -34,12 +35,14 @@ func (m *MsgMhfStampcardStamp) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli m.GR = bf.ReadUint16() m.Stamps = bf.ReadUint16() _ = bf.ReadUint16() - m.Reward1 = uint16(bf.ReadUint32()) - m.Reward2 = uint16(bf.ReadUint32()) - m.Item1 = uint16(bf.ReadUint32()) - m.Item2 = uint16(bf.ReadUint32()) - m.Quantity1 = uint16(bf.ReadUint32()) - m.Quantity2 = uint16(bf.ReadUint32()) + if _config.ErupeConfig.ClientMode != _config.Z1 { + m.Reward1 = uint16(bf.ReadUint32()) + m.Reward2 = uint16(bf.ReadUint32()) + m.Item1 = uint16(bf.ReadUint32()) + m.Item2 = uint16(bf.ReadUint32()) + m.Quantity1 = uint16(bf.ReadUint32()) + m.Quantity2 = uint16(bf.ReadUint32()) + } return nil } diff --git a/patch-schema/tower.sql b/patch-schema/tower.sql new file mode 100644 index 000000000..0697fc2be --- /dev/null +++ b/patch-schema/tower.sql @@ -0,0 +1,29 @@ +BEGIN; + +CREATE TABLE IF NOT EXISTS tower ( + char_id INT, + tr INT, + trp INT, + tsp INT, + block1 INT, + block2 INT, + skills TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0', + gems TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0' +); + +ALTER TABLE IF EXISTS guild_characters + ADD COLUMN IF NOT EXISTS tower_mission_1 INT; + +ALTER TABLE IF EXISTS guild_characters + ADD COLUMN IF NOT EXISTS tower_mission_2 INT; + +ALTER TABLE IF EXISTS guild_characters + ADD COLUMN IF NOT EXISTS tower_mission_3 INT; + +ALTER TABLE IF EXISTS guilds + ADD COLUMN IF NOT EXISTS tower_mission_page INT DEFAULT 1; + +ALTER TABLE IF EXISTS guilds + ADD COLUMN IF NOT EXISTS tower_rp INT DEFAULT 0; + +END; \ No newline at end of file diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 1c189f5fb..4647b8021 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -27,15 +27,16 @@ func stubEnumerateNoResults(s *Session, ackHandle uint32) { doAckBufSucceed(s, ackHandle, enumBf.Data()) } -// Temporary function to just return no results for many MSG_MHF_GET* packets. -func stubGetNoResults(s *Session, ackHandle uint32) { - resp := byteframe.NewByteFrame() - resp.WriteUint32(0x0A218EAD) // Unk shared ID. Sent in response of MSG_MHF_GET_TOWER_INFO, MSG_MHF_GET_PAPER_DATA etc. (World ID?) - resp.WriteUint32(0) // Unk - resp.WriteUint32(0) // Unk - resp.WriteUint32(0) // Entry count - - doAckBufSucceed(s, ackHandle, resp.Data()) +func doAckEarthSucceed(s *Session, ackHandle uint32, data []*byteframe.ByteFrame) { + bf := byteframe.NewByteFrame() + bf.WriteUint32(uint32(s.server.erupeConfig.DevModeOptions.EarthIDOverride)) + bf.WriteUint32(0) + bf.WriteUint32(0) + bf.WriteUint32(uint32(len(data))) + for i := range data { + bf.WriteBytes(data[i].Data()) + } + doAckBufSucceed(s, ackHandle, bf.Data()) } func doAckBufSucceed(s *Session, ackHandle uint32, data []byte) { @@ -1574,46 +1575,16 @@ func handleMsgMhfStampcardPrize(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfUnreserveSrg(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfReadBeatLevel(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfReadBeatLevel) - - // This response is fixed and will never change on JP, - // but I've left it dynamic for possible other client differences. - resp := byteframe.NewByteFrame() - for i := 0; i < int(pkt.ValidIDCount); i++ { - resp.WriteUint32(pkt.IDs[i]) - resp.WriteUint32(1) - resp.WriteUint32(1) - resp.WriteUint32(1) - } - - doAckBufSucceed(s, pkt.AckHandle, resp.Data()) -} - -func handleMsgMhfUpdateBeatLevel(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfUpdateBeatLevel) - - doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) -} - -func handleMsgMhfReadBeatLevelAllRanking(s *Session, p mhfpacket.MHFPacket) {} - -func handleMsgMhfReadBeatLevelMyRanking(s *Session, p mhfpacket.MHFPacket) {} - -func handleMsgMhfReadLastWeekBeatRanking(s *Session, p mhfpacket.MHFPacket) {} - -func handleMsgMhfGetFixedSeibatuRankingTable(s *Session, p mhfpacket.MHFPacket) {} - func handleMsgMhfKickExportForce(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetEarthStatus) bf := byteframe.NewByteFrame() - bf.WriteUint32(uint32(TimeWeekStart().Unix())) // Start - bf.WriteUint32(uint32(TimeWeekNext().Unix())) // End + bf.WriteUint32(uint32(TimeWeekStart().Add(time.Hour * -24).Unix())) // Start + bf.WriteUint32(uint32(TimeWeekNext().Add(time.Hour * 24).Unix())) // End bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthStatusOverride) - bf.WriteInt32(21) - bf.WriteInt32(0) + bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthIDOverride) + bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthMonsterOverride) bf.WriteInt32(0) bf.WriteInt32(0) bf.WriteInt32(0) @@ -1624,86 +1595,183 @@ func handleMsgMhfRegistSpabiTime(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetEarthValue) - var earthValues []struct{ Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 } - if pkt.ReqType == 3 { - earthValues = []struct { - Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 - }{ - // TW identical to JP - { - Unk0: 0x03E9, - Unk1: 0x24, - }, - { - Unk0: 0x2329, - Unk1: 0x03, - }, - { - Unk0: 0x232A, - Unk1: 0x0A, - Unk2: 0x012C, - }, + type EarthValues struct { + Value []uint32 + } + + var earthValues []EarthValues + switch pkt.ReqType { + case 1: + earthValues = []EarthValues{ + {[]uint32{1, 312, 0, 0, 0, 0}}, + {[]uint32{2, 99, 0, 0, 0, 0}}, } - } else if pkt.ReqType == 2 { - earthValues = []struct { - Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 - }{ - // JP response was empty - { - Unk0: 0x01, - Unk1: 0x168B, - }, - { - Unk0: 0x02, - Unk1: 0x0737, - }, + case 2: + earthValues = []EarthValues{ + {[]uint32{1, 5771, 0, 0, 0, 0}}, + {[]uint32{2, 1847, 0, 0, 0, 0}}, } - } else if pkt.ReqType == 1 { - earthValues = []struct { - Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 - }{ - // JP simply sent 01 and 02 respectively - { - Unk0: 0x01, - Unk1: 0x0138, - }, - { - Unk0: 0x02, - Unk1: 0x63, - }, + case 3: + earthValues = []EarthValues{ + {[]uint32{1001, 36, 0, 0, 0, 0}}, + {[]uint32{9001, 3, 0, 0, 0, 0}}, + {[]uint32{9002, 10, 300, 0, 0, 0}}, } } - resp := byteframe.NewByteFrame() - resp.WriteUint32(0x0A218EAD) // Unk shared ID. Sent in response of MSG_MHF_GET_TOWER_INFO, MSG_MHF_GET_PAPER_DATA etc. - resp.WriteUint32(0) // Unk - resp.WriteUint32(0) // Unk - resp.WriteUint32(uint32(len(earthValues))) // value count - for _, v := range earthValues { - resp.WriteUint32(v.Unk0) - resp.WriteUint32(v.Unk1) - resp.WriteUint32(v.Unk2) - resp.WriteUint32(v.Unk3) - resp.WriteUint32(v.Unk4) - resp.WriteUint32(v.Unk5) + var data []*byteframe.ByteFrame + for _, i := range earthValues { + bf := byteframe.NewByteFrame() + for _, j := range i.Value { + bf.WriteUint32(j) + } + data = append(data, bf) } - - doAckBufSucceed(s, pkt.AckHandle, resp.Data()) + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfDebugPostValue(s *Session, p mhfpacket.MHFPacket) {} -func handleMsgMhfGetNotice(s *Session, p mhfpacket.MHFPacket) {} - -func handleMsgMhfPostNotice(s *Session, p mhfpacket.MHFPacket) {} - func handleMsgMhfGetRandFromTable(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfGetSenyuDailyCount(s *Session, p mhfpacket.MHFPacket) {} +type SeibattleTimetable struct { + Start time.Time + End time.Time +} + +type SeibattleKeyScore struct { + Unk0 uint8 + Unk1 int32 +} + +type SeibattleCareer struct { + Unk0 uint16 + Unk1 uint16 + Unk2 uint16 +} + +type SeibattleOpponent struct { + Unk0 int32 + Unk1 int8 +} + +type SeibattleConventionResult struct { + Unk0 uint32 + Unk1 uint16 + Unk2 uint16 + Unk3 uint16 + Unk4 uint16 +} + +type SeibattleCharScore struct { + Unk0 uint32 +} + +type SeibattleCurResult struct { + Unk0 uint32 + Unk1 uint16 + Unk2 uint16 + Unk3 uint16 +} + +type Seibattle struct { + Timetable []SeibattleTimetable + KeyScore []SeibattleKeyScore + Career []SeibattleCareer + Opponent []SeibattleOpponent + ConventionResult []SeibattleConventionResult + CharScore []SeibattleCharScore + CurResult []SeibattleCurResult +} + func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetSeibattle) - stubGetNoResults(s, pkt.AckHandle) + var data []*byteframe.ByteFrame + seibattle := Seibattle{ + Timetable: []SeibattleTimetable{ + {TimeMidnight(), TimeMidnight().Add(time.Hour * 8)}, + {TimeMidnight().Add(time.Hour * 8), TimeMidnight().Add(time.Hour * 16)}, + {TimeMidnight().Add(time.Hour * 16), TimeMidnight().Add(time.Hour * 24)}, + }, + KeyScore: []SeibattleKeyScore{ + {0, 0}, + }, + Career: []SeibattleCareer{ + {0, 0, 0}, + }, + Opponent: []SeibattleOpponent{ + {1, 1}, + }, + ConventionResult: []SeibattleConventionResult{ + {0, 0, 0, 0, 0}, + }, + CharScore: []SeibattleCharScore{ + {0}, + }, + CurResult: []SeibattleCurResult{ + {0, 0, 0, 0}, + }, + } + + switch pkt.Type { + case 1: + for _, timetable := range seibattle.Timetable { + bf := byteframe.NewByteFrame() + bf.WriteUint32(uint32(timetable.Start.Unix())) + bf.WriteUint32(uint32(timetable.End.Unix())) + data = append(data, bf) + } + case 3: // Key score? + for _, keyScore := range seibattle.KeyScore { + bf := byteframe.NewByteFrame() + bf.WriteUint8(keyScore.Unk0) + bf.WriteInt32(keyScore.Unk1) + data = append(data, bf) + } + case 4: // Career? + for _, career := range seibattle.Career { + bf := byteframe.NewByteFrame() + bf.WriteUint16(career.Unk0) + bf.WriteUint16(career.Unk1) + bf.WriteUint16(career.Unk2) + data = append(data, bf) + } + case 5: // Opponent? + for _, opponent := range seibattle.Opponent { + bf := byteframe.NewByteFrame() + bf.WriteInt32(opponent.Unk0) + bf.WriteInt8(opponent.Unk1) + data = append(data, bf) + } + case 6: // Convention result? + for _, conventionResult := range seibattle.ConventionResult { + bf := byteframe.NewByteFrame() + bf.WriteUint32(conventionResult.Unk0) + bf.WriteUint16(conventionResult.Unk1) + bf.WriteUint16(conventionResult.Unk2) + bf.WriteUint16(conventionResult.Unk3) + bf.WriteUint16(conventionResult.Unk4) + data = append(data, bf) + } + case 7: // Char score? + for _, charScore := range seibattle.CharScore { + bf := byteframe.NewByteFrame() + bf.WriteUint32(charScore.Unk0) + data = append(data, bf) + } + case 8: // Cur result? + for _, curResult := range seibattle.CurResult { + bf := byteframe.NewByteFrame() + bf.WriteUint32(curResult.Unk0) + bf.WriteUint16(curResult.Unk1) + bf.WriteUint16(curResult.Unk2) + bf.WriteUint16(curResult.Unk3) + data = append(data, bf) + } + } + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/handlers_caravan.go b/server/channelserver/handlers_caravan.go index 86cf73249..c90f44812 100644 --- a/server/channelserver/handlers_caravan.go +++ b/server/channelserver/handlers_caravan.go @@ -1,21 +1,73 @@ package channelserver import ( - "encoding/hex" + "erupe-ce/common/byteframe" + "erupe-ce/common/stringsupport" "erupe-ce/network/mhfpacket" + "time" ) +type RyoudamaReward struct { + Unk0 uint8 + Unk1 uint8 + Unk2 uint16 + Unk3 uint16 + Unk4 uint16 + Unk5 uint16 +} + +type RyoudamaKeyScore struct { + Unk0 uint8 + Unk1 int32 +} + +type RyoudamaCharInfo struct { + CID uint32 + Unk0 int32 + Name string +} + +type RyoudamaBoostInfo struct { + Start time.Time + End time.Time +} + +type Ryoudama struct { + Reward []RyoudamaReward + KeyScore []RyoudamaKeyScore + CharInfo []RyoudamaCharInfo + BoostInfo []RyoudamaBoostInfo + Score []int32 +} + func handleMsgMhfGetRyoudama(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetRyoudama) - // likely guild related - // REQ: 00 04 13 53 8F 18 00 - // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 01 FE 4E - // REQ: 00 06 13 53 8F 18 00 - // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 - // REQ: 00 05 13 53 8F 18 00 - // RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 0E 2A 15 9E CC 00 00 00 01 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 1E 55 B0 2F 00 00 00 01 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 2A 15 9E CC 00 00 00 02 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 03 D5 30 56 00 00 00 02 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 3F 57 76 9F 00 00 00 03 93 56 92 6E 96 B3 97 70 00 00 00 00 00 00 38 D9 0E C4 00 00 00 03 87 64 83 78 83 42 00 00 00 00 00 00 00 00 23 F3 B9 77 00 00 00 04 82 B3 82 CC 82 DC 82 E9 81 99 00 00 00 00 3F 1B 17 9C 00 00 00 04 82 B1 82 A4 82 BD 00 00 00 00 00 00 00 00 00 B9 F9 C0 00 00 00 05 82 CD 82 E9 82 A9 00 00 00 00 00 00 00 00 23 9F 9A EA 00 00 00 05 83 70 83 62 83 4C 83 83 83 49 00 00 00 00 38 D9 0E C4 00 00 00 06 87 64 83 78 83 42 00 00 00 00 00 00 00 00 1E 55 B0 2F 00 00 00 06 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 03 D5 30 56 00 00 00 07 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 02 D3 B8 77 00 00 00 07 6F 77 6C 32 35 32 35 00 00 00 00 00 00 00 - data, _ := hex.DecodeString("0A218EAD0000000000000000000000010000000000000000") - doAckBufSucceed(s, pkt.AckHandle, data) + var data []*byteframe.ByteFrame + ryoudama := Ryoudama{Score: []int32{0}} + switch pkt.Request2 { + case 4: + for _, score := range ryoudama.Score { + bf := byteframe.NewByteFrame() + bf.WriteInt32(score) + data = append(data, bf) + } + case 5: + for _, info := range ryoudama.CharInfo { + bf := byteframe.NewByteFrame() + bf.WriteUint32(info.CID) + bf.WriteInt32(info.Unk0) + bf.WriteBytes(stringsupport.PaddedString(info.Name, 14, true)) + data = append(data, bf) + } + case 6: + for _, info := range ryoudama.BoostInfo { + bf := byteframe.NewByteFrame() + bf.WriteUint32(uint32(info.Start.Unix())) + bf.WriteUint32(uint32(info.End.Unix())) + data = append(data, bf) + } + } + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostRyoudama(s *Session, p mhfpacket.MHFPacket) {} @@ -31,8 +83,41 @@ func handleMsgMhfPostTinyBin(s *Session, p mhfpacket.MHFPacket) { doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } -func handleMsgMhfCaravanMyScore(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfCaravanMyScore(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfCaravanMyScore) + var data []*byteframe.ByteFrame + /* + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + */ + doAckEarthSucceed(s, pkt.AckHandle, data) +} -func handleMsgMhfCaravanRanking(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfCaravanRanking(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfCaravanRanking) + var data []*byteframe.ByteFrame + /* RYOUDAN + bf.WriteInt32(1) + bf.WriteUint32(2) + bf.WriteBytes(stringsupport.PaddedString("Test", 26, true)) + */ -func handleMsgMhfCaravanMyRank(s *Session, p mhfpacket.MHFPacket) {} + /* PERSONAL + bf.WriteInt32(1) + bf.WriteBytes(stringsupport.PaddedString("Test", 14, true)) + */ + doAckEarthSucceed(s, pkt.AckHandle, data) +} + +func handleMsgMhfCaravanMyRank(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfCaravanMyRank) + var data []*byteframe.ByteFrame + /* + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + */ + doAckEarthSucceed(s, pkt.AckHandle, data) +} diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 7c961b5e9..3e950657f 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -35,16 +35,16 @@ const ( BroadcastTypeWorld = 0x0a ) -var commands map[string]config.Command +var commands map[string]_config.Command func init() { - commands = make(map[string]config.Command) + commands = make(map[string]_config.Command) zapConfig := zap.NewDevelopmentConfig() zapConfig.DisableCaller = true zapLogger, _ := zapConfig.Build() defer zapLogger.Sync() logger := zapLogger.Named("commands") - cmds := config.ErupeConfig.Commands + cmds := _config.ErupeConfig.Commands for _, cmd := range cmds { commands[cmd.Name] = cmd if cmd.Enabled { @@ -55,7 +55,7 @@ func init() { } } -func sendDisabledCommandMessage(s *Session, cmd config.Command) { +func sendDisabledCommandMessage(s *Session, cmd _config.Command) { sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandDisabled"], cmd.Name)) } @@ -211,7 +211,7 @@ func parseChatCommand(s *Session, command string) { for _, course := range mhfcourse.Courses() { for _, alias := range course.Aliases() { if strings.ToLower(name) == strings.ToLower(alias) { - if slices.Contains(s.server.erupeConfig.Courses, config.Course{Name: course.Aliases()[0], Enabled: true}) { + if slices.Contains(s.server.erupeConfig.Courses, _config.Course{Name: course.Aliases()[0], Enabled: true}) { var delta, rightsInt uint32 if mhfcourse.CourseExists(course.ID, s.courses) { ei := slices.IndexFunc(s.courses, func(c mhfcourse.Course) bool { diff --git a/server/channelserver/handlers_character.go b/server/channelserver/handlers_character.go index a53d4c42a..320d459a6 100644 --- a/server/channelserver/handlers_character.go +++ b/server/channelserver/handlers_character.go @@ -5,6 +5,7 @@ import ( "errors" "erupe-ce/common/bfutil" "erupe-ce/common/stringsupport" + _config "erupe-ce/config" "erupe-ce/network/mhfpacket" "erupe-ce/server/channelserver/compression/nullcomp" @@ -12,7 +13,8 @@ import ( ) const ( - pointerGender = 0x51 // +1 + pointerGender = 0x51 // +1 + pointerRP = 0x22D16 // +2 pointerHouseTier = 0x1FB6C // +5 pointerHouseData = 0x1FE01 // +195 @@ -26,6 +28,19 @@ const ( pointerHRP = 0x1FDF6 // +2 pointerGRP = 0x1FDFC // +4 pointerKQF = 0x23D20 // +8 + + pointerRPZ = 0x1A076 + pointerHouseTierZ = 0x16ECC + pointerHouseDataZ = 0x17161 + pointerBookshelfDataZ = 0x195F8 + pointerGalleryDataZ = 0x19680 + pointerToreDataZ = 0x17014 + pointerGardenDataZ = 0x19FB8 + pointerWeaponTypeZ = 0x16A75 + pointerWeaponIDZ = 0x1696A + pointerHRPZ = 0x17156 + pointerGRPZ = 0x1715C + pointerKQFZ = 0x1B080 ) type CharacterSaveData struct { @@ -81,10 +96,6 @@ func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error) return nil, err } - if len(saveData.decompSave) < pointerKQF { - return nil, err - } - saveData.updateStructWithSaveData() return saveData, nil @@ -137,8 +148,13 @@ func (save *CharacterSaveData) Decompress() error { func (save *CharacterSaveData) updateSaveDataWithStruct() { rpBytes := make([]byte, 2) binary.LittleEndian.PutUint16(rpBytes, save.RP) - copy(save.decompSave[pointerRP:pointerRP+2], rpBytes) - copy(save.decompSave[pointerKQF:pointerKQF+8], save.KQF) + if _config.ErupeConfig.ClientMode == _config.ZZ { + copy(save.decompSave[pointerRP:pointerRP+2], rpBytes) + copy(save.decompSave[pointerKQF:pointerKQF+8], save.KQF) + } else { + copy(save.decompSave[pointerRPZ:pointerRPZ+2], rpBytes) + copy(save.decompSave[pointerKQFZ:pointerKQFZ+8], save.KQF) + } } // This will update the save struct with the values stored in the character save @@ -150,20 +166,37 @@ func (save *CharacterSaveData) updateStructWithSaveData() { save.Gender = false } if !save.IsNewCharacter { - save.RP = binary.LittleEndian.Uint16(save.decompSave[pointerRP : pointerRP+2]) - save.HouseTier = save.decompSave[pointerHouseTier : pointerHouseTier+5] - save.HouseData = save.decompSave[pointerHouseData : pointerHouseData+195] - save.BookshelfData = save.decompSave[pointerBookshelfData : pointerBookshelfData+5576] - save.GalleryData = save.decompSave[pointerGalleryData : pointerGalleryData+1748] - save.ToreData = save.decompSave[pointerToreData : pointerToreData+240] - save.GardenData = save.decompSave[pointerGardenData : pointerGardenData+68] - save.WeaponType = save.decompSave[pointerWeaponType] - save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[pointerWeaponID : pointerWeaponID+2]) - save.HRP = binary.LittleEndian.Uint16(save.decompSave[pointerHRP : pointerHRP+2]) - if save.HRP == uint16(999) { - save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[pointerGRP : pointerGRP+4])) + if _config.ErupeConfig.ClientMode == _config.ZZ { + save.RP = binary.LittleEndian.Uint16(save.decompSave[pointerRP : pointerRP+2]) + save.HouseTier = save.decompSave[pointerHouseTier : pointerHouseTier+5] + save.HouseData = save.decompSave[pointerHouseData : pointerHouseData+195] + save.BookshelfData = save.decompSave[pointerBookshelfData : pointerBookshelfData+5576] + save.GalleryData = save.decompSave[pointerGalleryData : pointerGalleryData+1748] + save.ToreData = save.decompSave[pointerToreData : pointerToreData+240] + save.GardenData = save.decompSave[pointerGardenData : pointerGardenData+68] + save.WeaponType = save.decompSave[pointerWeaponType] + save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[pointerWeaponID : pointerWeaponID+2]) + save.HRP = binary.LittleEndian.Uint16(save.decompSave[pointerHRP : pointerHRP+2]) + if save.HRP == uint16(999) { + save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[pointerGRP : pointerGRP+4])) + } + save.KQF = save.decompSave[pointerKQF : pointerKQF+8] + } else { + save.RP = binary.LittleEndian.Uint16(save.decompSave[pointerRPZ : pointerRPZ+2]) + save.HouseTier = save.decompSave[pointerHouseTierZ : pointerHouseTierZ+5] + save.HouseData = save.decompSave[pointerHouseDataZ : pointerHouseDataZ+195] + save.BookshelfData = save.decompSave[pointerBookshelfDataZ : pointerBookshelfDataZ+5576] + save.GalleryData = save.decompSave[pointerGalleryDataZ : pointerGalleryDataZ+1748] + save.ToreData = save.decompSave[pointerToreDataZ : pointerToreDataZ+240] + save.GardenData = save.decompSave[pointerGardenDataZ : pointerGardenDataZ+68] + save.WeaponType = save.decompSave[pointerWeaponTypeZ] + save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[pointerWeaponIDZ : pointerWeaponIDZ+2]) + save.HRP = binary.LittleEndian.Uint16(save.decompSave[pointerHRPZ : pointerHRPZ+2]) + if save.HRP == uint16(999) { + save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[pointerGRPZ : pointerGRPZ+4])) + } + save.KQF = save.decompSave[pointerKQFZ : pointerKQFZ+8] } - save.KQF = save.decompSave[pointerKQF : pointerKQF+8] } return } diff --git a/server/channelserver/handlers_data.go b/server/channelserver/handlers_data.go index 64b14072c..bf8ed7a29 100644 --- a/server/channelserver/handlers_data.go +++ b/server/channelserver/handlers_data.go @@ -1,12 +1,12 @@ package channelserver import ( - "encoding/hex" "erupe-ce/common/stringsupport" "fmt" "io" "os" "path/filepath" + "time" "erupe-ce/common/byteframe" "erupe-ce/network/mhfpacket" @@ -310,43 +310,1373 @@ func handleMsgMhfLoadScenarioData(s *Session, p mhfpacket.MHFPacket) { doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } +var paperGiftData = map[uint32][]PaperGift{ + 6001: { + {11159, 1, 1, 5000}, + {11160, 1, 1, 3350}, + {11161, 1, 1, 1500}, + {11162, 1, 1, 100}, + {11163, 1, 1, 50}, + }, + 6002: { + {11159, 2, 1, 1800}, + {11160, 2, 1, 1200}, + {11161, 2, 1, 500}, + {11162, 1, 1, 50}, + {11037, 1, 1, 150}, + {11038, 1, 1, 150}, + {11044, 1, 1, 150}, + {11057, 1, 1, 150}, + {11059, 1, 1, 150}, + {11079, 1, 1, 150}, + {11098, 1, 1, 150}, + {11104, 1, 1, 150}, + {11117, 1, 1, 150}, + {11128, 1, 1, 150}, + {11133, 1, 1, 150}, + {11137, 1, 1, 150}, + {11143, 1, 1, 150}, + {11132, 1, 1, 150}, + {11039, 1, 1, 150}, + {11040, 1, 1, 150}, + {11049, 1, 1, 150}, + {11061, 1, 1, 150}, + {11063, 1, 1, 150}, + {11077, 1, 1, 150}, + {11099, 1, 1, 150}, + {11105, 1, 1, 150}, + {11129, 1, 1, 150}, + {11130, 1, 1, 150}, + {11131, 1, 1, 150}, + {11139, 1, 1, 150}, + {11145, 1, 1, 150}, + {11096, 1, 1, 150}, + {11041, 1, 1, 150}, + {11047, 1, 1, 150}, + {11054, 1, 1, 150}, + {11065, 1, 1, 150}, + {11068, 1, 1, 150}, + {11075, 1, 1, 150}, + {11100, 1, 1, 150}, + {11106, 1, 1, 150}, + {11119, 1, 1, 150}, + {11135, 1, 1, 150}, + {11136, 1, 1, 150}, + {11138, 1, 1, 150}, + {11088, 1, 1, 150}, + {10370, 1, 1, 150}, + {10368, 1, 1, 150}, + }, + 6010: { + {11159, 1, 1, 3700}, + {11160, 1, 1, 2900}, + {11161, 1, 1, 1300}, + {11453, 1, 1, 250}, + {11454, 1, 1, 250}, + {12055, 1, 1, 250}, + {12065, 1, 1, 250}, + {12058, 1, 1, 250}, + {12068, 1, 1, 250}, + {11774, 1, 1, 200}, + {11773, 1, 1, 400}, + }, + 6011: { + {11159, 1, 1, 3700}, + {11160, 1, 1, 2900}, + {11161, 1, 1, 1300}, + {11453, 1, 1, 250}, + {11454, 1, 1, 250}, + {12055, 1, 1, 250}, + {12065, 1, 1, 250}, + {12058, 1, 1, 250}, + {12068, 1, 1, 250}, + {11774, 1, 1, 200}, + {11773, 1, 1, 400}, + }, + 6012: { + {11159, 2, 1, 3500}, + {11160, 2, 1, 2900}, + {11161, 2, 1, 1300}, + {12508, 1, 1, 400}, + {11453, 1, 1, 200}, + {11454, 1, 1, 200}, + {12055, 1, 1, 200}, + {12065, 1, 1, 200}, + {12058, 1, 1, 200}, + {12068, 1, 1, 200}, + {11775, 1, 1, 400}, + {11776, 1, 1, 200}, + {11777, 1, 1, 100}, + }, + 7001: { + {11037, 1, 1, 290}, + {11038, 1, 1, 270}, + {11044, 1, 1, 270}, + {11057, 1, 1, 290}, + {11059, 1, 1, 290}, + {11079, 1, 1, 290}, + {11098, 1, 1, 280}, + {11104, 1, 1, 300}, + {11117, 1, 1, 280}, + {11128, 1, 1, 290}, + {11133, 1, 1, 290}, + {11137, 1, 1, 300}, + {11143, 1, 1, 290}, + {11132, 1, 1, 270}, + {11042, 1, 1, 47}, + {11045, 1, 1, 47}, + {11064, 1, 1, 47}, + {11062, 1, 1, 47}, + {11070, 1, 1, 48}, + {11101, 1, 1, 47}, + {11108, 1, 1, 47}, + {11109, 1, 1, 47}, + {11120, 1, 1, 47}, + {11122, 1, 1, 47}, + {11134, 1, 1, 47}, + {11141, 1, 1, 47}, + {11084, 1, 1, 47}, + {11087, 1, 1, 47}, + {11094, 1, 1, 47}, + {10374, 1, 1, 47}, + {10375, 1, 1, 47}, + {11051, 1, 1, 17}, + {11071, 1, 1, 16}, + {11076, 1, 1, 16}, + {11102, 1, 1, 17}, + {11124, 1, 1, 17}, + {11090, 1, 1, 17}, + {11159, 1, 1, 1200}, + {11159, 2, 1, 650}, + {11160, 1, 1, 800}, + {11160, 2, 1, 300}, + {11161, 1, 1, 100}, + {11161, 2, 1, 50}, + {11164, 1, 1, 100}, + {11162, 1, 1, 100}, + {11163, 1, 1, 100}, + {11158, 1, 1, 300}, + {11463, 1, 1, 300}, + {11356, 1, 1, 300}, + {11464, 1, 1, 300}, + {11357, 1, 1, 500}, + {11039, 1, 2, 300}, + {11040, 1, 2, 270}, + {11049, 1, 2, 300}, + {11061, 1, 2, 290}, + {11063, 1, 2, 290}, + {11077, 1, 2, 290}, + {11099, 1, 2, 280}, + {11105, 1, 2, 300}, + {11129, 1, 2, 250}, + {11130, 1, 2, 300}, + {11131, 1, 2, 280}, + {11139, 1, 2, 290}, + {11145, 1, 2, 260}, + {11096, 1, 2, 300}, + {11046, 1, 2, 47}, + {11066, 1, 2, 47}, + {11067, 1, 2, 47}, + {11072, 1, 2, 47}, + {11082, 1, 2, 47}, + {11103, 1, 2, 47}, + {11110, 1, 2, 47}, + {11112, 1, 2, 47}, + {11114, 1, 2, 47}, + {11115, 1, 2, 47}, + {11121, 1, 2, 47}, + {11144, 1, 2, 48}, + {11085, 1, 2, 47}, + {11089, 1, 2, 47}, + {11091, 1, 2, 47}, + {10376, 1, 2, 47}, + {10377, 1, 2, 47}, + {11127, 1, 2, 17}, + {11069, 1, 2, 17}, + {11142, 1, 2, 17}, + {11078, 1, 2, 17}, + {11056, 1, 2, 16}, + {11092, 1, 2, 16}, + {11159, 1, 2, 1200}, + {11159, 2, 2, 650}, + {11160, 1, 2, 800}, + {11160, 2, 2, 300}, + {11161, 1, 2, 100}, + {11161, 2, 2, 50}, + {11164, 1, 2, 100}, + {11162, 1, 2, 100}, + {11163, 1, 2, 100}, + {11158, 1, 2, 300}, + {11463, 1, 2, 300}, + {11356, 1, 2, 300}, + {11464, 1, 2, 300}, + {11357, 1, 2, 500}, + {11041, 1, 3, 266}, + {11047, 1, 3, 266}, + {11054, 1, 3, 266}, + {11065, 1, 3, 266}, + {11068, 1, 3, 266}, + {11075, 1, 3, 266}, + {11100, 1, 3, 266}, + {11106, 1, 3, 266}, + {11119, 1, 3, 266}, + {11135, 1, 3, 268}, + {11136, 1, 3, 268}, + {11138, 1, 3, 268}, + {11088, 1, 3, 268}, + {10370, 1, 3, 266}, + {10368, 1, 3, 268}, + {11043, 1, 3, 50}, + {11048, 1, 3, 50}, + {11050, 1, 3, 50}, + {11058, 1, 3, 50}, + {11060, 1, 3, 50}, + {11074, 1, 3, 50}, + {11107, 1, 3, 50}, + {11111, 1, 3, 50}, + {11113, 1, 3, 50}, + {11118, 1, 3, 50}, + {11126, 1, 3, 50}, + {11140, 1, 3, 50}, + {11086, 1, 3, 50}, + {11095, 1, 3, 50}, + {11055, 1, 3, 50}, + {10378, 1, 3, 50}, + {11052, 1, 3, 15}, + {11073, 1, 3, 15}, + {11146, 1, 3, 15}, + {11116, 1, 3, 15}, + {11123, 1, 3, 15}, + {11097, 1, 3, 15}, + {10367, 1, 3, 15}, + {10371, 1, 3, 15}, + {10373, 1, 3, 15}, + {10778, 1, 3, 375}, + {11209, 1, 3, 375}, + {10813, 1, 3, 375}, + {11389, 1, 3, 375}, + {11159, 1, 3, 1000}, + {11159, 2, 3, 250}, + {11160, 1, 3, 700}, + {11160, 2, 3, 175}, + {11161, 1, 3, 300}, + {11161, 2, 3, 75}, + {11465, 1, 3, 53}, + {11466, 1, 3, 27}, + {11467, 1, 3, 266}, + {11468, 1, 3, 533}, + {11469, 1, 3, 186}, + }, + 7002: { + {11037, 1, 1, 100}, + {11038, 1, 1, 100}, + {11044, 1, 1, 100}, + {11057, 1, 1, 100}, + {11059, 1, 1, 100}, + {11079, 1, 1, 100}, + {11098, 1, 1, 100}, + {11104, 1, 1, 100}, + {11117, 1, 1, 100}, + {11128, 1, 1, 100}, + {11133, 1, 1, 100}, + {11137, 1, 1, 100}, + {11143, 1, 1, 100}, + {11132, 1, 1, 100}, + {11042, 1, 1, 60}, + {11045, 1, 1, 60}, + {11064, 1, 1, 60}, + {11062, 1, 1, 60}, + {11070, 1, 1, 60}, + {11101, 1, 1, 60}, + {11108, 1, 1, 60}, + {11109, 1, 1, 60}, + {11120, 1, 1, 60}, + {11122, 1, 1, 60}, + {11134, 1, 1, 60}, + {11141, 1, 1, 60}, + {11084, 1, 1, 60}, + {11087, 1, 1, 60}, + {11094, 1, 1, 60}, + {10374, 1, 1, 60}, + {10375, 1, 1, 60}, + {11051, 1, 1, 20}, + {11071, 1, 1, 20}, + {11076, 1, 1, 20}, + {11102, 1, 1, 20}, + {11124, 1, 1, 20}, + {11090, 1, 1, 20}, + {11164, 1, 1, 400}, + {11162, 1, 1, 200}, + {11163, 1, 1, 200}, + {11463, 1, 1, 100}, + {11464, 1, 1, 150}, + {10355, 1, 1, 150}, + {12506, 1, 1, 200}, + {12507, 1, 1, 300}, + {12508, 1, 1, 900}, + {13629, 1, 1, 350}, + {13628, 1, 1, 200}, + {11356, 1, 1, 100}, + {11357, 1, 1, 150}, + {12014, 1, 1, 250}, + {12016, 1, 1, 400}, + {12015, 1, 1, 410}, + {11159, 2, 1, 500}, + {11159, 4, 1, 500}, + {11159, 6, 1, 500}, + {11160, 2, 1, 400}, + {11160, 4, 1, 400}, + {11160, 6, 1, 400}, + {11161, 2, 1, 100}, + {11161, 4, 1, 100}, + {11161, 6, 1, 100}, + {11039, 1, 2, 100}, + {11040, 1, 2, 100}, + {11049, 1, 2, 100}, + {11061, 1, 2, 100}, + {11063, 1, 2, 100}, + {11077, 1, 2, 100}, + {11099, 1, 2, 100}, + {11105, 1, 2, 100}, + {11129, 1, 2, 100}, + {11130, 1, 2, 100}, + {11131, 1, 2, 100}, + {11139, 1, 2, 100}, + {11145, 1, 2, 100}, + {11096, 1, 2, 100}, + {11046, 1, 2, 60}, + {11066, 1, 2, 60}, + {11067, 1, 2, 60}, + {11072, 1, 2, 60}, + {11082, 1, 2, 60}, + {11103, 1, 2, 60}, + {11110, 1, 2, 60}, + {11112, 1, 2, 60}, + {11114, 1, 2, 60}, + {11115, 1, 2, 60}, + {11121, 1, 2, 60}, + {11144, 1, 2, 60}, + {11085, 1, 2, 60}, + {11089, 1, 2, 60}, + {11091, 1, 2, 60}, + {10376, 1, 2, 60}, + {10377, 1, 2, 60}, + {11127, 1, 2, 20}, + {11069, 1, 2, 20}, + {11142, 1, 2, 20}, + {11078, 1, 2, 20}, + {11056, 1, 2, 20}, + {11092, 1, 2, 20}, + {11164, 1, 2, 400}, + {11162, 1, 2, 200}, + {11163, 1, 2, 200}, + {11463, 1, 2, 250}, + {11464, 1, 2, 350}, + {12506, 1, 2, 150}, + {12507, 1, 2, 200}, + {12508, 1, 2, 350}, + {13629, 1, 2, 250}, + {13628, 1, 2, 200}, + {10355, 1, 2, 400}, + {11158, 1, 2, 100}, + {11356, 1, 2, 100}, + {11357, 1, 2, 100}, + {12014, 1, 2, 300}, + {12016, 1, 2, 450}, + {12015, 1, 2, 460}, + {11159, 2, 2, 500}, + {11159, 4, 2, 500}, + {11159, 6, 2, 500}, + {11160, 2, 2, 400}, + {11160, 4, 2, 400}, + {11160, 6, 2, 400}, + {11161, 2, 2, 100}, + {11161, 4, 2, 100}, + {11161, 6, 2, 100}, + {11041, 1, 3, 120}, + {11047, 1, 3, 120}, + {11054, 1, 3, 120}, + {11065, 1, 3, 120}, + {11068, 1, 3, 120}, + {11075, 1, 3, 120}, + {11100, 1, 3, 120}, + {11106, 1, 3, 120}, + {11119, 1, 3, 120}, + {11135, 1, 3, 120}, + {11136, 1, 3, 120}, + {11138, 1, 3, 120}, + {11088, 1, 3, 120}, + {10370, 1, 3, 120}, + {10368, 1, 3, 120}, + {11043, 1, 3, 65}, + {11048, 1, 3, 65}, + {11050, 1, 3, 65}, + {11058, 1, 3, 65}, + {11060, 1, 3, 65}, + {11074, 1, 3, 65}, + {11107, 1, 3, 65}, + {11111, 1, 3, 65}, + {11113, 1, 3, 65}, + {11118, 1, 3, 65}, + {11126, 1, 3, 65}, + {11140, 1, 3, 65}, + {11086, 1, 3, 65}, + {11095, 1, 3, 65}, + {11055, 1, 3, 65}, + {10378, 1, 3, 65}, + {11052, 1, 3, 15}, + {11073, 1, 3, 15}, + {11146, 1, 3, 15}, + {11116, 1, 3, 15}, + {11123, 1, 3, 15}, + {11097, 1, 3, 15}, + {10367, 1, 3, 15}, + {10371, 1, 3, 15}, + {10373, 1, 3, 15}, + {10778, 3, 3, 490}, + {11209, 3, 3, 490}, + {10813, 3, 3, 490}, + {11389, 3, 3, 490}, + {12046, 3, 3, 500}, + {12503, 3, 3, 500}, + {11159, 2, 3, 500}, + {11159, 4, 3, 500}, + {11159, 6, 3, 500}, + {11160, 2, 3, 400}, + {11160, 4, 3, 400}, + {11160, 6, 3, 400}, + {11161, 2, 3, 100}, + {11161, 4, 3, 100}, + {11161, 6, 3, 100}, + {11465, 1, 3, 53}, + {11466, 1, 3, 27}, + {11467, 1, 3, 266}, + {11468, 1, 3, 533}, + {11469, 1, 3, 186}, + }, + 7011: { + {11037, 1, 1, 290}, + {11038, 1, 1, 270}, + {11044, 1, 1, 270}, + {11057, 1, 1, 290}, + {11059, 1, 1, 290}, + {11079, 1, 1, 290}, + {11098, 1, 1, 280}, + {11104, 1, 1, 300}, + {11117, 1, 1, 280}, + {11128, 1, 1, 290}, + {11133, 1, 1, 290}, + {11137, 1, 1, 300}, + {11143, 1, 1, 290}, + {11132, 1, 1, 270}, + {11042, 1, 1, 47}, + {11045, 1, 1, 47}, + {11064, 1, 1, 47}, + {11062, 1, 1, 47}, + {11070, 1, 1, 48}, + {11101, 1, 1, 47}, + {11108, 1, 1, 47}, + {11109, 1, 1, 47}, + {11120, 1, 1, 47}, + {11122, 1, 1, 47}, + {11134, 1, 1, 47}, + {11141, 1, 1, 47}, + {11084, 1, 1, 47}, + {11087, 1, 1, 47}, + {11094, 1, 1, 47}, + {10374, 1, 1, 47}, + {10375, 1, 1, 47}, + {11051, 1, 1, 17}, + {11071, 1, 1, 16}, + {11076, 1, 1, 16}, + {11102, 1, 1, 17}, + {11124, 1, 1, 17}, + {11090, 1, 1, 17}, + {11159, 1, 1, 1200}, + {11159, 2, 1, 650}, + {11160, 1, 1, 800}, + {11160, 2, 1, 300}, + {11161, 1, 1, 100}, + {11161, 2, 1, 50}, + {11164, 1, 1, 100}, + {11162, 1, 1, 100}, + {11163, 1, 1, 100}, + {11158, 1, 1, 300}, + {11463, 1, 1, 300}, + {11356, 1, 1, 300}, + {11464, 1, 1, 300}, + {11357, 1, 1, 500}, + {11039, 1, 2, 300}, + {11040, 1, 2, 270}, + {11049, 1, 2, 300}, + {11061, 1, 2, 290}, + {11063, 1, 2, 290}, + {11077, 1, 2, 290}, + {11099, 1, 2, 280}, + {11105, 1, 2, 300}, + {11129, 1, 2, 250}, + {11130, 1, 2, 300}, + {11131, 1, 2, 280}, + {11139, 1, 2, 290}, + {11145, 1, 2, 260}, + {11096, 1, 2, 300}, + {11046, 1, 2, 47}, + {11066, 1, 2, 47}, + {11067, 1, 2, 47}, + {11072, 1, 2, 47}, + {11082, 1, 2, 47}, + {11103, 1, 2, 47}, + {11110, 1, 2, 47}, + {11112, 1, 2, 47}, + {11114, 1, 2, 47}, + {11115, 1, 2, 47}, + {11121, 1, 2, 47}, + {11144, 1, 2, 48}, + {11085, 1, 2, 47}, + {11089, 1, 2, 47}, + {11091, 1, 2, 47}, + {10376, 1, 2, 47}, + {10377, 1, 2, 47}, + {11127, 1, 2, 17}, + {11069, 1, 2, 17}, + {11142, 1, 2, 17}, + {11078, 1, 2, 17}, + {11056, 1, 2, 16}, + {11092, 1, 2, 16}, + {11159, 1, 2, 1200}, + {11159, 2, 2, 650}, + {11160, 1, 2, 800}, + {11160, 2, 2, 300}, + {11161, 1, 2, 100}, + {11161, 2, 2, 50}, + {11164, 1, 2, 100}, + {11162, 1, 2, 100}, + {11163, 1, 2, 100}, + {11158, 1, 2, 300}, + {11463, 1, 2, 300}, + {11356, 1, 2, 300}, + {11464, 1, 2, 300}, + {11357, 1, 2, 500}, + {11041, 1, 3, 266}, + {11047, 1, 3, 266}, + {11054, 1, 3, 266}, + {11065, 1, 3, 266}, + {11068, 1, 3, 266}, + {11075, 1, 3, 266}, + {11100, 1, 3, 266}, + {11106, 1, 3, 266}, + {11119, 1, 3, 266}, + {11135, 1, 3, 268}, + {11136, 1, 3, 268}, + {11138, 1, 3, 268}, + {11088, 1, 3, 268}, + {10370, 1, 3, 266}, + {10368, 1, 3, 268}, + {11043, 1, 3, 50}, + {11048, 1, 3, 50}, + {11050, 1, 3, 50}, + {11058, 1, 3, 50}, + {11060, 1, 3, 50}, + {11074, 1, 3, 50}, + {11107, 1, 3, 50}, + {11111, 1, 3, 50}, + {11113, 1, 3, 50}, + {11118, 1, 3, 50}, + {11126, 1, 3, 50}, + {11140, 1, 3, 50}, + {11086, 1, 3, 50}, + {11095, 1, 3, 50}, + {11055, 1, 3, 50}, + {10378, 1, 3, 50}, + {11052, 1, 3, 15}, + {11073, 1, 3, 15}, + {11146, 1, 3, 15}, + {11116, 1, 3, 15}, + {11123, 1, 3, 15}, + {11097, 1, 3, 15}, + {10367, 1, 3, 15}, + {10371, 1, 3, 15}, + {10373, 1, 3, 15}, + {10778, 1, 3, 375}, + {11209, 1, 3, 375}, + {10813, 1, 3, 375}, + {11389, 1, 3, 375}, + {11159, 1, 3, 1000}, + {11159, 2, 3, 250}, + {11160, 1, 3, 700}, + {11160, 2, 3, 175}, + {11161, 1, 3, 300}, + {11161, 2, 3, 75}, + {11465, 1, 3, 53}, + {11466, 1, 3, 27}, + {11467, 1, 3, 266}, + {11468, 1, 3, 533}, + {11469, 1, 3, 186}, + }, + 7012: { + {11037, 1, 1, 290}, + {11038, 1, 1, 270}, + {11044, 1, 1, 270}, + {11057, 1, 1, 290}, + {11059, 1, 1, 290}, + {11079, 1, 1, 290}, + {11098, 1, 1, 280}, + {11104, 1, 1, 300}, + {11117, 1, 1, 280}, + {11128, 1, 1, 290}, + {11133, 1, 1, 290}, + {11137, 1, 1, 300}, + {11143, 1, 1, 290}, + {11132, 1, 1, 270}, + {11042, 1, 1, 47}, + {11045, 1, 1, 47}, + {11064, 1, 1, 47}, + {11062, 1, 1, 47}, + {11070, 1, 1, 48}, + {11101, 1, 1, 47}, + {11108, 1, 1, 47}, + {11109, 1, 1, 47}, + {11120, 1, 1, 47}, + {11122, 1, 1, 47}, + {11134, 1, 1, 47}, + {11141, 1, 1, 47}, + {11084, 1, 1, 47}, + {11087, 1, 1, 47}, + {11094, 1, 1, 47}, + {10374, 1, 1, 47}, + {10375, 1, 1, 47}, + {11051, 1, 1, 17}, + {11071, 1, 1, 16}, + {11076, 1, 1, 16}, + {11102, 1, 1, 17}, + {11124, 1, 1, 17}, + {11090, 1, 1, 17}, + {11159, 1, 1, 1200}, + {11159, 2, 1, 650}, + {11160, 1, 1, 800}, + {11160, 2, 1, 300}, + {11161, 1, 1, 100}, + {11161, 2, 1, 50}, + {11164, 1, 1, 100}, + {11162, 1, 1, 100}, + {11163, 1, 1, 100}, + {11158, 1, 1, 300}, + {11463, 1, 1, 300}, + {11356, 1, 1, 300}, + {11464, 1, 1, 300}, + {11357, 1, 1, 500}, + {11039, 1, 2, 300}, + {11040, 1, 2, 270}, + {11049, 1, 2, 300}, + {11061, 1, 2, 290}, + {11063, 1, 2, 290}, + {11077, 1, 2, 290}, + {11099, 1, 2, 280}, + {11105, 1, 2, 300}, + {11129, 1, 2, 250}, + {11130, 1, 2, 300}, + {11131, 1, 2, 280}, + {11139, 1, 2, 290}, + {11145, 1, 2, 260}, + {11096, 1, 2, 300}, + {11046, 1, 2, 47}, + {11066, 1, 2, 47}, + {11067, 1, 2, 47}, + {11072, 1, 2, 47}, + {11082, 1, 2, 47}, + {11103, 1, 2, 47}, + {11110, 1, 2, 47}, + {11112, 1, 2, 47}, + {11114, 1, 2, 47}, + {11115, 1, 2, 47}, + {11121, 1, 2, 47}, + {11144, 1, 2, 48}, + {11085, 1, 2, 47}, + {11089, 1, 2, 47}, + {11091, 1, 2, 47}, + {10376, 1, 2, 47}, + {10377, 1, 2, 47}, + {11127, 1, 2, 17}, + {11069, 1, 2, 17}, + {11142, 1, 2, 17}, + {11078, 1, 2, 17}, + {11056, 1, 2, 16}, + {11092, 1, 2, 16}, + {11159, 1, 2, 1200}, + {11159, 2, 2, 650}, + {11160, 1, 2, 800}, + {11160, 2, 2, 300}, + {11161, 1, 2, 100}, + {11161, 2, 2, 50}, + {11164, 1, 2, 100}, + {11162, 1, 2, 100}, + {11163, 1, 2, 100}, + {11158, 1, 2, 300}, + {11463, 1, 2, 300}, + {11356, 1, 2, 300}, + {11464, 1, 2, 300}, + {11357, 1, 2, 500}, + {11041, 1, 3, 266}, + {11047, 1, 3, 266}, + {11054, 1, 3, 266}, + {11065, 1, 3, 266}, + {11068, 1, 3, 266}, + {11075, 1, 3, 266}, + {11100, 1, 3, 266}, + {11106, 1, 3, 266}, + {11119, 1, 3, 266}, + {11135, 1, 3, 268}, + {11136, 1, 3, 268}, + {11138, 1, 3, 268}, + {11088, 1, 3, 268}, + {10370, 1, 3, 266}, + {10368, 1, 3, 268}, + {11043, 1, 3, 50}, + {11048, 1, 3, 50}, + {11050, 1, 3, 50}, + {11058, 1, 3, 50}, + {11060, 1, 3, 50}, + {11074, 1, 3, 50}, + {11107, 1, 3, 50}, + {11111, 1, 3, 50}, + {11113, 1, 3, 50}, + {11118, 1, 3, 50}, + {11126, 1, 3, 50}, + {11140, 1, 3, 50}, + {11086, 1, 3, 50}, + {11095, 1, 3, 50}, + {11055, 1, 3, 50}, + {10378, 1, 3, 50}, + {11052, 1, 3, 15}, + {11073, 1, 3, 15}, + {11146, 1, 3, 15}, + {11116, 1, 3, 15}, + {11123, 1, 3, 15}, + {11097, 1, 3, 15}, + {10367, 1, 3, 15}, + {10371, 1, 3, 15}, + {10373, 1, 3, 15}, + {10778, 1, 3, 375}, + {11209, 1, 3, 375}, + {10813, 1, 3, 375}, + {11389, 1, 3, 375}, + {11159, 1, 3, 1000}, + {11159, 2, 3, 250}, + {11160, 1, 3, 700}, + {11160, 2, 3, 175}, + {11161, 1, 3, 300}, + {11161, 2, 3, 75}, + {11465, 1, 3, 53}, + {11466, 1, 3, 27}, + {11467, 1, 3, 266}, + {11468, 1, 3, 533}, + {11469, 1, 3, 186}, + }, +} + +type PaperMissionTimetable struct { + Start time.Time + End time.Time +} + +type PaperMissionData struct { + Unk0 uint8 + Unk1 uint8 + Unk2 int16 + Reward1ID uint16 + Reward1Quantity uint8 + Reward2ID uint16 + Reward2Quantity uint8 +} + +type PaperMission struct { + Timetables []PaperMissionTimetable + Data []PaperMissionData +} + +type PaperData struct { + Unk0 uint16 + Unk1 int16 + Unk2 int16 + Unk3 int16 + Unk4 int16 + Unk5 int16 + Unk6 int16 +} + +type PaperGift struct { + Unk0 uint16 + Unk1 uint8 + Unk2 uint8 + Unk3 uint16 +} + func handleMsgMhfGetPaperData(s *Session, p mhfpacket.MHFPacket) { - // if the game gets bad responses for this it breaks the ability to save pkt := p.(*mhfpacket.MsgMhfGetPaperData) - var data []byte - var err error - if pkt.Unk2 == 4 { - data, err = hex.DecodeString("0A218EAD000000000000000000000000") - } else if pkt.Unk2 == 5 { - data, err = hex.DecodeString("0A218EAD00000000000000000000003403E900010000000000000000000003E900020000000000000000000003EB00010064006400C80064000003EB00020096006400F00064000003EC000A270F002800000000000003ED000A01F4000000000000000003EF00010000000000000000000003F000C801900BB801900BB8000003F200010FA0000000000000000003F200020FA0000000000000000003F3000117703A984E2061A8753003F3000217703A984E2061A8753003F400011F40445C57E46B6C791803F400021F40445C57E46B6C791803F700010010001000100000000003F7000200100010001000000000044D000107E001F4000000000000044D000207E001F4000000000000044F0001000000000BB800000BB8044F0002000000000BB800000BB804500001000A270F00280000000004500002000A270F00280000000004510001000A01F400000000000004510002000A01F400000000000007D100010011003A0000000602BC07D100010014003A0000000300C807D100010016003A0000000700FA07D10001001B003A00000001006407D100010035003A0000000803E807D100010043003A0000000901F407D100010044003A00000002009607D10001004A003A0000000400C807D10001004B003A0000000501F407D10001004C003A0000000A032007D100010050003A0000000B038407D100010059003A0000000C025807D100020011003C0000000602BC07D100020014003C0000000300C807D100020016003C00000007015E07D10002001B003C00000001006407D100020027003C0000000D00C807D100020028003C0000000F025807D100020035003C0000000803E807D100020043003C0000000201F407D100020044003C00000009009607D10002004A003C0000000400C807D10002004B003C0000000501F407D10002004C003C0000000A032007D100020050003C0000000B038407D100020051003C0000000E038407D100020059003C0000000C025807D10002005E003C0000001003E8") - } else if pkt.Unk2 == 6 { - data, err = hex.DecodeString("0A218EAD0000000000000000000001A503EA00640000000000000000000003EE00012710271000000000000003EE000227104E2000000000000003F100140000000000000000000003F5000100010001006400C8012C03F5000100010002006400C8012C03F5000100020001012C006400C803F5000100020002012C006400C803F500010003000100C8012C006403F500010003000200C8012C006403F5000200010001012C006400C803F5000200010002012C006400C803F500020002000100C8012C006403F500020002000200C8012C006403F5000200030001006400C8012C03F5000200030002006400C8012C03F500030001000100C8012C006403F500030001000200C8012C006403F5000300020001006400C8012C03F5000300020002006400C8012C03F5000300030001012C006400C803F5000300030002012C006400C803F800010001005000000000000003F800010002005000000000000003F800010003005000000000000003F800020001005000000000000003F800020002005000000000000003F800020003005000000000000004B10001003C003200000000000004B10002003C003200000000000004B200010000000500320000000004B2000100060014003C0000000004B200010015002800460000000004B200010029007800500000000004B20001007900A0005A0000000004B2000100A100FA00640000000004B2000100FB01F400640000000004B2000101F5270F00640000000004B200020000006400640000000004B20002006500C800640000000004B2000200C901F400960000000004B2000201F5270F00960000000004B3000100000005000A0000000004B300010006000A00140000000004B30001000B001E001E0000000004B30001001F003C00280000000004B30001003D007800320000000004B3000100790082003C0000000004B300010083008C00460000000004B30001008D009600500000000004B30001009700A000550000000004B3000100A100C800640000000004B3000100C901F400640000000004B3000101F5270F00640000000004B300020000007800460000000004B30002007901F400780000000004B3000201F5270F00780000000004B4000100000005000F0000000004B400010006000A00140000000004B40001000B000F00190000000004B4000100100014001B0000000004B4000100150019001E0000000004B40001001A001E00200000000004B40001001F002800230000000004B400010029003200250000000004B400010033003C00280000000004B40001003D0046002B0000000004B4000100470050002D0000000004B400010051005A002F0000000004B40001005B006400320000000004B400010065006E003C0000000004B40001006F007800460000000004B4000100790082004B0000000004B400010083008C00520000000004B40001008D00A000550000000004B4000100A100C800640000000004B4000100C901F400640000000004B4000101F5270F00640000000004B400020000007800460000000004B40002007901F400780000000004B4000201F5270F0078000000000FA10001000000000000000000000FA10002000029AB0005000000010FA10002000029AB0005000000010FA10002000029AB0005000000010FA10002000029AB0005000000010FA10002000029AC0002000000010FA10002000029AC0002000000010FA10002000029AC0002000000010FA10002000029AC0002000000010FA10002000029AD0001000000010FA10002000029AD0001000000010FA10002000029AD0001000000010FA10002000029AD0001000000010FA10002000029AF0003000000010FA10002000029AF0003000000010FA10002000029AF0003000000010FA10002000029AF0003000000010FA10002000028900001000000010FA10002000028900001000000010FA10002000029AE0002000000010FA10002000029AE0002000000010FA10002000029BA0002000000010FA10002000029BB0002000000010FA10002000029B60001000000010FA10002000029B60001000000010FA5000100002B970001138800010FA5000100002B9800010D1600010FA5000100002B99000105DC00010FA5000100002B9A0001006400010FA5000100002B9B0001003200010FA5000200002B970002070800010FA5000200002B98000204B000010FA5000200002B99000201F400010FA5000200002B9A0001003200010FA5000200002B1D0001009600010FA5000200002B1E0001009600010FA5000200002B240001009600010FA5000200002B310001009600010FA5000200002B330001009600010FA5000200002B470001009600010FA5000200002B5A0001009600010FA5000200002B600001009600010FA5000200002B6D0001009600010FA5000200002B780001009600010FA5000200002B7D0001009600010FA5000200002B810001009600010FA5000200002B870001009600010FA5000200002B7C0001009600010FA5000200002B1F0001009600010FA5000200002B200001009600010FA5000200002B290001009600010FA5000200002B350001009600010FA5000200002B370001009600010FA5000200002B450001009600010FA5000200002B5B0001009600010FA5000200002B610001009600010FA5000200002B790001009600010FA5000200002B7A0001009600010FA5000200002B7B0001009600010FA5000200002B830001009600010FA5000200002B890001009600010FA5000200002B580001009600010FA5000200002B210001009600010FA5000200002B270001009600010FA5000200002B2E0001009600010FA5000200002B390001009600010FA5000200002B3C0001009600010FA5000200002B430001009600010FA5000200002B5C0001009600010FA5000200002B620001009600010FA5000200002B6F0001009600010FA5000200002B7F0001009600010FA5000200002B800001009600010FA5000200002B820001009600010FA5000200002B500001009600010FA50002000028820001009600010FA50002000028800001009600010FA6000100002B970001138800010FA6000100002B9800010D1600010FA6000100002B99000105DC00010FA6000100002B9A0001006400010FA6000100002B9B0001003200010FA6000200002B970002070800010FA6000200002B98000204B000010FA6000200002B99000201F400010FA6000200002B9A0001003200010FA6000200002B1D0001009600010FA6000200002B1E0001009600010FA6000200002B240001009600010FA6000200002B310001009600010FA6000200002B330001009600010FA6000200002B470001009600010FA6000200002B5A0001009600010FA6000200002B600001009600010FA6000200002B6D0001009600010FA6000200002B780001009600010FA6000200002B7D0001009600010FA6000200002B810001009600010FA6000200002B870001009600010FA6000200002B7C0001009600010FA6000200002B1F0001009600010FA6000200002B200001009600010FA6000200002B290001009600010FA6000200002B350001009600010FA6000200002B370001009600010FA6000200002B450001009600010FA6000200002B5B0001009600010FA6000200002B610001009600010FA6000200002B790001009600010FA6000200002B7A0001009600010FA6000200002B7B0001009600010FA6000200002B830001009600010FA6000200002B890001009600010FA6000200002B580001009600010FA6000200002B210001009600010FA6000200002B270001009600010FA6000200002B2E0001009600010FA6000200002B390001009600010FA6000200002B3C0001009600010FA6000200002B430001009600010FA6000200002B5C0001009600010FA6000200002B620001009600010FA6000200002B6F0001009600010FA6000200002B7F0001009600010FA6000200002B800001009600010FA6000200002B820001009600010FA6000200002B500001009600010FA60002000028820001009600010FA60002000028800001009600010FA7000100002B320001004600010FA7000100002B340001004600010FA7000100002B360001004600010FA7000100002B380001004600010FA7000100002B3A0001004600010FA7000100002B6E0001004600010FA7000100002B700001004600010FA7000100002B660001004600010FA7000100002B680001004600010FA7000100002B6A0001004600010FA7000100002B220001004600010FA7000100002B230001004600010FA7000100002B420001004600010FA7000100002B840001004600010FA7000100002B3B0001004600010FA7000100002B280001004600010FA7000100002B260001004600010FA7000100002B5F0001004600010FA7000100002B630001004600010FA7000100002B640001004600010FA7000100002B710001004600010FA7000100002B7E0001004600010FA7000100002B4C0001004600010FA7000100002B4D0001004600010FA7000100002B4E0001004600010FA7000100002B4F0001004600010FA7000100002B560001004600010FA7000100002B570001004600010FA70001000028860001004600010FA70001000028870001004600010FA70001000028880001004600010FA70001000028890001004600010FA700010000288A0001004600010FA7000100002B3D0001002D00010FA7000100002B3F0001002D00010FA7000100002B410001002D00010FA7000100002B440001002D00010FA7000100002B460001002D00010FA7000100002B6C0001002D00010FA7000100002B730001002D00010FA7000100002B770001002D00010FA7000100002B860001002D00010FA7000100002B300001002D00010FA7000100002B520001002D00010FA7000100002B590001002D00010FA700010000287F0001002D00010FA70001000028830001002D00010FA70001000028850001002D00010FA7000100002B480001000F00010FA7000100002B490001000F00010FA7000100002B4B0001000F00010FA7000100002B750001000F00010FA7000100002B550001000E00010FA7000100002B2D0001000A00010FA7000100002B8B0001000A00010FA70001000028840001000500010FA70001000028810001000100010FA7000100002B9B0001009600010FA7000100002CC90001003200010FA7000100002CCA0001001900010FA7000100002CCB000100C800010FA7000100002CCC0001019000010FA7000100002CCD0001009600010FA7000100002B1D0001005C00010FA7000100002B1E0001005C00010FA7000100002B240001005C00010FA7000100002B310001005C00010FA7000100002B330001005C00010FA7000100002B470001005C00010FA7000100002B5A0001005C00010FA7000100002B600001005C00010FA7000100002B6D0001005C00010FA7000100002B7D0001005C00010FA7000100002B810001005C00010FA7000100002B870001005C00010FA7000100002B7C0001005C00010FA7000100002B1F0001005C00010FA7000100002B200001005C00010FA7000100002B290001005C00010FA7000100002B350001005C00010FA7000100002B370001005C00010FA7000100002B450001005C00010FA7000100002B5B0001005C00010FA7000100002B610001005C00010FA7000100002B790001005C00010FA7000100002B7A0001005C00010FA7000100002B7B0001005C00010FA7000100002B830001005C00010FA7000100002B890001005B00010FA7000100002B580001005B00010FA7000100002B210001005B00010FA7000100002B270001005B00010FA7000100002B2E0001005B00010FA7000100002B390001005B00010FA7000100002B3C0001005B00010FA7000100002B430001005B00010FA7000100002B5C0001005B00010FA7000100002B620001005B00010FA7000100002B6F0001005B00010FA7000100002B7F0001005B00010FA7000100002B800001005B00010FA7000100002B820001005B00010FA7000100002B500001005B00010FA70001000028820001005B00010FA70001000028800001005B00010FA7000100002B250001005B00010FA7000100002B3E0001005B00010FA7000100002B5D0001005B00010FA7000100002B650001005B00010FA7000100002B720001005B00010FA7000100002B850001005B00010FA7000100002B2B0001005B00010FA7000100002B5E0001005B00010FA7000100002B740001005B00010FA7000100002B400001005B00010FA7000100002B4A0001005B00010FA7000100002B6B0001005B00010FA7000100002B880001005B00010FA7000100002B510001005B00010FA7000100002B530001005B00010FA7000100002B540001005B00010FA7000100002B2A0001005B00010FA7000100002B670001005B00010FA7000100002B690001005B00010FA7000100002B760001005B00010FA7000100002B2F0001005B00010FA7000100002B2C0001005B00010FA7000100002B8A0001005B00010FA7000200002B320001005A00010FA7000200002B340001005A00010FA7000200002B360001005A00010FA7000200002B380001005A00010FA7000200002B3A0001005A00010FA7000200002B6E0001005A00010FA7000200002B700001005A00010FA7000200002B660001005A00010FA7000200002B680001005A00010FA7000200002B6A0001005A00010FA7000200002B220001005A00010FA7000200002B230001005A00010FA7000200002B420001005A00010FA7000200002B840001005A00010FA7000200002B3B0001005A00010FA7000200002B280001005A00010FA7000200002B260001005A00010FA7000200002B5F0001005A00010FA7000200002B630001005A00010FA7000200002B640001005A00010FA7000200002B710001005A00010FA7000200002B7E0001005A00010FA7000200002B4C0001005A00010FA7000200002B4D0001005A00010FA7000200002B4E0001005A00010FA7000200002B4F0001005A00010FA7000200002B560001005A00010FA7000200002B570001005A00010FA70002000028860001005A00010FA70002000028870001005A00010FA70002000028880001005A00010FA70002000028890001005A00010FA700020000288A0001005A00010FA7000200002B3D0001005000010FA7000200002B3F0001005000010FA7000200002B410001005000010FA7000200002B440001005000010FA7000200002B460001005000010FA7000200002B6C0001005000010FA7000200002B730001005000010FA7000200002B770001005000010FA7000200002B860001005000010FA7000200002B300001005000010FA7000200002B520001005000010FA7000200002B590001005000010FA700020000287F0001005000010FA70002000028830001005000010FA70002000028850001005000010FA7000200002B480001001600010FA7000200002B490001001600010FA7000200002B4B0001001600010FA7000200002B750001001600010FA7000200002B550001001600010FA7000200002B2D0001000F00010FA7000200002B8B0001000F00010FA70002000028840001000800010FA70002000028810001000200010FA7000200002B97000304C400010FA7000200002B980003028A00010FA7000200002B99000300A000010FA7000200002D8D0001032000010FA7000200002D8E0001032000010FA7000200002B9B000101F400010FA7000200002B9A0001022600010FA7000200002CC90001003200010FA7000200002CCA0001001900010FA7000200002CCB000100FA00010FA7000200002CCC000101F400010FA7000200002CCD000100AF0001106A000100002B9B000117700001106A000100002CC9000100C80001106A000100002CCA000100640001106A000100002CCB000103E80001106A000100002CCC000107D00001106A000100002CCD000102BC0001106A000200002D8D000103200001106A000200002D8E000103200001106A000200002B9B000101900001106A000200002CC9000101900001106A000200002CCA000100C80001106A000200002CCB000107D00001106A000200002CCC00010FA00001106A000200002CCD000105780001") - } else if pkt.Unk2 == 6001 { - data, err = hex.DecodeString("0A218EAD0000000000000000000000052B97010113882B9801010D162B99010105DC2B9A010100642B9B01010032") - } else if pkt.Unk2 == 6002 { - data, err = hex.DecodeString("0A218EAD00000000000000000000002F2B97020107082B98020104B02B99020101F42B9A010100322B1D010100962B1E010100962B24010100962B31010100962B33010100962B47010100962B5A010100962B60010100962B6D010100962B78010100962B7D010100962B81010100962B87010100962B7C010100962B1F010100962B20010100962B29010100962B35010100962B37010100962B45010100962B5B010100962B61010100962B79010100962B7A010100962B7B010100962B83010100962B89010100962B58010100962B21010100962B27010100962B2E010100962B39010100962B3C010100962B43010100962B5C010100962B62010100962B6F010100962B7F010100962B80010100962B82010100962B5001010096288201010096288001010096") - } else if pkt.Unk2 == 6010 { - data, err = hex.DecodeString("0A218EAD00000000000000000000000B2B9701010E742B9801010B542B99010105142CBD010100FA2CBE010100FA2F17010100FA2F21010100FA2F1A010100FA2F24010100FA2DFE010100C82DFD01010190") - } else if pkt.Unk2 == 6011 { - data, err = hex.DecodeString("0A218EAD00000000000000000000000B2B9701010E742B9801010B542B99010105142CBD010100FA2CBE010100FA2F17010100FA2F21010100FA2F1A010100FA2F24010100FA2DFE010100C82DFD01010190") - } else if pkt.Unk2 == 6012 { - data, err = hex.DecodeString("0A218EAD00000000000000000000000D2B9702010DAC2B9802010B542B990201051430DC010101902CBD010100C82CBE010100C82F17010100C82F21010100C82F1A010100C82F24010100C82DFF010101902E00010100C82E0101010064") - } else if pkt.Unk2 == 7001 { - data, err = hex.DecodeString("0A218EAD00000000000000000000009D2B1D010101222B1E0101010E2B240101010E2B31010101222B33010101222B47010101222B5A010101182B600101012C2B6D010101182B78010101222B7D010101222B810101012C2B87010101222B7C0101010E2B220101002F2B250101002F2B380101002F2B360101002F2B3E010100302B5D0101002F2B640101002F2B650101002F2B700101002F2B720101002F2B7E0101002F2B850101002F2B4C0101002F2B4F0101002F2B560101002F28860101002F28870101002F2B2B010100112B3F010100102B44010100102B5E010100112B74010100112B52010100112B97010104B02B970201028A2B98010103202B980201012C2B99010100642B99020100322B9C010100642B9A010100642B9B010100642B960101012C2CC70101012C2C5C0101012C2CC80101012C2C5D010101F42B1F0102012C2B200102010E2B290102012C2B35010201222B37010201222B45010201222B5B010201182B610102012C2B79010200FA2B7A0102012C2B7B010201182B83010201222B89010201042B580102012C2B260102002F2B3A0102002F2B3B0102002F2B400102002F2B4A0102002F2B5F0102002F2B660102002F2B680102002F2B6A0102002F2B6B0102002F2B710102002F2B88010200302B4D0102002F2B510102002F2B530102002F28880102002F28890102002F2B77010200112B3D010200112B86010200112B46010200112B30010200102B54010200102B97010204B02B970202028A2B98010203202B980202012C2B99010200642B99020200322B9C010200642B9A010200642B9B010200642B960102012C2CC70102012C2C5C0102012C2CC80102012C2C5D010201F42B210103010A2B270103010A2B2E0103010A2B390103010A2B3C0103010A2B430103010A2B5C0103010A2B620103010A2B6F0103010A2B7F0103010C2B800103010C2B820103010C2B500103010C28820103010A28800103010C2B23010300322B28010300322B2A010300322B32010300322B34010300322B42010300322B63010300322B67010300322B69010300322B6E010300322B76010300322B84010300322B4E010300322B57010300322B2F01030032288A010300322B2C0103000F2B410103000F2B8A0103000F2B6C0103000F2B730103000F2B590103000F287F0103000F28830103000F28850103000F2A1A010301772BC9010301772A3D010301772C7D010301772B97010303E82B97020300FA2B98010302BC2B98020300AF2B990103012C2B990203004B2CC9010300352CCA0103001B2CCB0103010A2CCC010302152CCD010300BA") - } else if pkt.Unk2 == 7002 { - data, err = hex.DecodeString("0A218EAD0000000000000000000000B92B1D010100642B1E010100642B24010100642B31010100642B33010100642B47010100642B5A010100642B60010100642B6D010100642B78010100642B7D010100642B81010100642B87010100642B7C010100642B220101003C2B250101003C2B380101003C2B360101003C2B3E0101003C2B5D0101003C2B640101003C2B650101003C2B700101003C2B720101003C2B7E0101003C2B850101003C2B4C0101003C2B4F0101003C2B560101003C28860101003C28870101003C2B2B010100142B3F010100142B44010100142B5E010100142B74010100142B52010100142B9C010101902B9A010100C82B9B010100C82CC7010100642CC80101009628730101009630DA010100C830DB0101012C30DC01010384353D0101015E353C010100C82C5C010100642C5D010100962EEE010100FA2EF0010101902EEF0101019A2B97020101F42B97040101F42B97060101F42B98020101902B98040101902B98060101902B99020100642B99040100642B99060100642B1F010200642B20010200642B29010200642B35010200642B37010200642B45010200642B5B010200642B61010200642B79010200642B7A010200642B7B010200642B83010200642B89010200642B58010200642B260102003C2B3A0102003C2B3B0102003C2B400102003C2B4A0102003C2B5F0102003C2B660102003C2B680102003C2B6A0102003C2B6B0102003C2B710102003C2B880102003C2B4D0102003C2B510102003C2B530102003C28880102003C28890102003C2B77010200142B3D010200142B86010200142B46010200142B30010200142B54010200142B9C010201902B9A010200C82B9B010200C82CC7010200FA2CC80102015E30DA0102009630DB010200C830DC0102015E353D010200FA353C010200C82873010201902B96010200642C5C010200642C5D010200642EEE0102012C2EF0010201C22EEF010201CC2B97020201F42B97040201F42B97060201F42B98020201902B98040201902B98060201902B99020200642B99040200642B99060200642B21010300782B27010300782B2E010300782B39010300782B3C010300782B43010300782B5C010300782B62010300782B6F010300782B7F010300782B80010300782B82010300782B50010300782882010300782880010300782B23010300412B28010300412B2A010300412B32010300412B34010300412B42010300412B63010300412B67010300412B69010300412B6E010300412B76010300412B84010300412B4E010300412B57010300412B2F01030041288A010300412B2C0103000F2B410103000F2B8A0103000F2B6C0103000F2B730103000F2B590103000F287F0103000F28830103000F28850103000F2A1A030301EA2BC9030301EA2A3D030301EA2C7D030301EA2F0E030301F430D7030301F42B97020301F42B97040301F42B97060301F42B98020301902B98040301902B98060301902B99020300642B99040300642B99060300642CC9010300352CCA0103001B2CCB0103010A2CCC010302152CCD010300BA") - } else if pkt.Unk2 == 7011 { - data, err = hex.DecodeString("0A218EAD00000000000000000000009D2B1D010101222B1E0101010E2B240101010E2B31010101222B33010101222B47010101222B5A010101182B600101012C2B6D010101182B78010101222B7D010101222B810101012C2B87010101222B7C0101010E2B220101002F2B250101002F2B380101002F2B360101002F2B3E010100302B5D0101002F2B640101002F2B650101002F2B700101002F2B720101002F2B7E0101002F2B850101002F2B4C0101002F2B4F0101002F2B560101002F28860101002F28870101002F2B2B010100112B3F010100102B44010100102B5E010100112B74010100112B52010100112B97010104B02B970201028A2B98010103202B980201012C2B99010100642B99020100322B9C010100642B9A010100642B9B010100642B960101012C2CC70101012C2C5C0101012C2CC80101012C2C5D010101F42B1F0102012C2B200102010E2B290102012C2B35010201222B37010201222B45010201222B5B010201182B610102012C2B79010200FA2B7A0102012C2B7B010201182B83010201222B89010201042B580102012C2B260102002F2B3A0102002F2B3B0102002F2B400102002F2B4A0102002F2B5F0102002F2B660102002F2B680102002F2B6A0102002F2B6B0102002F2B710102002F2B88010200302B4D0102002F2B510102002F2B530102002F28880102002F28890102002F2B77010200112B3D010200112B86010200112B46010200112B30010200102B54010200102B97010204B02B970202028A2B98010203202B980202012C2B99010200642B99020200322B9C010200642B9A010200642B9B010200642B960102012C2CC70102012C2C5C0102012C2CC80102012C2C5D010201F42B210103010A2B270103010A2B2E0103010A2B390103010A2B3C0103010A2B430103010A2B5C0103010A2B620103010A2B6F0103010A2B7F0103010C2B800103010C2B820103010C2B500103010C28820103010A28800103010C2B23010300322B28010300322B2A010300322B32010300322B34010300322B42010300322B63010300322B67010300322B69010300322B6E010300322B76010300322B84010300322B4E010300322B57010300322B2F01030032288A010300322B2C0103000F2B410103000F2B8A0103000F2B6C0103000F2B730103000F2B590103000F287F0103000F28830103000F28850103000F2A1A010301772BC9010301772A3D010301772C7D010301772B97010303E82B97020300FA2B98010302BC2B98020300AF2B990103012C2B990203004B2CC9010300352CCA0103001B2CCB0103010A2CCC010302152CCD010300BA") - } else if pkt.Unk2 == 7012 { - data, err = hex.DecodeString("0A218EAD00000000000000000000009D2B1D010101222B1E0101010E2B240101010E2B31010101222B33010101222B47010101222B5A010101182B600101012C2B6D010101182B78010101222B7D010101222B810101012C2B87010101222B7C0101010E2B220101002F2B250101002F2B380101002F2B360101002F2B3E010100302B5D0101002F2B640101002F2B650101002F2B700101002F2B720101002F2B7E0101002F2B850101002F2B4C0101002F2B4F0101002F2B560101002F28860101002F28870101002F2B2B010100112B3F010100102B44010100102B5E010100112B74010100112B52010100112B97010104B02B970201028A2B98010103202B980201012C2B99010100642B99020100322B9C010100642B9A010100642B9B010100642B960101012C2CC70101012C2C5C0101012C2CC80101012C2C5D010101F42B1F0102012C2B200102010E2B290102012C2B35010201222B37010201222B45010201222B5B010201182B610102012C2B79010200FA2B7A0102012C2B7B010201182B83010201222B89010201042B580102012C2B260102002F2B3A0102002F2B3B0102002F2B400102002F2B4A0102002F2B5F0102002F2B660102002F2B680102002F2B6A0102002F2B6B0102002F2B710102002F2B88010200302B4D0102002F2B510102002F2B530102002F28880102002F28890102002F2B77010200112B3D010200112B86010200112B46010200112B30010200102B54010200102B97010204B02B970202028A2B98010203202B980202012C2B99010200642B99020200322B9C010200642B9A010200642B9B010200642B960102012C2CC70102012C2C5C0102012C2CC80102012C2C5D010201F42B210103010A2B270103010A2B2E0103010A2B390103010A2B3C0103010A2B430103010A2B5C0103010A2B620103010A2B6F0103010A2B7F0103010C2B800103010C2B820103010C2B500103010C28820103010A28800103010C2B23010300322B28010300322B2A010300322B32010300322B34010300322B42010300322B63010300322B67010300322B69010300322B6E010300322B76010300322B84010300322B4E010300322B57010300322B2F01030032288A010300322B2C0103000F2B410103000F2B8A0103000F2B6C0103000F2B730103000F2B590103000F287F0103000F28830103000F28850103000F2A1A010301772BC9010301772A3D010301772C7D010301772B97010303E82B97020300FA2B98010302BC2B98020300AF2B990103012C2B990203004B2CC9010300352CCA0103001B2CCB0103010A2CCC010302152CCD010300BA") + var data []*byteframe.ByteFrame + + var paperData []PaperData + var paperMissions PaperMission + var paperGift []PaperGift + + switch pkt.Unk2 { + case 0: + paperMissions = PaperMission{ + []PaperMissionTimetable{{TimeMidnight(), TimeMidnight().Add(24 * time.Hour)}}, + []PaperMissionData{}, + } + case 5: + paperData = []PaperData{ + // getTowerQuestTowerLevel + {1001, 1, 0, 0, 0, 0, 0}, + {1001, 2, 0, 0, 0, 0, 0}, + // iniTQT + {1003, 1, 100, 100, 200, 100, 0}, + {1003, 2, 150, 100, 240, 100, 0}, + {1004, 10, 9999, 40, 0, 0, 0}, + {1005, 10, 500, 0, 0, 0, 0}, + // getPaperDataSetFromProp + {1007, 1, 0, 0, 0, 0, 0}, + {1008, 200, 400, 3000, 400, 3000, 0}, + // getPaperDataSetParam1 / Dure Goal + {1010, 1, 4000, 0, 0, 0, 0}, + {1010, 2, 4000, 0, 0, 0, 0}, + // update_disp_flag / getPaperDataSetParam1 + {1011, 1, 6000, 15000, 20000, 25000, 30000}, + {1011, 2, 6000, 15000, 20000, 25000, 30000}, + {1012, 1, 8000, 17500, 22500, 27500, 31000}, + {1012, 2, 8000, 17500, 22500, 27500, 31000}, + // setServerZako + {1015, 1, 16, 16, 16, 0, 0}, + {1015, 2, 16, 16, 16, 0, 0}, + // createTowerFloorRandomNumberArray + {1101, 1, 2016, 500, 0, 0, 0}, + {1101, 2, 2016, 500, 0, 0, 0}, + // HRP/SRP/GRP/GSRP/TRP reward + {1103, 1, 0, 0, 3000, 0, 3000}, + {1103, 2, 0, 0, 3000, 0, 3000}, + // getTowerNextVenomLevel + {1104, 1, 10, 9999, 40, 0, 0}, + {1104, 2, 10, 9999, 40, 0, 0}, + {1105, 1, 10, 500, 0, 0, 0}, + {1105, 2, 10, 500, 0, 0, 0}, + // setServerBoss + {2001, 1, 17, 58, 0, 6, 700}, + {2001, 1, 20, 58, 0, 3, 200}, + {2001, 1, 22, 58, 0, 7, 250}, + {2001, 1, 27, 58, 0, 1, 100}, + {2001, 1, 53, 58, 0, 8, 1000}, + {2001, 1, 67, 58, 0, 9, 500}, + {2001, 1, 68, 58, 0, 2, 150}, + {2001, 1, 74, 58, 0, 4, 200}, + {2001, 1, 75, 58, 0, 5, 500}, + {2001, 1, 76, 58, 0, 10, 800}, + {2001, 1, 80, 58, 0, 11, 900}, + {2001, 1, 89, 58, 0, 12, 600}, + {2001, 2, 17, 60, 0, 6, 700}, + {2001, 2, 20, 60, 0, 3, 200}, + {2001, 2, 22, 60, 0, 7, 350}, + {2001, 2, 27, 60, 0, 1, 100}, + {2001, 2, 39, 60, 0, 13, 200}, + {2001, 2, 40, 60, 0, 15, 600}, + {2001, 2, 53, 60, 0, 8, 1000}, + {2001, 2, 67, 60, 0, 2, 500}, + {2001, 2, 68, 60, 0, 9, 150}, + {2001, 2, 74, 60, 0, 4, 200}, + {2001, 2, 75, 60, 0, 5, 500}, + {2001, 2, 76, 60, 0, 10, 800}, + {2001, 2, 80, 60, 0, 11, 900}, + {2001, 2, 81, 60, 0, 14, 900}, + {2001, 2, 89, 60, 0, 12, 600}, + {2001, 2, 94, 60, 0, 16, 1000}, + } + case 6: + paperData = []PaperData{ + // updateClearTowerFloor + {1002, 100, 0, 0, 0, 0, 0}, + // give_gem_func + {1006, 1, 10000, 10000, 0, 0, 0}, + {1006, 2, 10000, 20000, 0, 0, 0}, + {1009, 20, 0, 0, 0, 0, 0}, + // ttcStageInitDRP + {1013, 1, 1, 1, 100, 200, 300}, + {1013, 1, 1, 2, 100, 200, 300}, + {1013, 1, 2, 1, 300, 100, 200}, + {1013, 1, 2, 2, 300, 100, 200}, + {1013, 1, 3, 1, 200, 300, 100}, + {1013, 1, 3, 2, 200, 300, 100}, + {1013, 2, 1, 1, 300, 100, 200}, + {1013, 2, 1, 2, 300, 100, 200}, + {1013, 2, 2, 1, 200, 300, 100}, + {1013, 2, 2, 2, 200, 300, 100}, + {1013, 2, 3, 1, 100, 200, 300}, + {1013, 2, 3, 2, 100, 200, 300}, + {1013, 3, 1, 1, 200, 300, 100}, + {1013, 3, 1, 2, 200, 300, 100}, + {1013, 3, 2, 1, 100, 200, 300}, + {1013, 3, 2, 2, 100, 200, 300}, + {1013, 3, 3, 1, 300, 100, 200}, + {1013, 3, 3, 2, 300, 100, 200}, + {1016, 1, 1, 80, 0, 0, 0}, + {1016, 1, 2, 80, 0, 0, 0}, + {1016, 1, 3, 80, 0, 0, 0}, + {1016, 2, 1, 80, 0, 0, 0}, + {1016, 2, 2, 80, 0, 0, 0}, + {1016, 2, 3, 80, 0, 0, 0}, + {1201, 1, 60, 50, 0, 0, 0}, + {1201, 2, 60, 50, 0, 0, 0}, + // Gimmick Damage {ID, Block, StartFloor, EndFloor, Multiplier*100, Unk, Unk} + {1202, 1, 0, 5, 50, 0, 0}, + {1202, 1, 6, 20, 60, 0, 0}, + {1202, 1, 21, 40, 70, 0, 0}, + {1202, 1, 41, 120, 80, 0, 0}, + {1202, 1, 121, 160, 90, 0, 0}, + {1202, 1, 161, 250, 100, 0, 0}, + {1202, 1, 251, 500, 100, 0, 0}, + {1202, 1, 501, 9999, 100, 0, 0}, + {1202, 2, 0, 100, 100, 0, 0}, + {1202, 2, 101, 200, 100, 0, 0}, + {1202, 2, 201, 500, 150, 0, 0}, + {1202, 2, 501, 9999, 150, 0, 0}, + // Mon Damage {ID, Block, StartFloor, EndFloor, Multiplier*100, Unk, Unk} + {1203, 1, 0, 5, 10, 0, 0}, + {1203, 1, 6, 10, 20, 0, 0}, + {1203, 1, 11, 30, 30, 0, 0}, + {1203, 1, 31, 60, 40, 0, 0}, + {1203, 1, 61, 120, 50, 0, 0}, + {1203, 1, 121, 130, 60, 0, 0}, + {1203, 1, 131, 140, 70, 0, 0}, + {1203, 1, 141, 150, 80, 0, 0}, + {1203, 1, 151, 160, 85, 0, 0}, + {1203, 1, 161, 200, 100, 0, 0}, + {1203, 1, 201, 500, 100, 0, 0}, + {1203, 1, 501, 9999, 100, 0, 0}, + {1203, 2, 0, 120, 70, 0, 0}, + {1203, 2, 121, 500, 120, 0, 0}, + {1203, 2, 501, 9999, 120, 0, 0}, + // Mon HP {ID, Block, StartFloor, EndFloor, Multiplier*100, Unk, Unk} + {1204, 1, 0, 5, 15, 0, 0}, + {1204, 1, 6, 10, 20, 0, 0}, + {1204, 1, 11, 15, 25, 0, 0}, + {1204, 1, 16, 20, 27, 0, 0}, + {1204, 1, 21, 25, 30, 0, 0}, + {1204, 1, 26, 30, 32, 0, 0}, + {1204, 1, 31, 40, 35, 0, 0}, + {1204, 1, 41, 50, 37, 0, 0}, + {1204, 1, 51, 60, 40, 0, 0}, + {1204, 1, 61, 70, 43, 0, 0}, + {1204, 1, 71, 80, 45, 0, 0}, + {1204, 1, 81, 90, 47, 0, 0}, + {1204, 1, 91, 100, 50, 0, 0}, + {1204, 1, 101, 110, 60, 0, 0}, + {1204, 1, 111, 120, 70, 0, 0}, + {1204, 1, 121, 130, 75, 0, 0}, + {1204, 1, 131, 140, 82, 0, 0}, + {1204, 1, 141, 160, 85, 0, 0}, + {1204, 1, 161, 200, 100, 0, 0}, + {1204, 1, 201, 500, 100, 0, 0}, + {1204, 1, 501, 9999, 100, 0, 0}, + {1204, 2, 0, 120, 70, 0, 0}, + {1204, 2, 121, 500, 120, 0, 0}, + {1204, 2, 501, 9999, 120, 0, 0}, + // Supply Items {ID, Block, Unk, ItemID, Quantity, Unk, Unk} + {4001, 1, 0, 0, 0, 0, 0}, + {4001, 2, 0, 10667, 5, 0, 1}, + {4001, 2, 0, 10667, 5, 0, 1}, + {4001, 2, 0, 10667, 5, 0, 1}, + {4001, 2, 0, 10667, 5, 0, 1}, + {4001, 2, 0, 10668, 2, 0, 1}, + {4001, 2, 0, 10668, 2, 0, 1}, + {4001, 2, 0, 10668, 2, 0, 1}, + {4001, 2, 0, 10668, 2, 0, 1}, + {4001, 2, 0, 10669, 1, 0, 1}, + {4001, 2, 0, 10669, 1, 0, 1}, + {4001, 2, 0, 10669, 1, 0, 1}, + {4001, 2, 0, 10669, 1, 0, 1}, + {4001, 2, 0, 10671, 3, 0, 1}, + {4001, 2, 0, 10671, 3, 0, 1}, + {4001, 2, 0, 10671, 3, 0, 1}, + {4001, 2, 0, 10671, 3, 0, 1}, + {4001, 2, 0, 10384, 1, 0, 1}, + {4001, 2, 0, 10384, 1, 0, 1}, + {4001, 2, 0, 10670, 2, 0, 1}, + {4001, 2, 0, 10670, 2, 0, 1}, + {4001, 2, 0, 10682, 2, 0, 1}, + {4001, 2, 0, 10683, 2, 0, 1}, + {4001, 2, 0, 10678, 1, 0, 1}, + {4001, 2, 0, 10678, 1, 0, 1}, + // Item Rewards {ID, Block, Unk, ItemID, Quantity?, Chance*100, Unk} + {4005, 1, 0, 11159, 1, 5000, 1}, + {4005, 1, 0, 11160, 1, 3350, 1}, + {4005, 1, 0, 11161, 1, 1500, 1}, + {4005, 1, 0, 11162, 1, 100, 1}, + {4005, 1, 0, 11163, 1, 50, 1}, + {4005, 2, 0, 11159, 2, 1800, 1}, + {4005, 2, 0, 11160, 2, 1200, 1}, + {4005, 2, 0, 11161, 2, 500, 1}, + {4005, 2, 0, 11162, 1, 50, 1}, + {4005, 2, 0, 11037, 1, 150, 1}, + {4005, 2, 0, 11038, 1, 150, 1}, + {4005, 2, 0, 11044, 1, 150, 1}, + {4005, 2, 0, 11057, 1, 150, 1}, + {4005, 2, 0, 11059, 1, 150, 1}, + {4005, 2, 0, 11079, 1, 150, 1}, + {4005, 2, 0, 11098, 1, 150, 1}, + {4005, 2, 0, 11104, 1, 150, 1}, + {4005, 2, 0, 11117, 1, 150, 1}, + {4005, 2, 0, 11128, 1, 150, 1}, + {4005, 2, 0, 11133, 1, 150, 1}, + {4005, 2, 0, 11137, 1, 150, 1}, + {4005, 2, 0, 11143, 1, 150, 1}, + {4005, 2, 0, 11132, 1, 150, 1}, + {4005, 2, 0, 11039, 1, 150, 1}, + {4005, 2, 0, 11040, 1, 150, 1}, + {4005, 2, 0, 11049, 1, 150, 1}, + {4005, 2, 0, 11061, 1, 150, 1}, + {4005, 2, 0, 11063, 1, 150, 1}, + {4005, 2, 0, 11077, 1, 150, 1}, + {4005, 2, 0, 11099, 1, 150, 1}, + {4005, 2, 0, 11105, 1, 150, 1}, + {4005, 2, 0, 11129, 1, 150, 1}, + {4005, 2, 0, 11130, 1, 150, 1}, + {4005, 2, 0, 11131, 1, 150, 1}, + {4005, 2, 0, 11139, 1, 150, 1}, + {4005, 2, 0, 11145, 1, 150, 1}, + {4005, 2, 0, 11096, 1, 150, 1}, + {4005, 2, 0, 11041, 1, 150, 1}, + {4005, 2, 0, 11047, 1, 150, 1}, + {4005, 2, 0, 11054, 1, 150, 1}, + {4005, 2, 0, 11065, 1, 150, 1}, + {4005, 2, 0, 11068, 1, 150, 1}, + {4005, 2, 0, 11075, 1, 150, 1}, + {4005, 2, 0, 11100, 1, 150, 1}, + {4005, 2, 0, 11106, 1, 150, 1}, + {4005, 2, 0, 11119, 1, 150, 1}, + {4005, 2, 0, 11135, 1, 150, 1}, + {4005, 2, 0, 11136, 1, 150, 1}, + {4005, 2, 0, 11138, 1, 150, 1}, + {4005, 2, 0, 11088, 1, 150, 1}, + {4005, 2, 0, 10370, 1, 150, 1}, + {4005, 2, 0, 10368, 1, 150, 1}, + {4006, 1, 0, 11159, 1, 5000, 1}, + {4006, 1, 0, 11160, 1, 3350, 1}, + {4006, 1, 0, 11161, 1, 1500, 1}, + {4006, 1, 0, 11162, 1, 100, 1}, + {4006, 1, 0, 11163, 1, 50, 1}, + {4006, 2, 0, 11159, 2, 1800, 1}, + {4006, 2, 0, 11160, 2, 1200, 1}, + {4006, 2, 0, 11161, 2, 500, 1}, + {4006, 2, 0, 11162, 1, 50, 1}, + {4006, 2, 0, 11037, 1, 150, 1}, + {4006, 2, 0, 11038, 1, 150, 1}, + {4006, 2, 0, 11044, 1, 150, 1}, + {4006, 2, 0, 11057, 1, 150, 1}, + {4006, 2, 0, 11059, 1, 150, 1}, + {4006, 2, 0, 11079, 1, 150, 1}, + {4006, 2, 0, 11098, 1, 150, 1}, + {4006, 2, 0, 11104, 1, 150, 1}, + {4006, 2, 0, 11117, 1, 150, 1}, + {4006, 2, 0, 11128, 1, 150, 1}, + {4006, 2, 0, 11133, 1, 150, 1}, + {4006, 2, 0, 11137, 1, 150, 1}, + {4006, 2, 0, 11143, 1, 150, 1}, + {4006, 2, 0, 11132, 1, 150, 1}, + {4006, 2, 0, 11039, 1, 150, 1}, + {4006, 2, 0, 11040, 1, 150, 1}, + {4006, 2, 0, 11049, 1, 150, 1}, + {4006, 2, 0, 11061, 1, 150, 1}, + {4006, 2, 0, 11063, 1, 150, 1}, + {4006, 2, 0, 11077, 1, 150, 1}, + {4006, 2, 0, 11099, 1, 150, 1}, + {4006, 2, 0, 11105, 1, 150, 1}, + {4006, 2, 0, 11129, 1, 150, 1}, + {4006, 2, 0, 11130, 1, 150, 1}, + {4006, 2, 0, 11131, 1, 150, 1}, + {4006, 2, 0, 11139, 1, 150, 1}, + {4006, 2, 0, 11145, 1, 150, 1}, + {4006, 2, 0, 11096, 1, 150, 1}, + {4006, 2, 0, 11041, 1, 150, 1}, + {4006, 2, 0, 11047, 1, 150, 1}, + {4006, 2, 0, 11054, 1, 150, 1}, + {4006, 2, 0, 11065, 1, 150, 1}, + {4006, 2, 0, 11068, 1, 150, 1}, + {4006, 2, 0, 11075, 1, 150, 1}, + {4006, 2, 0, 11100, 1, 150, 1}, + {4006, 2, 0, 11106, 1, 150, 1}, + {4006, 2, 0, 11119, 1, 150, 1}, + {4006, 2, 0, 11135, 1, 150, 1}, + {4006, 2, 0, 11136, 1, 150, 1}, + {4006, 2, 0, 11138, 1, 150, 1}, + {4006, 2, 0, 11088, 1, 150, 1}, + {4006, 2, 0, 10370, 1, 150, 1}, + {4006, 2, 0, 10368, 1, 150, 1}, + {4007, 1, 0, 11058, 1, 70, 1}, + {4007, 1, 0, 11060, 1, 70, 1}, + {4007, 1, 0, 11062, 1, 70, 1}, + {4007, 1, 0, 11064, 1, 70, 1}, + {4007, 1, 0, 11066, 1, 70, 1}, + {4007, 1, 0, 11118, 1, 70, 1}, + {4007, 1, 0, 11120, 1, 70, 1}, + {4007, 1, 0, 11110, 1, 70, 1}, + {4007, 1, 0, 11112, 1, 70, 1}, + {4007, 1, 0, 11114, 1, 70, 1}, + {4007, 1, 0, 11042, 1, 70, 1}, + {4007, 1, 0, 11043, 1, 70, 1}, + {4007, 1, 0, 11074, 1, 70, 1}, + {4007, 1, 0, 11140, 1, 70, 1}, + {4007, 1, 0, 11067, 1, 70, 1}, + {4007, 1, 0, 11048, 1, 70, 1}, + {4007, 1, 0, 11046, 1, 70, 1}, + {4007, 1, 0, 11103, 1, 70, 1}, + {4007, 1, 0, 11107, 1, 70, 1}, + {4007, 1, 0, 11108, 1, 70, 1}, + {4007, 1, 0, 11121, 1, 70, 1}, + {4007, 1, 0, 11134, 1, 70, 1}, + {4007, 1, 0, 11084, 1, 70, 1}, + {4007, 1, 0, 11085, 1, 70, 1}, + {4007, 1, 0, 11086, 1, 70, 1}, + {4007, 1, 0, 11087, 1, 70, 1}, + {4007, 1, 0, 11094, 1, 70, 1}, + {4007, 1, 0, 11095, 1, 70, 1}, + {4007, 1, 0, 10374, 1, 70, 1}, + {4007, 1, 0, 10375, 1, 70, 1}, + {4007, 1, 0, 10376, 1, 70, 1}, + {4007, 1, 0, 10377, 1, 70, 1}, + {4007, 1, 0, 10378, 1, 70, 1}, + {4007, 1, 0, 11069, 1, 45, 1}, + {4007, 1, 0, 11071, 1, 45, 1}, + {4007, 1, 0, 11073, 1, 45, 1}, + {4007, 1, 0, 11076, 1, 45, 1}, + {4007, 1, 0, 11078, 1, 45, 1}, + {4007, 1, 0, 11116, 1, 45, 1}, + {4007, 1, 0, 11123, 1, 45, 1}, + {4007, 1, 0, 11127, 1, 45, 1}, + {4007, 1, 0, 11142, 1, 45, 1}, + {4007, 1, 0, 11056, 1, 45, 1}, + {4007, 1, 0, 11090, 1, 45, 1}, + {4007, 1, 0, 11097, 1, 45, 1}, + {4007, 1, 0, 10367, 1, 45, 1}, + {4007, 1, 0, 10371, 1, 45, 1}, + {4007, 1, 0, 10373, 1, 45, 1}, + {4007, 1, 0, 11080, 1, 15, 1}, + {4007, 1, 0, 11081, 1, 15, 1}, + {4007, 1, 0, 11083, 1, 15, 1}, + {4007, 1, 0, 11125, 1, 15, 1}, + {4007, 1, 0, 11093, 1, 14, 1}, + {4007, 1, 0, 11053, 1, 10, 1}, + {4007, 1, 0, 11147, 1, 10, 1}, + {4007, 1, 0, 10372, 1, 5, 1}, + {4007, 1, 0, 10369, 1, 1, 1}, + {4007, 1, 0, 11163, 1, 150, 1}, + {4007, 1, 0, 11465, 1, 50, 1}, + {4007, 1, 0, 11466, 1, 25, 1}, + {4007, 1, 0, 11467, 1, 200, 1}, + {4007, 1, 0, 11468, 1, 400, 1}, + {4007, 1, 0, 11469, 1, 150, 1}, + {4007, 1, 0, 11037, 1, 92, 1}, + {4007, 1, 0, 11038, 1, 92, 1}, + {4007, 1, 0, 11044, 1, 92, 1}, + {4007, 1, 0, 11057, 1, 92, 1}, + {4007, 1, 0, 11059, 1, 92, 1}, + {4007, 1, 0, 11079, 1, 92, 1}, + {4007, 1, 0, 11098, 1, 92, 1}, + {4007, 1, 0, 11104, 1, 92, 1}, + {4007, 1, 0, 11117, 1, 92, 1}, + {4007, 1, 0, 11133, 1, 92, 1}, + {4007, 1, 0, 11137, 1, 92, 1}, + {4007, 1, 0, 11143, 1, 92, 1}, + {4007, 1, 0, 11132, 1, 92, 1}, + {4007, 1, 0, 11039, 1, 92, 1}, + {4007, 1, 0, 11040, 1, 92, 1}, + {4007, 1, 0, 11049, 1, 92, 1}, + {4007, 1, 0, 11061, 1, 92, 1}, + {4007, 1, 0, 11063, 1, 92, 1}, + {4007, 1, 0, 11077, 1, 92, 1}, + {4007, 1, 0, 11099, 1, 92, 1}, + {4007, 1, 0, 11105, 1, 92, 1}, + {4007, 1, 0, 11129, 1, 92, 1}, + {4007, 1, 0, 11130, 1, 92, 1}, + {4007, 1, 0, 11131, 1, 92, 1}, + {4007, 1, 0, 11139, 1, 92, 1}, + {4007, 1, 0, 11145, 1, 91, 1}, + {4007, 1, 0, 11096, 1, 91, 1}, + {4007, 1, 0, 11041, 1, 91, 1}, + {4007, 1, 0, 11047, 1, 91, 1}, + {4007, 1, 0, 11054, 1, 91, 1}, + {4007, 1, 0, 11065, 1, 91, 1}, + {4007, 1, 0, 11068, 1, 91, 1}, + {4007, 1, 0, 11075, 1, 91, 1}, + {4007, 1, 0, 11100, 1, 91, 1}, + {4007, 1, 0, 11106, 1, 91, 1}, + {4007, 1, 0, 11119, 1, 91, 1}, + {4007, 1, 0, 11135, 1, 91, 1}, + {4007, 1, 0, 11136, 1, 91, 1}, + {4007, 1, 0, 11138, 1, 91, 1}, + {4007, 1, 0, 11088, 1, 91, 1}, + {4007, 1, 0, 10370, 1, 91, 1}, + {4007, 1, 0, 10368, 1, 91, 1}, + {4007, 1, 0, 11045, 1, 91, 1}, + {4007, 1, 0, 11070, 1, 91, 1}, + {4007, 1, 0, 11101, 1, 91, 1}, + {4007, 1, 0, 11109, 1, 91, 1}, + {4007, 1, 0, 11122, 1, 91, 1}, + {4007, 1, 0, 11141, 1, 91, 1}, + {4007, 1, 0, 11051, 1, 91, 1}, + {4007, 1, 0, 11102, 1, 91, 1}, + {4007, 1, 0, 11124, 1, 91, 1}, + {4007, 1, 0, 11072, 1, 91, 1}, + {4007, 1, 0, 11082, 1, 91, 1}, + {4007, 1, 0, 11115, 1, 91, 1}, + {4007, 1, 0, 11144, 1, 91, 1}, + {4007, 1, 0, 11089, 1, 91, 1}, + {4007, 1, 0, 11091, 1, 91, 1}, + {4007, 1, 0, 11092, 1, 91, 1}, + {4007, 1, 0, 11050, 1, 91, 1}, + {4007, 1, 0, 11111, 1, 91, 1}, + {4007, 1, 0, 11113, 1, 91, 1}, + {4007, 1, 0, 11126, 1, 91, 1}, + {4007, 1, 0, 11055, 1, 91, 1}, + {4007, 1, 0, 11052, 1, 91, 1}, + {4007, 1, 0, 11146, 1, 91, 1}, + {4007, 2, 0, 11058, 1, 90, 1}, + {4007, 2, 0, 11060, 1, 90, 1}, + {4007, 2, 0, 11062, 1, 90, 1}, + {4007, 2, 0, 11064, 1, 90, 1}, + {4007, 2, 0, 11066, 1, 90, 1}, + {4007, 2, 0, 11118, 1, 90, 1}, + {4007, 2, 0, 11120, 1, 90, 1}, + {4007, 2, 0, 11110, 1, 90, 1}, + {4007, 2, 0, 11112, 1, 90, 1}, + {4007, 2, 0, 11114, 1, 90, 1}, + {4007, 2, 0, 11042, 1, 90, 1}, + {4007, 2, 0, 11043, 1, 90, 1}, + {4007, 2, 0, 11074, 1, 90, 1}, + {4007, 2, 0, 11140, 1, 90, 1}, + {4007, 2, 0, 11067, 1, 90, 1}, + {4007, 2, 0, 11048, 1, 90, 1}, + {4007, 2, 0, 11046, 1, 90, 1}, + {4007, 2, 0, 11103, 1, 90, 1}, + {4007, 2, 0, 11107, 1, 90, 1}, + {4007, 2, 0, 11108, 1, 90, 1}, + {4007, 2, 0, 11121, 1, 90, 1}, + {4007, 2, 0, 11134, 1, 90, 1}, + {4007, 2, 0, 11084, 1, 90, 1}, + {4007, 2, 0, 11085, 1, 90, 1}, + {4007, 2, 0, 11086, 1, 90, 1}, + {4007, 2, 0, 11087, 1, 90, 1}, + {4007, 2, 0, 11094, 1, 90, 1}, + {4007, 2, 0, 11095, 1, 90, 1}, + {4007, 2, 0, 10374, 1, 90, 1}, + {4007, 2, 0, 10375, 1, 90, 1}, + {4007, 2, 0, 10376, 1, 90, 1}, + {4007, 2, 0, 10377, 1, 90, 1}, + {4007, 2, 0, 10378, 1, 90, 1}, + {4007, 2, 0, 11069, 1, 80, 1}, + {4007, 2, 0, 11071, 1, 80, 1}, + {4007, 2, 0, 11073, 1, 80, 1}, + {4007, 2, 0, 11076, 1, 80, 1}, + {4007, 2, 0, 11078, 1, 80, 1}, + {4007, 2, 0, 11116, 1, 80, 1}, + {4007, 2, 0, 11123, 1, 80, 1}, + {4007, 2, 0, 11127, 1, 80, 1}, + {4007, 2, 0, 11142, 1, 80, 1}, + {4007, 2, 0, 11056, 1, 80, 1}, + {4007, 2, 0, 11090, 1, 80, 1}, + {4007, 2, 0, 11097, 1, 80, 1}, + {4007, 2, 0, 10367, 1, 80, 1}, + {4007, 2, 0, 10371, 1, 80, 1}, + {4007, 2, 0, 10373, 1, 80, 1}, + {4007, 2, 0, 11080, 1, 22, 1}, + {4007, 2, 0, 11081, 1, 22, 1}, + {4007, 2, 0, 11083, 1, 22, 1}, + {4007, 2, 0, 11125, 1, 22, 1}, + {4007, 2, 0, 11093, 1, 22, 1}, + {4007, 2, 0, 11053, 1, 15, 1}, + {4007, 2, 0, 11147, 1, 15, 1}, + {4007, 2, 0, 10372, 1, 8, 1}, + {4007, 2, 0, 10369, 1, 2, 1}, + {4007, 2, 0, 11159, 3, 1220, 1}, + {4007, 2, 0, 11160, 3, 650, 1}, + {4007, 2, 0, 11161, 3, 160, 1}, + {4007, 2, 0, 11661, 1, 800, 1}, + {4007, 2, 0, 11662, 1, 800, 1}, + {4007, 2, 0, 11163, 1, 500, 1}, + {4007, 2, 0, 11162, 1, 550, 1}, + {4007, 2, 0, 11465, 1, 50, 1}, + {4007, 2, 0, 11466, 1, 25, 1}, + {4007, 2, 0, 11467, 1, 250, 1}, + {4007, 2, 0, 11468, 1, 500, 1}, + {4007, 2, 0, 11469, 1, 175, 1}, + // Probably treasure chest rewards + {4202, 1, 0, 11163, 1, 6000, 1}, + {4202, 1, 0, 11465, 1, 200, 1}, + {4202, 1, 0, 11466, 1, 100, 1}, + {4202, 1, 0, 11467, 1, 1000, 1}, + {4202, 1, 0, 11468, 1, 2000, 1}, + {4202, 1, 0, 11469, 1, 700, 1}, + {4202, 2, 0, 11661, 1, 800, 1}, + {4202, 2, 0, 11662, 1, 800, 1}, + {4202, 2, 0, 11163, 1, 400, 1}, + {4202, 2, 0, 11465, 1, 400, 1}, + {4202, 2, 0, 11466, 1, 200, 1}, + {4202, 2, 0, 11467, 1, 2000, 1}, + {4202, 2, 0, 11468, 1, 4000, 1}, + {4202, 2, 0, 11469, 1, 1400, 1}, + } + default: + if pkt.Unk2 < 1000 { + s.logger.Info("PaperData request for unknown type", zap.Uint32("Unk2", pkt.Unk2)) + } + } + + if pkt.Unk2 > 1000 { + _, ok := paperGiftData[pkt.Unk2] + if ok { + paperGift = paperGiftData[pkt.Unk2] + } else { + s.logger.Info("PaperGift request for unknown type", zap.Uint32("Unk2", pkt.Unk2)) + } + for _, gift := range paperGift { + bf := byteframe.NewByteFrame() + bf.WriteUint16(gift.Unk0) + bf.WriteUint8(gift.Unk1) + bf.WriteUint8(gift.Unk2) + bf.WriteUint16(gift.Unk3) + data = append(data, bf) + } + doAckEarthSucceed(s, pkt.AckHandle, data) + } else if pkt.Unk2 == 0 { + bf := byteframe.NewByteFrame() + bf.WriteUint16(uint16(len(paperMissions.Timetables))) + bf.WriteUint16(uint16(len(paperMissions.Data))) + for _, timetable := range paperMissions.Timetables { + bf.WriteUint32(uint32(timetable.Start.Unix())) + bf.WriteUint32(uint32(timetable.End.Unix())) + } + for _, mdata := range paperMissions.Data { + bf.WriteUint8(mdata.Unk0) + bf.WriteUint8(mdata.Unk1) + bf.WriteInt16(mdata.Unk2) + bf.WriteUint16(mdata.Reward1ID) + bf.WriteUint8(mdata.Reward1Quantity) + bf.WriteUint16(mdata.Reward2ID) + bf.WriteUint8(mdata.Reward2Quantity) + } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } else { - data = []byte{0x00, 0x00, 0x00, 0x00} - s.logger.Info("GET_PAPER request for unknown type") + for _, pdata := range paperData { + bf := byteframe.NewByteFrame() + bf.WriteUint16(pdata.Unk0) + bf.WriteInt16(pdata.Unk1) + bf.WriteInt16(pdata.Unk2) + bf.WriteInt16(pdata.Unk3) + bf.WriteInt16(pdata.Unk4) + bf.WriteInt16(pdata.Unk5) + bf.WriteInt16(pdata.Unk6) + data = append(data, bf) + } + doAckEarthSucceed(s, pkt.AckHandle, data) } - if err != nil { - panic(err) - } - doAckBufSucceed(s, pkt.AckHandle, data) } func handleMsgSysAuthData(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/handlers_diva.go b/server/channelserver/handlers_diva.go index 0daabe70c..14baf8b2b 100644 --- a/server/channelserver/handlers_diva.go +++ b/server/channelserver/handlers_diva.go @@ -3,6 +3,7 @@ package channelserver import ( "encoding/hex" "erupe-ce/common/stringsupport" + _config "erupe-ce/config" "time" "erupe-ce/common/byteframe" @@ -71,7 +72,11 @@ func handleMsgMhfGetUdSchedule(s *Session, p mhfpacket.MHFPacket) { var timestamps []uint32 if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.DivaEvent >= 0 { if s.server.erupeConfig.DevModeOptions.DivaEvent == 0 { - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 36)) + if s.server.erupeConfig.ClientMode == _config.Z1 { + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 32)) + } else { + doAckBufSucceed(s, pkt.AckHandle, make([]byte, 36)) + } return } timestamps = generateDivaTimestamps(s, uint32(s.server.erupeConfig.DevModeOptions.DivaEvent), true) @@ -79,9 +84,11 @@ func handleMsgMhfGetUdSchedule(s *Session, p mhfpacket.MHFPacket) { timestamps = generateDivaTimestamps(s, start, false) } - bf.WriteUint32(id) - for _, timestamp := range timestamps { - bf.WriteUint32(timestamp) + if s.server.erupeConfig.ClientMode != _config.Z1 { + bf.WriteUint32(id) + } + for i := range timestamps { + bf.WriteUint32(timestamps[i]) } bf.WriteUint16(0x19) // Unk 00011001 diff --git a/server/channelserver/handlers_event.go b/server/channelserver/handlers_event.go index bba4c1065..ffc1b895f 100644 --- a/server/channelserver/handlers_event.go +++ b/server/channelserver/handlers_event.go @@ -2,6 +2,7 @@ package channelserver import ( "erupe-ce/common/token" + _config "erupe-ce/config" "math" "time" @@ -90,14 +91,18 @@ func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) { } func generateFeatureWeapons(count int) activeFeature { - if count > 14 { - count = 14 + max := 14 + if _config.ErupeConfig.ClientMode != _config.ZZ { + max = 13 + } + if count > max { + count = max } nums := make([]int, 0) var result int for len(nums) < count { rng := token.RNG() - num := rng.Intn(14) + num := rng.Intn(max) exist := false for _, v := range nums { if v == num { diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index 09520d8c4..ec58c7487 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -7,6 +7,7 @@ import ( "encoding/hex" "encoding/json" "errors" + _config "erupe-ce/config" "fmt" "math" "sort" @@ -1390,7 +1391,12 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(member.CharID) bf.WriteUint16(member.HRP) bf.WriteUint16(member.GR) - bf.WriteUint16(member.WeaponID) + if s.server.erupeConfig.ClientMode != _config.ZZ { + // Magnet Spike crash workaround + bf.WriteUint16(0) + } else { + bf.WriteUint16(member.WeaponID) + } if member.WeaponType == 1 || member.WeaponType == 5 || member.WeaponType == 10 { // If weapon is ranged bf.WriteUint8(7) } else { diff --git a/server/channelserver/handlers_mercenary.go b/server/channelserver/handlers_mercenary.go index 251bc107b..85ca65f9a 100644 --- a/server/channelserver/handlers_mercenary.go +++ b/server/channelserver/handlers_mercenary.go @@ -222,8 +222,8 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfContractMercenary) switch pkt.Op { - case 0: - s.server.db.Exec("UPDATE characters SET pact_id=$1 WHERE id=$2", pkt.PactMercID, s.charID) + case 0: // Form loan + s.server.db.Exec("UPDATE characters SET pact_id=$1 WHERE id=$2", pkt.PactMercID, pkt.CID) case 1: // Cancel lend s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID) case 2: // Cancel loan diff --git a/server/channelserver/handlers_quest.go b/server/channelserver/handlers_quest.go index 9caef6dbf..8f40f7539 100644 --- a/server/channelserver/handlers_quest.go +++ b/server/channelserver/handlers_quest.go @@ -1,15 +1,14 @@ package channelserver import ( - "encoding/hex" + "erupe-ce/common/byteframe" + "erupe-ce/network/mhfpacket" "fmt" + "go.uber.org/zap" "io" "os" "path/filepath" - - "erupe-ce/common/byteframe" - "erupe-ce/network/mhfpacket" - "go.uber.org/zap" + "time" ) func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) { @@ -85,7 +84,7 @@ func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) { var totalCount, returnedCount uint16 bf := byteframe.NewByteFrame() bf.WriteUint16(0) - err := filepath.Walk(fmt.Sprintf("%s/events/", s.server.erupeConfig.BinPath), func(path string, info os.FileInfo, err error) error { + filepath.Walk(fmt.Sprintf("%s/events/", s.server.erupeConfig.BinPath), func(path string, info os.FileInfo, err error) error { if err != nil { return err } else if info.IsDir() { @@ -108,9 +107,418 @@ func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) { } return nil }) - if err != nil || totalCount == 0 { - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 18)) - return + + type tuneValue struct { + ID uint16 + Value uint16 + } + + tuneValues := []tuneValue{ + {ID: 20, Value: 1}, + {ID: 26, Value: 1}, + {ID: 27, Value: 1}, + {ID: 33, Value: 1}, + {ID: 40, Value: 1}, + {ID: 49, Value: 1}, + {ID: 53, Value: 1}, + {ID: 59, Value: 1}, + {ID: 67, Value: 1}, + {ID: 80, Value: 1}, + {ID: 94, Value: 1}, + {ID: 1010, Value: 300}, + {ID: 1011, Value: 300}, + {ID: 1012, Value: 300}, + {ID: 1013, Value: 300}, + {ID: 1014, Value: 200}, + {ID: 1015, Value: 200}, + {ID: 1021, Value: 400}, + {ID: 1023, Value: 8}, + {ID: 1024, Value: 150}, + {ID: 1025, Value: 1}, + {ID: 1026, Value: 999}, // get_grank_cap + {ID: 1027, Value: 100}, + {ID: 1028, Value: 100}, + {ID: 1030, Value: 8}, + {ID: 1031, Value: 100}, + {ID: 1032, Value: 0}, // isValid_partner + {ID: 1044, Value: 200}, // get_rate_tload_time_out + {ID: 1045, Value: 0}, // get_rate_tower_treasure_preset + {ID: 1046, Value: 99}, + {ID: 1048, Value: 0}, // get_rate_tower_log_disable + {ID: 1049, Value: 10}, // get_rate_tower_gem_max + {ID: 1050, Value: 1}, // get_rate_tower_gem_set + {ID: 1051, Value: 200}, + {ID: 1052, Value: 200}, + {ID: 1063, Value: 50000}, + {ID: 1064, Value: 50000}, + {ID: 1065, Value: 25000}, + {ID: 1066, Value: 25000}, + {ID: 1067, Value: 90}, // get_lobby_member_upper_for_making_room Lv1? + {ID: 1068, Value: 80}, // get_lobby_member_upper_for_making_room Lv2? + {ID: 1069, Value: 70}, // get_lobby_member_upper_for_making_room Lv3? + {ID: 1072, Value: 300}, // get_rate_premium_ravi_tama + {ID: 1073, Value: 300}, // get_rate_premium_ravi_ax_tama + {ID: 1074, Value: 300}, // get_rate_premium_ravi_g_tama + {ID: 1078, Value: 0}, + {ID: 1079, Value: 1}, + {ID: 1080, Value: 1}, + {ID: 1081, Value: 1}, + {ID: 1082, Value: 4}, + {ID: 1083, Value: 2}, + {ID: 1084, Value: 10}, + {ID: 1085, Value: 1}, + {ID: 1086, Value: 4}, + {ID: 1087, Value: 2}, + {ID: 1088, Value: 10}, + {ID: 1089, Value: 1}, + {ID: 1090, Value: 3}, + {ID: 1091, Value: 2}, + {ID: 1092, Value: 10}, + {ID: 1093, Value: 2}, + {ID: 1094, Value: 5}, + {ID: 1095, Value: 2}, + {ID: 1096, Value: 10}, + {ID: 1097, Value: 2}, + {ID: 1098, Value: 5}, + {ID: 1099, Value: 2}, + {ID: 1100, Value: 10}, + {ID: 1101, Value: 2}, + {ID: 1102, Value: 5}, + {ID: 1103, Value: 2}, + {ID: 1104, Value: 10}, + {ID: 1106, Value: 0}, + {ID: 1145, Value: 200}, + {ID: 1146, Value: 0}, // isTower_invisible + {ID: 1147, Value: 0}, // isVenom_playable + {ID: 1149, Value: 20}, + {ID: 1152, Value: 1130}, + {ID: 1154, Value: 0}, // isDisabled_object_season + {ID: 1158, Value: 1}, + {ID: 1160, Value: 300}, + {ID: 1162, Value: 1}, + {ID: 1163, Value: 3}, + {ID: 1164, Value: 5}, + {ID: 1165, Value: 1}, + {ID: 1166, Value: 5}, + {ID: 1167, Value: 1}, + {ID: 1168, Value: 3}, + {ID: 1169, Value: 3}, + {ID: 1170, Value: 5}, + {ID: 1171, Value: 1}, + {ID: 1172, Value: 1}, + {ID: 1173, Value: 1}, + {ID: 1174, Value: 2}, + {ID: 1175, Value: 4}, + {ID: 1176, Value: 10}, + {ID: 1177, Value: 4}, + {ID: 1178, Value: 10}, + {ID: 1179, Value: 2}, + {ID: 1180, Value: 5}, + {ID: 3000, Value: 100}, + {ID: 3001, Value: 100}, + {ID: 3002, Value: 100}, + {ID: 3003, Value: 100}, + {ID: 3004, Value: 100}, + {ID: 3005, Value: 100}, + {ID: 3006, Value: 100}, + {ID: 3007, Value: 100}, + {ID: 3008, Value: 100}, + {ID: 3009, Value: 100}, + {ID: 3010, Value: 100}, + {ID: 3011, Value: 100}, + {ID: 3012, Value: 100}, + {ID: 3013, Value: 100}, + {ID: 3014, Value: 100}, + {ID: 3015, Value: 100}, + {ID: 3016, Value: 100}, + {ID: 3017, Value: 100}, + {ID: 3018, Value: 100}, + {ID: 3019, Value: 100}, + {ID: 3020, Value: 100}, + {ID: 3021, Value: 100}, + {ID: 3022, Value: 100}, + {ID: 3023, Value: 100}, + {ID: 3024, Value: 100}, + {ID: 3025, Value: 100}, + {ID: 3286, Value: 200}, + {ID: 3287, Value: 200}, + {ID: 3288, Value: 200}, + {ID: 3289, Value: 200}, + {ID: 3290, Value: 200}, + {ID: 3291, Value: 200}, + {ID: 3292, Value: 200}, + {ID: 3293, Value: 200}, + {ID: 3294, Value: 200}, + {ID: 3295, Value: 200}, + {ID: 3296, Value: 200}, + {ID: 3297, Value: 200}, + {ID: 3298, Value: 200}, + {ID: 3299, Value: 200}, + {ID: 3300, Value: 200}, + {ID: 3301, Value: 200}, + {ID: 3302, Value: 200}, + {ID: 3303, Value: 200}, + {ID: 3304, Value: 200}, + {ID: 3305, Value: 200}, + {ID: 3306, Value: 200}, + {ID: 3307, Value: 200}, + {ID: 3308, Value: 200}, + {ID: 3309, Value: 200}, + {ID: 3310, Value: 200}, + {ID: 3311, Value: 200}, + {ID: 3312, Value: 300}, + {ID: 3313, Value: 300}, + {ID: 3314, Value: 300}, + {ID: 3315, Value: 300}, + {ID: 3316, Value: 300}, + {ID: 3317, Value: 300}, + {ID: 3318, Value: 300}, + {ID: 3319, Value: 300}, + {ID: 3320, Value: 300}, + {ID: 3321, Value: 300}, + {ID: 3322, Value: 300}, + {ID: 3323, Value: 300}, + {ID: 3324, Value: 300}, + {ID: 3325, Value: 300}, + {ID: 3326, Value: 300}, + {ID: 3327, Value: 300}, + {ID: 3328, Value: 300}, + {ID: 3329, Value: 300}, + {ID: 3330, Value: 300}, + {ID: 3331, Value: 300}, + {ID: 3332, Value: 300}, + {ID: 3333, Value: 300}, + {ID: 3334, Value: 300}, + {ID: 3335, Value: 300}, + {ID: 3336, Value: 300}, + {ID: 3337, Value: 300}, + {ID: 3338, Value: 100}, + {ID: 3339, Value: 100}, + {ID: 3340, Value: 100}, + {ID: 3341, Value: 100}, + {ID: 3342, Value: 100}, + {ID: 3343, Value: 100}, + {ID: 3344, Value: 100}, + {ID: 3345, Value: 100}, + {ID: 3346, Value: 100}, + {ID: 3347, Value: 100}, + {ID: 3348, Value: 100}, + {ID: 3349, Value: 100}, + {ID: 3350, Value: 100}, + {ID: 3351, Value: 100}, + {ID: 3352, Value: 100}, + {ID: 3353, Value: 100}, + {ID: 3354, Value: 100}, + {ID: 3355, Value: 100}, + {ID: 3356, Value: 100}, + {ID: 3357, Value: 100}, + {ID: 3358, Value: 100}, + {ID: 3359, Value: 100}, + {ID: 3360, Value: 100}, + {ID: 3361, Value: 100}, + {ID: 3362, Value: 100}, + {ID: 3363, Value: 100}, + {ID: 3364, Value: 100}, + {ID: 3365, Value: 100}, + {ID: 3366, Value: 100}, + {ID: 3367, Value: 100}, + {ID: 3368, Value: 100}, + {ID: 3369, Value: 100}, + {ID: 3370, Value: 100}, + {ID: 3371, Value: 100}, + {ID: 3372, Value: 100}, + {ID: 3373, Value: 100}, + {ID: 3374, Value: 100}, + {ID: 3375, Value: 100}, + {ID: 3376, Value: 100}, + {ID: 3377, Value: 100}, + {ID: 3378, Value: 100}, + {ID: 3379, Value: 100}, + {ID: 3380, Value: 100}, + {ID: 3381, Value: 100}, + {ID: 3382, Value: 100}, + {ID: 3383, Value: 100}, + {ID: 3384, Value: 100}, + {ID: 3385, Value: 100}, + {ID: 3386, Value: 100}, + {ID: 3387, Value: 100}, + {ID: 3388, Value: 100}, + {ID: 3389, Value: 100}, + {ID: 3390, Value: 100}, + {ID: 3391, Value: 100}, + {ID: 3392, Value: 100}, + {ID: 3393, Value: 100}, + {ID: 3394, Value: 100}, + {ID: 3395, Value: 100}, + {ID: 3396, Value: 100}, + {ID: 3397, Value: 100}, + {ID: 3398, Value: 100}, + {ID: 3399, Value: 100}, + {ID: 3400, Value: 100}, + {ID: 3401, Value: 100}, + {ID: 3402, Value: 100}, + {ID: 3416, Value: 100}, + {ID: 3417, Value: 100}, + {ID: 3418, Value: 100}, + {ID: 3419, Value: 100}, + {ID: 3420, Value: 100}, + {ID: 3421, Value: 100}, + {ID: 3422, Value: 100}, + {ID: 3423, Value: 100}, + {ID: 3424, Value: 100}, + {ID: 3425, Value: 100}, + {ID: 3426, Value: 100}, + {ID: 3427, Value: 100}, + {ID: 3428, Value: 100}, + {ID: 3442, Value: 100}, + {ID: 3443, Value: 100}, + {ID: 3444, Value: 100}, + {ID: 3445, Value: 100}, + {ID: 3446, Value: 100}, + {ID: 3447, Value: 100}, + {ID: 3448, Value: 100}, + {ID: 3449, Value: 100}, + {ID: 3450, Value: 100}, + {ID: 3451, Value: 100}, + {ID: 3452, Value: 100}, + {ID: 3453, Value: 100}, + {ID: 3454, Value: 100}, + {ID: 3468, Value: 100}, + {ID: 3469, Value: 100}, + {ID: 3470, Value: 100}, + {ID: 3471, Value: 100}, + {ID: 3472, Value: 100}, + {ID: 3473, Value: 100}, + {ID: 3474, Value: 100}, + {ID: 3475, Value: 100}, + {ID: 3476, Value: 100}, + {ID: 3477, Value: 100}, + {ID: 3478, Value: 100}, + {ID: 3479, Value: 100}, + {ID: 3480, Value: 100}, + {ID: 3494, Value: 0}, + {ID: 3495, Value: 0}, + {ID: 3496, Value: 0}, + {ID: 3497, Value: 0}, + {ID: 3498, Value: 0}, + {ID: 3499, Value: 0}, + {ID: 3500, Value: 0}, + {ID: 3501, Value: 0}, + {ID: 3502, Value: 0}, + {ID: 3503, Value: 0}, + {ID: 3504, Value: 0}, + {ID: 3505, Value: 0}, + {ID: 3506, Value: 0}, + {ID: 3520, Value: 0}, + {ID: 3521, Value: 0}, + {ID: 3522, Value: 0}, + {ID: 3523, Value: 0}, + {ID: 3524, Value: 0}, + {ID: 3525, Value: 0}, + {ID: 3526, Value: 0}, + {ID: 3527, Value: 0}, + {ID: 3528, Value: 0}, + {ID: 3529, Value: 0}, + {ID: 3530, Value: 0}, + {ID: 3531, Value: 0}, + {ID: 3532, Value: 0}, + {ID: 3546, Value: 0}, + {ID: 3547, Value: 0}, + {ID: 3548, Value: 0}, + {ID: 3549, Value: 0}, + {ID: 3550, Value: 0}, + {ID: 3551, Value: 0}, + {ID: 3552, Value: 0}, + {ID: 3553, Value: 0}, + {ID: 3554, Value: 0}, + {ID: 3555, Value: 0}, + {ID: 3556, Value: 0}, + {ID: 3557, Value: 0}, + {ID: 3558, Value: 0}, + {ID: 3572, Value: 0}, + {ID: 3573, Value: 0}, + {ID: 3574, Value: 0}, + {ID: 3575, Value: 0}, + {ID: 3576, Value: 0}, + {ID: 3577, Value: 0}, + {ID: 3578, Value: 0}, + {ID: 3579, Value: 0}, + {ID: 3580, Value: 0}, + {ID: 3581, Value: 0}, + {ID: 3582, Value: 0}, + {ID: 3583, Value: 0}, + {ID: 3584, Value: 0}, + } + + tuneValues = append(tuneValues, tuneValue{1020, uint16(s.server.erupeConfig.GameplayOptions.GCPMultiplier * 100)}) + + tuneValues = append(tuneValues, tuneValue{1029, s.server.erupeConfig.GameplayOptions.GUrgentRate}) + + if s.server.erupeConfig.GameplayOptions.DisableHunterNavi { + tuneValues = append(tuneValues, tuneValue{1037, 1}) + } + + if s.server.erupeConfig.GameplayOptions.EnableHiganjimaEvent { + tuneValues = append(tuneValues, tuneValue{1144, 1}) + } else { + tuneValues = append(tuneValues, tuneValue{1144, 0}) + } + + if s.server.erupeConfig.GameplayOptions.EnableNierEvent { + tuneValues = append(tuneValues, tuneValue{1153, 1}) + } else { + tuneValues = append(tuneValues, tuneValue{1153, 0}) + } + + if s.server.erupeConfig.GameplayOptions.DisableRoad { + tuneValues = append(tuneValues, tuneValue{1155, 1}) + } else { + tuneValues = append(tuneValues, tuneValue{1155, 0}) + } + + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3026, uint16(s.server.erupeConfig.GameplayOptions.GRPMultiplier * 100)}) + } + + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3039, uint16(s.server.erupeConfig.GameplayOptions.GSRPMultiplier * 100)}) + } + + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3052, uint16(s.server.erupeConfig.GameplayOptions.GZennyMultiplier * 100)}) + } + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3078, uint16(s.server.erupeConfig.GameplayOptions.GZennyMultiplier * 100)}) + } + + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3104, uint16(s.server.erupeConfig.GameplayOptions.MaterialMultiplier * 100)}) + } + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3130, uint16(s.server.erupeConfig.GameplayOptions.MaterialMultiplier * 100)}) + } + + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3156, s.server.erupeConfig.GameplayOptions.ExtraCarves}) + } + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3182, s.server.erupeConfig.GameplayOptions.ExtraCarves}) + } + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3208, s.server.erupeConfig.GameplayOptions.ExtraCarves}) + } + for i := uint16(0); i < 13; i++ { + tuneValues = append(tuneValues, tuneValue{i + 3234, s.server.erupeConfig.GameplayOptions.ExtraCarves}) + } + + offset := uint16(time.Now().Unix()) + bf.WriteUint16(offset) + bf.WriteUint16(uint16(len(tuneValues))) + for i := range tuneValues { + bf.WriteUint16(tuneValues[i].ID ^ offset) + bf.WriteUint16(offset) + bf.WriteBytes(make([]byte, 4)) + bf.WriteUint16(tuneValues[i].Value ^ offset) } vsQuestItems := []uint16{1580, 1581, 1582, 1583, 1584, 1585, 1587, 1588, 1589, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604} @@ -123,10 +531,6 @@ func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) { {false, 5000}, {false, 10000}, } - - data, _ := hex.DecodeString("06E601CF051406E6D4D4D40007CA02F006E6D4D4D4000685051506E6D4D4D40007CA051206E6D4D4D40007CA051306E6D4D4D40007CA02DC06E6D4D4D40006E202D806E6D4D4D40006E202A406E6D4D4D40006E5026806E6D4D4D40006E3027406E6D4D4D40006E3027006E6D4D4D40006E4026506E6D4D4D40006E602E006E6D4D4D40006EE02E706E6D4D4D40006E70B4006E6D4D4D40006E602E206E6D4D4D400068202E506E6D4D4D400068206C706E6D4D4D40006E706B606E6D4D4D40006E706D706E6D4D4D40006E706F206E6D4D4D40006E706DD06E6D4D4D40006E706D306E6D4D4D40006E706FC06E6D4D4D40006E706B806E6D4D4D40006E706CE06E6D4D4D40006E706FD06E6D4D4D40006E706A506E6D4D4D40006E7051906E6D4D4D40006EE02E606E6D4D4D40006700B4106E6D4D4D40006E60B4E06E6D4D4D40006E60B4F06E6D4D4D40006E60B4C06E6D4D4D40006E60B4D06E6D4D4D40006E60B4A06E6D4D4D40006E60B4B06E6D4D4D40006E60B4806E6D4D4D40006E60B4906E6D4D4D40006E60B5606E6D4D4D40006E60B5706E6D4D4D40006E60B5406E6D4D4D40006E60B2606E6D4D4D40006E60B2706E6D4D4D40006E602DE06E6D4D4D40006E702DF06E6D4D4D40006E70B2406E6D4D4D40006E60B2506E6D4D4D40006E60A3006E6D4D4D400062E0A3106E6D4D4D400062E0A3E06E6D4D4D400062E0B2206E6D4D4D40006E60B2306E6D4D4D40006E60B2006E6D4D4D40006E60B2106E6D4D4D40006E60B2E06E6D4D4D40006E60B2F06E6D4D4D40006E6051A06E6D4D4D4000682051B06E6D4D4D400077602CD06E6D4D4D40006BC0B2C06E6D4D4D40006E60A3F06E6D4D4D400062E0A3C06E6D4D4D400062E0A3D06E6D4D4D400062E0A3A06E6D4D4D400062E0A3B06E6D4D4D400062E0A3806E6D4D4D400062E0A3906E6D4D4D400062E0A0606E6D4D4D400062E0A0706E6D4D4D400062E0A0406E6D4D4D400062E0A0506E6D4D4D400062E0A0206E6D4D4D400062E0A0306E6D4D4D400062E0A0006E6D4D4D400062E0A0106E6D4D4D400062E0A0E06E6D4D4D400062E0A0F06E6D4D4D400062E0A0C06E6D4D4D400062E0A0D06E6D4D4D400062E0A0A06E6D4D4D400062E0A0B06E6D4D4D400062E0A0806E6D4D4D400062E0A0906E6D4D4D400062E0A1606E6D4D4D40007CA0A1706E6D4D4D40007CA0A1406E6D4D4D40007CA0A1506E6D4D4D40007CA0A1206E6D4D4D40007CA0A1306E6D4D4D40007CA0A1006E6D4D4D40007CA0A1106E6D4D4D40007CA0A1E06E6D4D4D40007CA0A1F06E6D4D4D40007CA0A1C06E6D4D4D40007CA0A1D06E6D4D4D40007CA0A1A06E6D4D4D40007CA0A1B06E6D4D4D40007CA0A1806E6D4D4D40007CA0A1906E6D4D4D40007CA0BE606E6D4D4D40007CA0BE706E6D4D4D40007CA0BE406E6D4D4D40007CA0BE506E6D4D4D40007CA0BE206E6D4D4D40007CA0B2D06E6D4D4D40006E60B2A06E6D4D4D40006E60BE306E6D4D4D40007CA02D606E6D4D4D40007CA029F06E6D4D4D400062E0B9406E6D4D4D40006820BE006E6D4D4D40007CA0BE106E6D4D4D40007CA0BEE06E6D4D4D40007CA0BEF06E6D4D4D40007CA02C106E6D4D4D400C5B602CE06E6D4D4D400C5B602CF06E6D4D4D400674E02CC06E6D4D4D400674E051006E6D4D4D400062E02FA06E6D4D4D400062E02CA06E6D4D4D40006B602CB06E6D4D4D40006A0051106E6D4D4D400062E02FD06E6D4D4D400062E0B9506E6D4D4D40006820B9206E6D4D4D40006820B9306E6D4D4D40006820B9006E6D4D4D40006820B9106E6D4D4D40006820B9E06E6D4D4D40006820B9F06E6D4D4D40006820BEC06E6D4D4D40006820BED06E6D4D4D40006820BEA06E6D4D4D40006820BEB06E6D4D4D40006820BE806E6D4D4D40006820BE906E6D4D4D40006820BF606E6D4D4D40006820BF706E6D4D4D40006820BF406E6D4D4D40006820BF506E6D4D4D40006820BF206E6D4D4D40006820BF306E6D4D4D40006820BF006E6D4D4D40006820BF106E6D4D4D400068202DB06E6D4D4D40006E70B9C06E6D4D4D40006820BFE06E6D4D4D40006820BFF06E6D4D4D400068202A706E6D4D4D40006E70B9D06E6D4D4D40006820BFC06E6D4D4D400068202D106E6D4D4D40006E702DD06E6D4D4D40006E402DA06E6D4D4D40006EC02D906E6D4D4D40006E402A606E6D4D4D40006EC02A506E6D4D4D40006E402A206E6D4D4D40006EC02A106E6D4D4D40006E402AE06E6D4D4D40006EC02AD06E6D4D4D40006E402AA06E6D4D4D40006EC02A906E6D4D4D40006E402B606E6D4D4D40006EC0BFD06E6D4D4D40006820BFA06E6D4D4D40006820BFB06E6D4D4D40006820BF806E6D4D4D40006820BF906E6D4D4D40006820BC606E6D4D4D40006820BC706E6D4D4D40006820BC406E6D4D4D40006820BC506E6D4D4D40006820BC206E6D4D4D40006820BC306E6D4D4D40006820BC006E6D4D4D40006820BC106E6D4D4D40006820BCE06E6D4D4D40006820BCF06E6D4D4D40006820BCC06E6D4D4D40006820BCD06E6D4D4D40006820BCA06E6D4D4D40006820BCB06E6D4D4D40006820BC806E6D4D4D40006820BC906E6D4D4D40006820BD606E6D4D4D40006820BD706E6D4D4D40006820BD406E6D4D4D40006820BD506E6D4D4D40006820BD206E6D4D4D40006820BD306E6D4D4D40006820BD006E6D4D4D40006820BD106E6D4D4D40006820BDE06E6D4D4D40006820BDF06E6D4D4D40006820BDC06E6D4D4D40006820BDD06E6D4D4D40006820BDA06E6D4D4D40006820BDB06E6D4D4D40006820B9A06E6D4D4D40006820BD806E6D4D4D40006820BD906E6D4D4D40006820BA606E6D4D4D40006820BA706E6D4D4D40006820BA406E6D4D4D40006820BA506E6D4D4D40006820BA206E6D4D4D40006820BA306E6D4D4D40006820BA006E6D4D4D40006820BA106E6D4D4D40006820BAE06E6D4D4D40006820BAF06E6D4D4D40006820BAC06E6D4D4D40006820BBE06E6D4D4D40006820BBF06E6D4D4D40006820BBC06E6D4D4D40006820BBD06E6D4D4D40006820BBA06E6D4D4D40006820BBB06E6D4D4D40006820BB806E6D4D4D40006820BB906E6D4D4D40006820B8606E6D4D4D40006820B8706E6D4D4D40006820B8406E6D4D4D40006820B8506E6D4D4D40006820B8206E6D4D4D400068202D706E6D4D4D40007CA02D406E6D4D4D40007CA026E06E6D4D4D40007CA0B9B06E6D4D4D40006820B9806E6D4D4D40006820B6A06E6D4D4D40006820B6B06E6D4D4D4000682029C06E6D4D4D40006E60B6806E6D4D4D4000682029D06E6D4D4D40006E60B6906E6D4D4D40006820A6E06E6D4D4D40006E60A6F06E6D4D4D40006E60A6C06E6D4D4D40006E60A6D06E6D4D4D40006E60A6A06E6D4D4D40006E60A6B06E6D4D4D40006E60A6806E6D4D4D40006E60A6906E6D4D4D40006E60A7606E6D4D4D40006E60A7706E6D4D4D40006E602E406E6D4D4D40005010A7406E6D4D4D40006E60A7506E6D4D4D40006E602D006E6D4D4D40006E60A7206E6D4D4D40006E6026606E6D4D4D400028C0A4406E6D4D4D40006E60A4506E6D4D4D40006E6026C06E6D4D4D40006E7026D06E6D4D4D40006E5026A06E6D4D4D40006E3026B06E6D4D4D40006E70A4206E6D4D4D40006E6026906E6D4D4D40006E7027606E6D4D4D40006E5027706E6D4D4D40006E50A4306E6D4D4D40006E6027506E6D4D4D40006E7027206E6D4D4D40006E7027306E6D4D4D40006E70A4006E6D4D4D40006E60A4106E6D4D4D40006E60A4E06E6D4D4D40006E60A4F06E6D4D4D40006E60A4C06E6D4D4D40006E60A4D06E6D4D4D40006E60A4A06E6D4D4D40006E60A4B06E6D4D4D40006E60A4806E6D4D4D40006E6029E06E6D4D4D40006E602A306E6D4D4D40006E402A006E6D4D4D40006E302AF06E6D4D4D40006E402AC06E6D4D4D40006E302AB06E6D4D4D40006E402A806E6D4D4D40006E3027106E6D4D4D40006E2027E06E6D4D4D40006EC027F06E6D4D4D40006E2027C06E6D4D4D40006EC027D06E6D4D4D40006E40B7606E6D4D4D40006820B7706E6D4D4D40006820B7406E6D4D4D40006820B7506E6D4D4D40006820B7206E6D4D4D40006820B7306E6D4D4D40006820B7006E6D4D4D40006820B7106E6D4D4D40006820B7E06E6D4D4D40006820B3C06E6D4D4D40006E60D3406E6D4D4D40006820D3506E6D4D4D40006820B3D06E6D4D4D40006E6026706E6D4D4D40006E60D5E06E6D4D4D40006820D5F06E6D4D4D40006820D5C06E6D4D4D40006820D5D06E6D4D4D40006820D5A06E6D4D4D40006820D5B06E6D4D4D40006820D5806E6D4D4D40006820D5906E6D4D4D40006820D2606E6D4D4D40006820D2706E6D4D4D40006820D2406E6D4D4D40006820D2506E6D4D4D40006820D2206E6D4D4D40006820D3206E6D4D4D40006820D3306E6D4D4D40006820D3006E6D4D4D40006820D3106E6D4D4D40006820D3E06E6D4D4D40006820D2306E6D4D4D40006820D2006E6D4D4D40006820D2106E6D4D4D40006820D2E06E6D4D4D40006820D2F06E6D4D4D40006820D2C06E6D4D4D40006820D2D06E6D4D4D40006820D2A06E6D4D4D40006820D2B06E6D4D4D40006820D2806E6D4D4D40006820D2906E6D4D4D40006820D3606E6D4D4D40006820D3706E6D4D4D400068202E306E6D4D4D40006F802E106E6D4D4D40006820D3F06E6D4D4D40006820D0A06E6D4D4D40006820D0B06E6D4D4D40006820D0806E6D4D4D40006820D0906E6D4D4D40006820D1606E6D4D4D40006820D1706E6D4D4D40006820D1406E6D4D4D40006820D1506E6D4D4D40006820D1206E6D4D4D40006820D3C06E6D4D4D400068202B406E6D4D4D40006E60D1306E6D4D4D40006820D1006E6D4D4D40006820D1106E6D4D4D40006820D1E06E6D4D4D40006820AE006E6D4D4D40006820AE106E6D4D4D40006820AEE06E6D4D4D40006820AEF06E6D4D4D40006820AEC06E6D4D4D40006820AED06E6D4D4D40006820AEA06E6D4D4D40006820AEB06E6D4D4D40006820AE806E6D4D4D40006820AE906E6D4D4D40006820AF606E6D4D4D4000682026406E6D4D4D40006E60AF706E6D4D4D40006820B3A06E6D4D4D40006E60AB206E6D4D4D40006E60B3B06E6D4D4D40006E60D3D06E6D4D4D40006820D3A06E6D4D4D40006820D3B06E6D4D4D40006820AB306E6D4D4D40006E60AB006E6D4D4D40006E60AB106E6D4D4D40006E60ABE06E6D4D4D40006E60ABF06E6D4D4D40006E60ABC06E6D4D4D40006E60ABD06E6D4D4D40006E60ABA06E6D4D4D40006E60ABB06E6D4D4D40006E60AB806E6D4D4D40006E60AB906E6D4D4D40006E60A8606E6D4D4D40006E60A8806E6D4D4D40006E60A8906E6D4D4D40006E60A9606E6D4D4D40006E60A9706E6D4D4D40006E60A9406E6D4D4D40006E60A9506E6D4D4D40006E60A9206E6D4D4D40006E60A9306E6D4D4D40006E60A9006E6D4D4D40006E60A9106E6D4D4D40006E60A9E06E6D4D4D40006E60A9F06E6D4D4D40006E60A9C06E6D4D4D40006E60D3806E6D4D4D40006820D3906E6D4D4D40006820D0606E6D4D4D40006820D0706E6D4D4D40006820D0406E6D4D4D40006820D0506E6D4D4D40006820D0206E6D4D4D40006820D0306E6D4D4D40006820D0006E6D4D4D40006820D0106E6D4D4D40006820D0E06E6D4D4D40006820D0F06E6D4D4D40006820D0C06E6D4D4D40006820D0D06E6D4D4D40006820B3806E6D4D4D40006E60B3906E6D4D4D40006E60B0606E6D4D4D40006E60B0706E6D4D4D40006E60B0406E6D4D4D40006E60B0506E6D4D4D40006E60B0206E6D4D4D40006E60B0306E6D4D4D40006E60B0006E6D4D4D40006E60B1206E6D4D4D40006E60B1306E6D4D4D40006E60B1006E6D4D4D40006E60B1106E6D4D4D40006E60B1E06E6D4D4D40006E60B1F06E6D4D4D40006E60B1C06E6D4D4D40006E60B1D06E6D4D4D40006E60B1A06E6D4D4D40006E60B1B06E6D4D4D40006E60B1806E6D4D4D40006E60B1906E6D4D4D40006E608E606E6D4D4D40006E6029B06E6D4D4D40006F20AF406E6D4D4D4000682026006E6D4D4D40006E70AC606E6D4D4D40006820AC706E6D4D4D40006820AC406E6D4D4D40006820AC506E6D4D4D40006820AC206E6D4D4D40006820AC306E6D4D4D40006820AC006E6D4D4D40006820AC106E6D4D4D40006820ACE06E6D4D4D40006820ACF06E6D4D4D40006820ACC06E6D4D4D40006820ACD06E6D4D4D40006820ACA06E6D4D4D4000682027A06E6D4D4D40006E30ADC06E6D4D4D40006820ADD06E6D4D4D40006820ADA06E6D4D4D40006820ADB06E6D4D4D40006820AD806E6D4D4D40006820AD906E6D4D4D40006820AA606E6D4D4D40006820AA706E6D4D4D40006820AA406E6D4D4D40006820AA506E6D4D4D40006820AA206E6D4D4D40006820AA306E6D4D4D40006820AA006E6D4D4D4000682") - bf.WriteBytes(data) - bf.WriteUint16(uint16(len(vsQuestItems))) bf.WriteUint32(uint32(len(vsQuestBets))) bf.WriteUint16(0) // Unk diff --git a/server/channelserver/handlers_seibattle.go b/server/channelserver/handlers_seibattle.go new file mode 100644 index 000000000..4df05c67d --- /dev/null +++ b/server/channelserver/handlers_seibattle.go @@ -0,0 +1,98 @@ +package channelserver + +import ( + "erupe-ce/common/byteframe" + "erupe-ce/network/mhfpacket" +) + +func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetBreakSeibatuLevelReward) + bf := byteframe.NewByteFrame() + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} + +type WeeklySeibatuRankingReward struct { + Unk0 int32 + Unk1 int32 + Unk2 uint32 + Unk3 int32 + Unk4 int32 + Unk5 int32 +} + +func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetWeeklySeibatuRankingReward) + var data []*byteframe.ByteFrame + weeklySeibatuRankingRewards := []WeeklySeibatuRankingReward{ + {0, 0, 0, 0, 0, 0}, + } + for _, reward := range weeklySeibatuRankingRewards { + bf := byteframe.NewByteFrame() + bf.WriteInt32(reward.Unk0) + bf.WriteInt32(reward.Unk1) + bf.WriteUint32(reward.Unk2) + bf.WriteInt32(reward.Unk3) + bf.WriteInt32(reward.Unk4) + bf.WriteInt32(reward.Unk5) + data = append(data, bf) + } + doAckEarthSucceed(s, pkt.AckHandle, data) +} + +func handleMsgMhfGetFixedSeibatuRankingTable(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetFixedSeibatuRankingTable) + bf := byteframe.NewByteFrame() + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteBytes(make([]byte, 32)) + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} + +func handleMsgMhfReadBeatLevel(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfReadBeatLevel) + + // This response is fixed and will never change on JP, + // but I've left it dynamic for possible other client differences. + resp := byteframe.NewByteFrame() + for i := 0; i < int(pkt.ValidIDCount); i++ { + resp.WriteUint32(pkt.IDs[i]) + resp.WriteUint32(1) + resp.WriteUint32(1) + resp.WriteUint32(1) + } + + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) +} + +func handleMsgMhfReadLastWeekBeatRanking(s *Session, p mhfpacket.MHFPacket) {} + +func handleMsgMhfUpdateBeatLevel(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfUpdateBeatLevel) + + doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) +} + +func handleMsgMhfReadBeatLevelAllRanking(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfReadBeatLevelAllRanking) + bf := byteframe.NewByteFrame() + bf.WriteUint32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + + for i := 0; i < 100; i++ { + bf.WriteUint32(0) + bf.WriteUint32(0) + bf.WriteBytes(make([]byte, 32)) + } + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} + +func handleMsgMhfReadBeatLevelMyRanking(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfReadBeatLevelMyRanking) + bf := byteframe.NewByteFrame() + doAckBufSucceed(s, pkt.AckHandle, bf.Data()) +} diff --git a/server/channelserver/handlers_tower.go b/server/channelserver/handlers_tower.go index 0a2675812..a9bc1421c 100644 --- a/server/channelserver/handlers_tower.go +++ b/server/channelserver/handlers_tower.go @@ -1,102 +1,477 @@ package channelserver import ( - "encoding/hex" + "fmt" + "go.uber.org/zap" + "time" + + "erupe-ce/common/byteframe" + "erupe-ce/common/stringsupport" "erupe-ce/network/mhfpacket" ) +type TowerInfoTRP struct { + TR int32 + TRP int32 +} + +type TowerInfoSkill struct { + TSP int32 + Unk1 []int16 // 40 +} + +type TowerInfoHistory struct { + Unk0 []int16 // 5 + Unk1 []int16 // 5 +} + +type TowerInfoLevel struct { + Floors int32 + Unk1 int32 + Unk2 int32 + Unk3 int32 +} + func handleMsgMhfGetTowerInfo(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetTowerInfo) - var data []byte - var err error - /* - type: - 1 == TOWER_RANK_POINT, - 2 == GET_OWN_TOWER_SKILL - 3 == GET_OWN_TOWER_LEVEL_V3 - 4 == TOWER_TOUHA_HISTORY - 5 = ? - - [] = type - req - resp - - 01 1d 01 fc 00 09 [00 00 00 01] 00 00 00 02 00 00 00 00 - 00 12 01 fc 00 09 01 00 00 18 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 - - 01 1d 01 fc 00 0a [00 00 00 02] 00 00 00 00 00 00 00 00 - 00 12 01 fc 00 0a 01 00 00 94 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - - 01 1d 01 ff 00 0f [00 00 00 04] 00 00 00 00 00 00 00 00 - 00 12 01 ff 00 0f 01 00 00 24 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - - 01 1d 01 fc 00 0b [00 00 00 05] 00 00 00 00 00 00 00 00 - 00 12 01 fc 00 0b 01 00 00 10 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 00 - */ - switch pkt.InfoType { - case mhfpacket.TowerInfoTypeTowerRankPoint: - data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000") - case mhfpacket.TowerInfoTypeGetOwnTowerSkill: - //data, err = hex.DecodeString("0A218EAD000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - data, err = hex.DecodeString("0A218EAD0000000000000000000000010000001C0000000500050000000000020000000000000000000000000000000000030003000000000003000500050000000300030003000300030003000200030001000300020002000300010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - case mhfpacket.TowerInfoTypeGetOwnTowerLevelV3: - panic("No known response values for GetOwnTowerLevelV3") - case mhfpacket.TowerInfoTypeTowerTouhaHistory: - data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000000000000000000000000000") - case mhfpacket.TowerInfoTypeUnk5: - data, err = hex.DecodeString("0A218EAD000000000000000000000000") + var data []*byteframe.ByteFrame + type TowerInfo struct { + TRP []TowerInfoTRP + Skill []TowerInfoSkill + History []TowerInfoHistory + Level []TowerInfoLevel } + towerInfo := TowerInfo{ + TRP: []TowerInfoTRP{{0, 0}}, + Skill: []TowerInfoSkill{{0, make([]int16, 40)}}, + History: []TowerInfoHistory{{make([]int16, 5), make([]int16, 5)}}, + Level: []TowerInfoLevel{{0, 0, 0, 0}, {0, 0, 0, 0}}, + } + + tempSkills := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + + err := s.server.db.QueryRow(`SELECT COALESCE(tr, 0), COALESCE(trp, 0), COALESCE(tsp, 0), COALESCE(block1, 0), COALESCE(block2, 0), skills FROM tower WHERE char_id=$1 + `, s.charID).Scan(&towerInfo.TRP[0].TR, &towerInfo.TRP[0].TRP, &towerInfo.Skill[0].TSP, &towerInfo.Level[0].Floors, &towerInfo.Level[1].Floors, &tempSkills) if err != nil { - stubGetNoResults(s, pkt.AckHandle) + s.server.db.Exec(`INSERT INTO tower (char_id) VALUES ($1)`, s.charID) } - doAckBufSucceed(s, pkt.AckHandle, data) + + for i, skill := range stringsupport.CSVElems(tempSkills) { + towerInfo.Skill[0].Unk1[i] = int16(skill) + } + + switch pkt.InfoType { + case 1: + for _, trp := range towerInfo.TRP { + bf := byteframe.NewByteFrame() + bf.WriteInt32(trp.TR) + bf.WriteInt32(trp.TRP) + data = append(data, bf) + } + case 2: + for _, skills := range towerInfo.Skill { + bf := byteframe.NewByteFrame() + bf.WriteInt32(skills.TSP) + for i := range skills.Unk1 { + bf.WriteInt16(skills.Unk1[i]) + } + data = append(data, bf) + } + case 4: + for _, history := range towerInfo.History { + bf := byteframe.NewByteFrame() + for i := range history.Unk0 { + bf.WriteInt16(history.Unk0[i]) + } + for i := range history.Unk1 { + bf.WriteInt16(history.Unk1[i]) + } + data = append(data, bf) + } + case 5: + for _, level := range towerInfo.Level { + bf := byteframe.NewByteFrame() + bf.WriteInt32(level.Floors) + bf.WriteInt32(level.Unk1) + bf.WriteInt32(level.Unk2) + bf.WriteInt32(level.Unk3) + data = append(data, bf) + } + } + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfPostTowerInfo) - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + + if s.server.erupeConfig.DevModeOptions.QuestDebugTools { + s.logger.Debug( + p.Opcode().String(), + zap.Uint32("InfoType", pkt.InfoType), + zap.Uint32("Unk1", pkt.Unk1), + zap.Int32("Skill", pkt.Skill), + zap.Int32("TR", pkt.TR), + zap.Int32("TRP", pkt.TRP), + zap.Int32("Cost", pkt.Cost), + zap.Int32("Unk6", pkt.Unk6), + zap.Int32("Unk7", pkt.Unk7), + zap.Int32("Block1", pkt.Block1), + zap.Int64("Unk9", pkt.Unk9), + ) + } + + switch pkt.InfoType { + case 2: + skills := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + s.server.db.QueryRow(`SELECT skills FROM tower WHERE char_id=$1`, s.charID).Scan(&skills) + s.server.db.Exec(`UPDATE tower SET skills=$1, tsp=tsp-$2 WHERE char_id=$3`, stringsupport.CSVSetIndex(skills, int(pkt.Skill), stringsupport.CSVGetIndex(skills, int(pkt.Skill))+1), pkt.Cost, s.charID) + case 7: + s.server.db.Exec(`UPDATE tower SET tr=$1, trp=trp+$2, block1=block1+$3 WHERE char_id=$4`, pkt.TR, pkt.TRP, pkt.Block1, s.charID) + } + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} + +// Default missions +var tenrouiraiData = []TenrouiraiData{ + {1, 1, 80, 0, 2, 2, 1, 1, 2, 2}, + {1, 4, 16, 0, 2, 2, 1, 1, 2, 2}, + {1, 6, 50, 0, 2, 2, 1, 0, 2, 2}, + {1, 4, 12, 50, 2, 2, 1, 1, 2, 2}, + {1, 3, 50, 0, 2, 2, 1, 1, 2, 2}, + {2, 5, 40000, 0, 2, 2, 1, 0, 2, 2}, + {1, 5, 50000, 50, 2, 2, 1, 1, 2, 2}, + {2, 1, 60, 0, 2, 2, 1, 1, 2, 2}, + {2, 3, 50, 0, 2, 1, 1, 0, 1, 2}, + {2, 3, 40, 50, 2, 1, 1, 1, 1, 2}, + {2, 4, 12, 0, 2, 1, 1, 1, 1, 2}, + {2, 6, 40, 0, 2, 1, 1, 0, 1, 2}, + {1, 1, 60, 50, 2, 1, 2, 1, 1, 2}, + {1, 5, 50000, 0, 3, 1, 2, 1, 1, 2}, + {1, 6, 50, 0, 3, 1, 2, 0, 1, 2}, + {1, 4, 16, 50, 3, 1, 2, 1, 1, 2}, + {1, 5, 50000, 0, 3, 1, 2, 1, 1, 2}, + {2, 3, 40, 0, 3, 1, 2, 0, 1, 2}, + {1, 3, 50, 50, 3, 1, 2, 1, 1, 2}, + {2, 5, 40000, 0, 3, 1, 2, 1, 1, 1}, + {2, 6, 40, 0, 3, 1, 2, 0, 1, 1}, + {2, 1, 60, 50, 3, 1, 2, 1, 1, 1}, + {2, 6, 50, 0, 3, 1, 2, 1, 1, 1}, + {2, 4, 12, 0, 3, 1, 2, 0, 1, 1}, + {1, 1, 80, 50, 3, 1, 2, 1, 1, 1}, + {1, 5, 40000, 0, 3, 1, 2, 1, 1, 1}, + {1, 3, 50, 0, 3, 1, 2, 0, 1, 1}, + {1, 4, 16, 50, 3, 1, 0, 1, 1, 1}, + {1, 6, 50, 0, 3, 1, 0, 1, 1, 1}, + {2, 3, 40, 0, 3, 1, 0, 1, 1, 1}, + {1, 1, 80, 50, 3, 1, 0, 0, 1, 1}, + {2, 5, 40000, 0, 3, 1, 0, 0, 1, 1}, + {2, 6, 40, 0, 3, 1, 0, 0, 1, 1}, +} + +type TenrouiraiProgress struct { + Page uint8 + Mission1 uint16 + Mission2 uint16 + Mission3 uint16 +} + +type TenrouiraiReward struct { + Index uint8 + Item []uint16 // 5 + Quantity []uint8 // 5 +} + +type TenrouiraiKeyScore struct { + Unk0 uint8 + Unk1 int32 +} + +type TenrouiraiData struct { + Block uint8 + Mission uint8 + // 1 = Floors climbed + // 2 = Collect antiques + // 3 = Open chests + // 4 = Cats saved + // 5 = TRP acquisition + // 6 = Monster slays + Goal uint16 + Cost uint16 + Skill1 uint8 // 80 + Skill2 uint8 // 40 + Skill3 uint8 // 40 + Skill4 uint8 // 20 + Skill5 uint8 // 40 + Skill6 uint8 // 50 +} + +type TenrouiraiCharScore struct { + Score int32 + Name string +} + +type TenrouiraiTicket struct { + Unk0 uint8 + RP uint32 + Unk2 uint32 +} + +type Tenrouirai struct { + Progress []TenrouiraiProgress + Reward []TenrouiraiReward + KeyScore []TenrouiraiKeyScore + Data []TenrouiraiData + CharScore []TenrouiraiCharScore + Ticket []TenrouiraiTicket } func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) { - // if the game gets bad responses for this it breaks the ability to save pkt := p.(*mhfpacket.MsgMhfGetTenrouirai) - var data []byte - var err error - if pkt.Unk0 == 1 { - data, err = hex.DecodeString("0A218EAD000000000000000000000001010000000000060010") - } else if pkt.Unk2 == 4 { - data, err = hex.DecodeString("0A218EAD0000000000000000000000210101005000000202010102020104001000000202010102020106003200000202010002020104000C003202020101020201030032000002020101020202059C4000000202010002020105C35000320202010102020201003C00000202010102020203003200000201010001020203002800320201010101020204000C00000201010101020206002800000201010001020101003C00320201020101020105C35000000301020101020106003200000301020001020104001000320301020101020105C350000003010201010202030028000003010200010201030032003203010201010202059C4000000301020101010206002800000301020001010201003C00320301020101010206003200000301020101010204000C000003010200010101010050003203010201010101059C40000003010201010101030032000003010200010101040010003203010001010101060032000003010001010102030028000003010001010101010050003203010000010102059C4000000301000001010206002800000301000001010010") - } else { - data = []byte{0x00, 0x00, 0x00, 0x00} - s.logger.Info("GET_TENROUIRAI request for unknown type") + var data []*byteframe.ByteFrame + + tenrouirai := Tenrouirai{ + Progress: []TenrouiraiProgress{{1, 0, 0, 0}}, + Data: tenrouiraiData, + Ticket: []TenrouiraiTicket{{0, 0, 0}}, } - if err != nil { - panic(err) + + switch pkt.Unk1 { + case 1: + for _, tdata := range tenrouirai.Data { + bf := byteframe.NewByteFrame() + bf.WriteUint8(tdata.Block) + bf.WriteUint8(tdata.Mission) + bf.WriteUint16(tdata.Goal) + bf.WriteUint16(tdata.Cost) + bf.WriteUint8(tdata.Skill1) + bf.WriteUint8(tdata.Skill2) + bf.WriteUint8(tdata.Skill3) + bf.WriteUint8(tdata.Skill4) + bf.WriteUint8(tdata.Skill5) + bf.WriteUint8(tdata.Skill6) + data = append(data, bf) + } + case 2: + for _, reward := range tenrouirai.Reward { + bf := byteframe.NewByteFrame() + bf.WriteUint8(reward.Index) + bf.WriteUint16(reward.Item[0]) + bf.WriteUint16(reward.Item[1]) + bf.WriteUint16(reward.Item[2]) + bf.WriteUint16(reward.Item[3]) + bf.WriteUint16(reward.Item[4]) + bf.WriteUint8(reward.Quantity[0]) + bf.WriteUint8(reward.Quantity[1]) + bf.WriteUint8(reward.Quantity[2]) + bf.WriteUint8(reward.Quantity[3]) + bf.WriteUint8(reward.Quantity[4]) + data = append(data, bf) + } + case 4: + s.server.db.QueryRow(`SELECT tower_mission_page FROM guilds WHERE id=$1`, pkt.GuildID).Scan(&tenrouirai.Progress[0].Page) + s.server.db.QueryRow(`SELECT SUM(tower_mission_1) AS _, SUM(tower_mission_2) AS _, SUM(tower_mission_3) AS _ FROM guild_characters WHERE guild_id=$1 + `, pkt.GuildID).Scan(&tenrouirai.Progress[0].Mission1, &tenrouirai.Progress[0].Mission2, &tenrouirai.Progress[0].Mission3) + + if tenrouirai.Progress[0].Mission1 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-3].Goal { + tenrouirai.Progress[0].Mission1 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-3].Goal + } + if tenrouirai.Progress[0].Mission2 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-2].Goal { + tenrouirai.Progress[0].Mission2 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-2].Goal + } + if tenrouirai.Progress[0].Mission3 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-1].Goal { + tenrouirai.Progress[0].Mission3 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-1].Goal + } + + for _, progress := range tenrouirai.Progress { + bf := byteframe.NewByteFrame() + bf.WriteUint8(progress.Page) + bf.WriteUint16(progress.Mission1) + bf.WriteUint16(progress.Mission2) + bf.WriteUint16(progress.Mission3) + data = append(data, bf) + } + case 5: + if pkt.Unk3 > 3 { + pkt.Unk3 %= 3 + if pkt.Unk3 == 0 { + pkt.Unk3 = 3 + } + } + rows, _ := s.server.db.Query(fmt.Sprintf(`SELECT name, tower_mission_%d FROM guild_characters gc INNER JOIN characters c ON gc.character_id = c.id WHERE guild_id=$1 AND tower_mission_%d IS NOT NULL ORDER BY tower_mission_%d DESC`, pkt.Unk3, pkt.Unk3, pkt.Unk3), pkt.GuildID) + for rows.Next() { + temp := TenrouiraiCharScore{} + rows.Scan(&temp.Name, &temp.Score) + tenrouirai.CharScore = append(tenrouirai.CharScore, temp) + } + for _, charScore := range tenrouirai.CharScore { + bf := byteframe.NewByteFrame() + bf.WriteInt32(charScore.Score) + bf.WriteBytes(stringsupport.PaddedString(charScore.Name, 14, true)) + data = append(data, bf) + } + case 6: + s.server.db.QueryRow(`SELECT tower_rp FROM guilds WHERE id=$1`, pkt.GuildID).Scan(&tenrouirai.Ticket[0].RP) + for _, ticket := range tenrouirai.Ticket { + bf := byteframe.NewByteFrame() + bf.WriteUint8(ticket.Unk0) + bf.WriteUint32(ticket.RP) + bf.WriteUint32(ticket.Unk2) + data = append(data, bf) + } } - doAckBufSucceed(s, pkt.AckHandle, data) + + doAckEarthSucceed(s, pkt.AckHandle, data) } func handleMsgMhfPostTenrouirai(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfPostTenrouirai) - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) -} -func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {} + if s.server.erupeConfig.DevModeOptions.QuestDebugTools { + s.logger.Debug( + p.Opcode().String(), + zap.Uint8("Unk0", pkt.Unk0), + zap.Uint8("Op", pkt.Op), + zap.Uint32("GuildID", pkt.GuildID), + zap.Uint8("Unk1", pkt.Unk1), + zap.Uint16("Floors", pkt.Floors), + zap.Uint16("Antiques", pkt.Antiques), + zap.Uint16("Chests", pkt.Chests), + zap.Uint16("Cats", pkt.Cats), + zap.Uint16("TRP", pkt.TRP), + zap.Uint16("Slays", pkt.Slays), + ) + } -func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket) { - pkt := p.(*mhfpacket.MsgMhfGetWeeklySeibatuRankingReward) - doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + if pkt.Op == 2 { + var page, requirement, donated int + s.server.db.QueryRow(`SELECT tower_mission_page, tower_rp FROM guilds WHERE id=$1`, pkt.GuildID).Scan(&page, &donated) + + for i := 0; i < (page*3)+1; i++ { + requirement += int(tenrouiraiData[i].Cost) + } + + bf := byteframe.NewByteFrame() + + sd, err := GetCharacterSaveData(s, s.charID) + if err == nil && sd != nil { + sd.RP -= pkt.DonatedRP + sd.Save(s) + if donated+int(pkt.DonatedRP) >= requirement { + s.server.db.Exec(`UPDATE guilds SET tower_mission_page=tower_mission_page+1 WHERE id=$1`, pkt.GuildID) + s.server.db.Exec(`UPDATE guild_characters SET tower_mission_1=NULL, tower_mission_2=NULL, tower_mission_3=NULL WHERE guild_id=$1`, pkt.GuildID) + pkt.DonatedRP = uint16(requirement - donated) + } + bf.WriteUint32(uint32(pkt.DonatedRP)) + s.server.db.Exec(`UPDATE guilds SET tower_rp=tower_rp+$1 WHERE id=$2`, pkt.DonatedRP, pkt.GuildID) + } else { + bf.WriteUint32(0) + } + + doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) + } else { + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + } } func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfPresentBox) - doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) + var data []*byteframe.ByteFrame + /* + bf.WriteUint32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + bf.WriteInt32(0) + */ + doAckEarthSucceed(s, pkt.AckHandle, data) +} + +type GemInfo struct { + Gem uint16 + Quantity uint16 +} + +type GemHistory struct { + Gem uint16 + Message uint16 + Timestamp time.Time + Sender string } func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetGemInfo) + var data []*byteframe.ByteFrame + gemInfo := []GemInfo{} + gemHistory := []GemHistory{} + + tempGems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&tempGems) + for i, v := range stringsupport.CSVElems(tempGems) { + gemInfo = append(gemInfo, GemInfo{uint16(((i / 5) * 256) + ((i % 5) + 1)), uint16(v)}) + } + + switch pkt.Unk0 { + case 1: + for _, info := range gemInfo { + bf := byteframe.NewByteFrame() + bf.WriteUint16(info.Gem) + bf.WriteUint16(info.Quantity) + data = append(data, bf) + } + case 2: + for _, history := range gemHistory { + bf := byteframe.NewByteFrame() + bf.WriteUint16(history.Gem) + bf.WriteUint16(history.Message) + bf.WriteUint32(uint32(history.Timestamp.Unix())) + bf.WriteBytes(stringsupport.PaddedString(history.Sender, 14, true)) + data = append(data, bf) + } + } + doAckEarthSucceed(s, pkt.AckHandle, data) +} + +func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfPostGemInfo) + + if s.server.erupeConfig.DevModeOptions.QuestDebugTools { + s.logger.Debug( + p.Opcode().String(), + zap.Uint32("Op", pkt.Op), + zap.Uint32("Unk1", pkt.Unk1), + zap.Int32("Gem", pkt.Gem), + zap.Int32("Quantity", pkt.Quantity), + zap.Int32("CID", pkt.CID), + zap.Int32("Message", pkt.Message), + zap.Int32("Unk6", pkt.Unk6), + ) + } + + gems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&gems) + switch pkt.Op { + case 1: // Add gem + i := int(((pkt.Gem / 256) * 5) + (((pkt.Gem - ((pkt.Gem / 256) * 256)) - 1) % 5)) + s.server.db.Exec(`UPDATE tower SET gems=$1 WHERE char_id=$2`, stringsupport.CSVSetIndex(gems, i, stringsupport.CSVGetIndex(gems, i)+int(pkt.Quantity)), s.charID) + case 2: // Transfer gem + // no way im doing this for now + } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } -func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfGetNotice(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfGetNotice) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} + +func handleMsgMhfPostNotice(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfPostNotice) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index 309ed1af8..dccece844 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -22,7 +22,7 @@ type Config struct { Logger *zap.Logger DB *sqlx.DB DiscordBot *discordbot.DiscordBot - ErupeConfig *config.Config + ErupeConfig *_config.Config Name string Enable bool } @@ -43,7 +43,7 @@ type Server struct { Port uint16 logger *zap.Logger db *sqlx.DB - erupeConfig *config.Config + erupeConfig *_config.Config acceptConns chan net.Conn deleteConns chan net.Conn sessions map[net.Conn]*Session diff --git a/server/discordbot/discord_bot.go b/server/discordbot/discord_bot.go index fc5c41ce8..c082faf70 100644 --- a/server/discordbot/discord_bot.go +++ b/server/discordbot/discord_bot.go @@ -9,14 +9,14 @@ import ( type DiscordBot struct { Session *discordgo.Session - config *config.Config + config *_config.Config logger *zap.Logger MainGuild *discordgo.Guild RealtimeChannel *discordgo.Channel } type Options struct { - Config *config.Config + Config *_config.Config Logger *zap.Logger } diff --git a/server/entranceserver/entrance_server.go b/server/entranceserver/entrance_server.go index c0a4e852b..8b06be0e0 100644 --- a/server/entranceserver/entrance_server.go +++ b/server/entranceserver/entrance_server.go @@ -18,7 +18,7 @@ import ( type Server struct { sync.Mutex logger *zap.Logger - erupeConfig *config.Config + erupeConfig *_config.Config db *sqlx.DB listener net.Listener isShuttingDown bool @@ -28,7 +28,7 @@ type Server struct { type Config struct { Logger *zap.Logger DB *sqlx.DB - ErupeConfig *config.Config + ErupeConfig *_config.Config } // NewServer creates a new Server type. @@ -68,7 +68,7 @@ func (s *Server) Shutdown() { s.listener.Close() } -//acceptClients handles accepting new clients in a loop. +// acceptClients handles accepting new clients in a loop. func (s *Server) acceptClients() { for { conn, err := s.listener.Accept() diff --git a/server/entranceserver/make_resp.go b/server/entranceserver/make_resp.go index 2d13709db..ac63a8ad5 100644 --- a/server/entranceserver/make_resp.go +++ b/server/entranceserver/make_resp.go @@ -3,13 +3,13 @@ package entranceserver import ( "encoding/binary" "encoding/hex" + _config "erupe-ce/config" "fmt" "net" "erupe-ce/common/stringsupport" "erupe-ce/common/byteframe" - "erupe-ce/config" "erupe-ce/server/channelserver" ) @@ -19,11 +19,17 @@ var season uint8 // Server Channels var currentplayers uint16 -func encodeServerInfo(config *config.Config, s *Server, local bool) []byte { +func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte { serverInfos := config.Entrance.Entries bf := byteframe.NewByteFrame() for serverIdx, si := range serverInfos { + // Prevent MezFes Worlds displaying on Z1 + if config.ClientMode == _config.Z1 { + if si.Type == 6 { + continue + } + } sid := (4096 + serverIdx*256) + 16 err := s.db.QueryRow("SELECT season FROM servers WHERE server_id=$1", sid).Scan(&season) if err != nil { @@ -91,8 +97,17 @@ func makeHeader(data []byte, respType string, entryCount uint16, key byte) []byt return bf.Data() } -func makeSv2Resp(config *config.Config, s *Server, local bool) []byte { +func makeSv2Resp(config *_config.Config, s *Server, local bool) []byte { serverInfos := config.Entrance.Entries + // Decrease by the number of MezFes Worlds + var mf int + if config.ClientMode == _config.Z1 { + for _, si := range serverInfos { + if si.Type == 6 { + mf++ + } + } + } rawServerData := encodeServerInfo(config, s, local) if s.erupeConfig.DevMode && s.erupeConfig.DevModeOptions.LogOutboundMessages { @@ -100,7 +115,7 @@ func makeSv2Resp(config *config.Config, s *Server, local bool) []byte { } bf := byteframe.NewByteFrame() - bf.WriteBytes(makeHeader(rawServerData, "SV2", uint16(len(serverInfos)), 0x00)) + bf.WriteBytes(makeHeader(rawServerData, "SV2", uint16(len(serverInfos)-mf), 0x00)) return bf.Data() } diff --git a/server/signserver/sign_server.go b/server/signserver/sign_server.go index fd4bd9bed..f93a6459a 100644 --- a/server/signserver/sign_server.go +++ b/server/signserver/sign_server.go @@ -16,14 +16,14 @@ import ( type Config struct { Logger *zap.Logger DB *sqlx.DB - ErupeConfig *config.Config + ErupeConfig *_config.Config } // Server is a MHF sign server. type Server struct { sync.Mutex logger *zap.Logger - erupeConfig *config.Config + erupeConfig *_config.Config sessions map[int]*Session db *sqlx.DB listener net.Listener diff --git a/server/signv2server/signv2_server.go b/server/signv2server/signv2_server.go index c00a4a641..c6db00b09 100644 --- a/server/signv2server/signv2_server.go +++ b/server/signv2server/signv2_server.go @@ -18,14 +18,14 @@ import ( type Config struct { Logger *zap.Logger DB *sqlx.DB - ErupeConfig *config.Config + ErupeConfig *_config.Config } // Server is the MHF custom launcher sign server. type Server struct { sync.Mutex logger *zap.Logger - erupeConfig *config.Config + erupeConfig *_config.Config db *sqlx.DB httpServer *http.Server isShuttingDown bool