From 76ba7cb94215e88ebdb4aeb79799800f747fe9bd Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 27 Nov 2023 03:41:48 -0500 Subject: [PATCH 01/24] feat: Custom prefixes and basic help command --- config.json | 6 ++++++ config/config.go | 1 + server/channelserver/handlers_cast_binary.go | 8 +++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index da75463ee..5a6e09216 100644 --- a/config.json +++ b/config.json @@ -14,6 +14,7 @@ "ClientMode": "ZZ", "QuestCacheExpiry": 300, "ProxyPort": 0, + "CommandPrefix": "!", "DevMode": true, "DevModeOptions": { "AutoCreateAccount": true, @@ -78,6 +79,11 @@ "RealtimeChannelID": "" }, "Commands": [ + { + "Name": "Help", + "Enabled": true, + "Prefix": "help" + }, { "Name": "Rights", "Enabled": false, diff --git a/config/config.go b/config/config.go index 31fedd246..5a50a511b 100644 --- a/config/config.go +++ b/config/config.go @@ -81,6 +81,7 @@ type Config struct { RealClientMode Mode QuestCacheExpiry int // Number of seconds to keep quest data cached ProxyPort uint16 // Forces the game to connect to a channel server proxy + CommandPrefix string // The prefix for commands DevMode bool DevModeOptions DevModeOptions diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index dbfafc68c..806c50749 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -318,6 +318,12 @@ func parseChatCommand(s *Session, command string) { } else { sendDisabledCommandMessage(s, commands["Teleport"]) } + case commands["Help"].Prefix: + if commands["Help"].Enabled { + sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportSuccess"], x, y)) + } else { + sendDisabledCommandMessage(s, commands["Help"]) + } } } @@ -391,7 +397,7 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) { bf.SetLE() chatMessage := &binpacket.MsgBinChat{} chatMessage.Parse(bf) - if strings.HasPrefix(chatMessage.Message, "!") { + if strings.HasPrefix(chatMessage.Message, s.server.erupeConfig.CommandPrefix) { parseChatCommand(s, chatMessage.Message) return } From ce773a6c569f464932d3c7c94b37183ed987726d Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 27 Nov 2023 04:05:15 -0500 Subject: [PATCH 02/24] feat: Finish help command and add description to commands. --- config.json | 8 ++++++++ config/config.go | 7 ++++--- server/channelserver/handlers_cast_binary.go | 5 ++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/config.json b/config.json index 5a6e09216..e18506f3a 100644 --- a/config.json +++ b/config.json @@ -82,35 +82,43 @@ { "Name": "Help", "Enabled": true, + "Description": "Show all of the commands", "Prefix": "help" }, { "Name": "Rights", "Enabled": false, + "Description": "Directly alter user's applied courses.", "Prefix": "rights" }, { "Name": "Raviente", "Enabled": true, + "Description": "Start or view an ongoing raviante raid.", "Prefix": "ravi" }, { "Name": "Teleport", "Enabled": false, + "Description": "Teleport to a specified stage.", "Prefix": "tele" }, { "Name": "Reload", "Enabled": true, + "Description": "Reload all user sessions (Forces log out)", "Prefix": "reload" }, { "Name": "KeyQuest", "Enabled": false, + "Description": "Allow the overriding of necessary key quests.", "Prefix": "kqf" }, { "Name": "Course", "Enabled": true, + "Description": "Apply/remove user courses based on the name.", "Prefix": "course" }, { "Name": "PSN", "Enabled": true, + "Description": "Link a PSN account to your Erupe account.", "Prefix": "psn" } ], diff --git a/config/config.go b/config/config.go index 5a50a511b..12cb00316 100644 --- a/config/config.go +++ b/config/config.go @@ -169,9 +169,10 @@ type Discord struct { // Command is a channelserver chat command type Command struct { - Name string - Enabled bool - Prefix string + Name string + Enabled bool + Description string + Prefix string } // Course represents a course within MHF diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 806c50749..e74728906 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -10,6 +10,7 @@ import ( "erupe-ce/network/binpacket" "erupe-ce/network/mhfpacket" "fmt" + "golang.org/x/exp/maps" "golang.org/x/exp/slices" "math" "strconv" @@ -320,7 +321,9 @@ func parseChatCommand(s *Session, command string) { } case commands["Help"].Prefix: if commands["Help"].Enabled { - sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportSuccess"], x, y)) + for _, command := range maps.Values(commands) { + sendServerChatMessage(s, fmt.Sprintf("%s: %s", command.Name, command.Description)) + } } else { sendDisabledCommandMessage(s, commands["Help"]) } From 23bc66eda508c4fe20538b8672527c4e8e88bfa6 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 27 Nov 2023 04:07:44 -0500 Subject: [PATCH 03/24] fix: Consider prefix length when slicing. --- server/channelserver/handlers_cast_binary.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index e74728906..990dfb1ce 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -85,7 +85,7 @@ func sendServerChatMessage(s *Session, message string) { } func parseChatCommand(s *Session, command string) { - args := strings.Split(command[1:], " ") + args := strings.Split(command[len(s.server.erupeConfig.CommandPrefix):], " ") switch args[0] { case commands["PSN"].Prefix: if commands["PSN"].Enabled { From 88652e1dc0c7e44b300767831dd421c836940d65 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 27 Nov 2023 15:32:52 -0500 Subject: [PATCH 04/24] chore: Change command name to show the prefix instead. --- server/channelserver/handlers_cast_binary.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index ef9ee8798..10ac2fa7c 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -326,7 +326,7 @@ func parseChatCommand(s *Session, command string) { case commands["Help"].Prefix: if commands["Help"].Enabled { for _, command := range maps.Values(commands) { - sendServerChatMessage(s, fmt.Sprintf("%s: %s", command.Name, command.Description)) + sendServerChatMessage(s, fmt.Sprintf("!%s: %s", command.Prefix, command.Description)) } } else { sendDisabledCommandMessage(s, commands["Help"]) From de5c3addd19b3a4f6af89cd28b08b241200fdeee Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 27 Nov 2023 15:34:28 -0500 Subject: [PATCH 05/24] fix: Show config prefix instead of just ! --- server/channelserver/handlers_cast_binary.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 10ac2fa7c..816ee3307 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -326,7 +326,7 @@ func parseChatCommand(s *Session, command string) { case commands["Help"].Prefix: if commands["Help"].Enabled { for _, command := range maps.Values(commands) { - sendServerChatMessage(s, fmt.Sprintf("!%s: %s", command.Prefix, command.Description)) + sendServerChatMessage(s, fmt.Sprintf("%s%s: %s", s.server.erupeConfig.CommandPrefix, command.Prefix, command.Description)) } } else { sendDisabledCommandMessage(s, commands["Help"]) From 7b7b2874c5d58ba3c6eccdb9aba7d258146fb548 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 27 Nov 2023 16:14:32 -0500 Subject: [PATCH 06/24] fix: Fixed description for reload command. --- config.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index e18506f3a..e30514bb6 100644 --- a/config.json +++ b/config.json @@ -84,8 +84,7 @@ "Enabled": true, "Description": "Show all of the commands", "Prefix": "help" - }, - { + }, { "Name": "Rights", "Enabled": false, "Description": "Directly alter user's applied courses.", @@ -103,7 +102,7 @@ }, { "Name": "Reload", "Enabled": true, - "Description": "Reload all user sessions (Forces log out)", + "Description": "Delete and recreate all players within the session.", "Prefix": "reload" }, { "Name": "KeyQuest", From 2199e07be86734d9df9a57167b0adf7aff2339d4 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 28 Nov 2023 22:07:20 +1100 Subject: [PATCH 07/24] simplify SaveDecoMyset --- server/channelserver/handlers_house.go | 94 +++++++++++--------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 35ebfa308..8587ee8aa 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -262,66 +262,50 @@ func handleMsgMhfLoadDecoMyset(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfSaveDecoMyset) - // TODO: Backwards compatibility for DecoMyset - if s.server.erupeConfig.RealClientMode < _config.ZZ { + var temp []byte + err := s.server.db.QueryRow("SELECT decomyset FROM characters WHERE id = $1", s.charID).Scan(&temp) + if err != nil { + s.logger.Error("Failed to load decomyset", zap.Error(err)) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) return } - // https://gist.github.com/Andoryuuta/9c524da7285e4b5ca7e52e0fc1ca1daf - var loadData []byte - bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload[1:]) // skip first unk byte - err := s.server.db.QueryRow("SELECT decomyset FROM characters WHERE id = $1", s.charID).Scan(&loadData) - if err != nil { - s.logger.Error("Failed to load decomyset", zap.Error(err)) - } else { - numSets := bf.ReadUint8() // sets being written - // empty save - if len(loadData) == 0 { - loadData = []byte{0x01, 0x00} - } - savedSets := loadData[1] // existing saved sets - // no sets, new slice with just first 2 bytes for appends later - if savedSets == 0 { - loadData = []byte{0x01, 0x00} - } - for i := 0; i < int(numSets); i++ { - writeSet := bf.ReadUint16() - dataChunk := bf.ReadBytes(76) - setBytes := append([]byte{uint8(writeSet >> 8), uint8(writeSet & 0xff)}, dataChunk...) - for x := 0; true; x++ { - if x == int(savedSets) { - // appending set - if loadData[len(loadData)-1] == 0x10 { - // sanity check for if there was a messy manual import - loadData = append(loadData[:len(loadData)-2], setBytes...) - } else { - loadData = append(loadData, setBytes...) - } - savedSets++ - break - } - currentSet := loadData[3+(x*78)] - if int(currentSet) == int(writeSet) { - // replacing a set - loadData = append(loadData[:2+(x*78)], append(setBytes, loadData[2+((x+1)*78):]...)...) - break - } else if int(currentSet) > int(writeSet) { - // inserting before current set - loadData = append(loadData[:2+((x)*78)], append(setBytes, loadData[2+((x)*78):]...)...) - savedSets++ - break - } - } - loadData[1] = savedSets // update set count - } - dumpSaveData(s, loadData, "decomyset") - _, err := s.server.db.Exec("UPDATE characters SET decomyset=$1 WHERE id=$2", loadData, s.charID) - if err != nil { - s.logger.Error("Failed to save decomyset", zap.Error(err)) - } + // Version handling + bf := byteframe.NewByteFrame() + var size int + if s.server.erupeConfig.RealClientMode >= _config.G10 { + size = 76 + bf.WriteUint8(1) + } else { + size = 68 + bf.WriteUint8(0) } - doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) + + // Build a map of set data + sets := make(map[uint16][]byte) + oldSets := byteframe.NewByteFrameFromBytes(temp[2:]) + for i := 0; i < len(temp)/size; i++ { + index := oldSets.ReadUint16() + sets[index] = oldSets.ReadBytes(uint(size)) + } + + // Overwrite existing sets + newSets := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload[2:]) + for i := uint8(0); i < pkt.RawDataPayload[1]; i++ { + index := newSets.ReadUint16() + sets[index] = newSets.ReadBytes(uint(size)) + } + + // Serialise the set data + bf.WriteUint8(uint8(len(sets))) + for u, b := range sets { + bf.WriteUint16(u) + bf.WriteBytes(b) + } + + dumpSaveData(s, bf.Data(), "decomyset") + s.server.db.Exec("UPDATE characters SET decomyset=$1 WHERE id=$2", bf.Data(), s.charID) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } type Title struct { From 2502b47077ebd677346c8cb80f2476e3a9c2ec11 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 28 Nov 2023 22:25:36 +1100 Subject: [PATCH 08/24] simplify SaveDecoMyset --- server/channelserver/handlers_house.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 8587ee8aa..1cb47ec3e 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -272,7 +272,7 @@ func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) { // Version handling bf := byteframe.NewByteFrame() - var size int + var size uint if s.server.erupeConfig.RealClientMode >= _config.G10 { size = 76 bf.WriteUint8(1) @@ -284,16 +284,16 @@ func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) { // Build a map of set data sets := make(map[uint16][]byte) oldSets := byteframe.NewByteFrameFromBytes(temp[2:]) - for i := 0; i < len(temp)/size; i++ { + for i := uint8(0); i < temp[1]; i++ { index := oldSets.ReadUint16() - sets[index] = oldSets.ReadBytes(uint(size)) + sets[index] = oldSets.ReadBytes(size) } // Overwrite existing sets newSets := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload[2:]) for i := uint8(0); i < pkt.RawDataPayload[1]; i++ { index := newSets.ReadUint16() - sets[index] = newSets.ReadBytes(uint(size)) + sets[index] = newSets.ReadBytes(size) } // Serialise the set data From acf942075c5663df3ef852f6339e2b21a77699e5 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 28 Nov 2023 23:13:26 +1100 Subject: [PATCH 09/24] use fallback backStage --- server/channelserver/handlers_stage.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/channelserver/handlers_stage.go b/server/channelserver/handlers_stage.go index 3092db3fd..abd9d3ba5 100644 --- a/server/channelserver/handlers_stage.go +++ b/server/channelserver/handlers_stage.go @@ -171,8 +171,8 @@ func handleMsgSysBackStage(s *Session, p mhfpacket.MHFPacket) { // Transfer back to the saved stage ID before the previous move or enter. backStage, err := s.stageMoveStack.Pop() - if err != nil { - panic(err) + if backStage == "" || err != nil { + backStage = "sl1Ns200p0a0u0" } if _, exists := s.stage.reservedClientSlots[s.charID]; exists { From 8d02c9f9071e0fa50889373e048158e3d649869d Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 28 Nov 2023 23:40:47 +1100 Subject: [PATCH 10/24] remove unnecessary dependency change --- server/channelserver/handlers_cast_binary.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 816ee3307..4d3fc639a 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -10,7 +10,6 @@ import ( "erupe-ce/network/binpacket" "erupe-ce/network/mhfpacket" "fmt" - "golang.org/x/exp/maps" "golang.org/x/exp/slices" "math" "strconv" @@ -325,7 +324,7 @@ func parseChatCommand(s *Session, command string) { } case commands["Help"].Prefix: if commands["Help"].Enabled { - for _, command := range maps.Values(commands) { + for _, command := range commands { sendServerChatMessage(s, fmt.Sprintf("%s%s: %s", s.server.erupeConfig.CommandPrefix, command.Prefix, command.Description)) } } else { From 1cd60eb5aee8ea8d7610ee9f327947a647d05600 Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 28 Nov 2023 23:41:22 +1100 Subject: [PATCH 11/24] hide disabled commands --- server/channelserver/handlers_cast_binary.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/channelserver/handlers_cast_binary.go b/server/channelserver/handlers_cast_binary.go index 4d3fc639a..71a8a6f07 100644 --- a/server/channelserver/handlers_cast_binary.go +++ b/server/channelserver/handlers_cast_binary.go @@ -325,7 +325,9 @@ func parseChatCommand(s *Session, command string) { case commands["Help"].Prefix: if commands["Help"].Enabled { for _, command := range commands { - sendServerChatMessage(s, fmt.Sprintf("%s%s: %s", s.server.erupeConfig.CommandPrefix, command.Prefix, command.Description)) + if command.Enabled { + sendServerChatMessage(s, fmt.Sprintf("%s%s: %s", s.server.erupeConfig.CommandPrefix, command.Prefix, command.Description)) + } } } else { sendDisabledCommandMessage(s, commands["Help"]) From d7b400c812c3fd1781ce38fab35a0738520daeaf Mon Sep 17 00:00:00 2001 From: wish Date: Tue, 28 Nov 2023 23:41:54 +1100 Subject: [PATCH 12/24] revise command descriptions --- config.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config.json b/config.json index e30514bb6..688a9879b 100644 --- a/config.json +++ b/config.json @@ -82,42 +82,42 @@ { "Name": "Help", "Enabled": true, - "Description": "Show all of the commands", + "Description": "Show enabled chat commands", "Prefix": "help" }, { "Name": "Rights", "Enabled": false, - "Description": "Directly alter user's applied courses.", + "Description": "Overwrite the Rights value on your account", "Prefix": "rights" }, { "Name": "Raviente", "Enabled": true, - "Description": "Start or view an ongoing raviante raid.", + "Description": "Various Raviente siege commands", "Prefix": "ravi" }, { "Name": "Teleport", "Enabled": false, - "Description": "Teleport to a specified stage.", + "Description": "Teleport to specified coordinates", "Prefix": "tele" }, { "Name": "Reload", "Enabled": true, - "Description": "Delete and recreate all players within the session.", + "Description": "Reload all players in your Land", "Prefix": "reload" }, { "Name": "KeyQuest", "Enabled": false, - "Description": "Allow the overriding of necessary key quests.", + "Description": "Overwrite your HR Key Quest progress", "Prefix": "kqf" }, { "Name": "Course", "Enabled": true, - "Description": "Apply/remove user courses based on the name.", + "Description": "Toggle Courses on your account", "Prefix": "course" }, { "Name": "PSN", "Enabled": true, - "Description": "Link a PSN account to your Erupe account.", + "Description": "Link a PlayStation Network ID to your account", "Prefix": "psn" } ], From ea981ca70f2813dfa516d6ed251677486e405f29 Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 29 Nov 2023 21:36:50 +1100 Subject: [PATCH 13/24] add Koban Shop items to OtherShops.sql --- bundled-schema/OtherShops.sql | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/bundled-schema/OtherShops.sql b/bundled-schema/OtherShops.sql index d25e453b0..3c88bb896 100644 --- a/bundled-schema/OtherShops.sql +++ b/bundled-schema/OtherShops.sql @@ -5,6 +5,42 @@ INSERT INTO public.shop_items VALUES (5,5,16516,100,1,0,0,1,0,0,0,0), (5,5,16517,100,1,0,0,1,0,0,0,0), + (6,5,9958,3,3,1,0,0,0,0,0,0), + (6,5,1897,3,1,1,0,0,0,0,0,0), + (6,5,8889,3,1,0,0,1,0,0,0,0), + (6,5,6176,3,6,1,0,0,0,0,0,0), + (6,5,1472,3,10,1,0,0,0,0,0,0), + (6,5,7280,3,3,0,0,1,0,0,0,0), + (6,5,8027,3,30,1,0,0,0,0,0,0), + (6,5,8028,3,30,1,0,0,0,0,0,0), + (6,5,8029,3,30,1,0,0,0,0,0,0), + (6,5,8026,3,30,1,0,0,0,0,0,0), + (6,5,8030,3,30,1,0,0,0,0,0,0), + (6,5,4353,3,30,1,0,0,0,0,0,0), + (6,5,4354,3,30,1,0,0,0,0,0,0), + (6,5,4355,3,30,1,0,0,0,0,0,0), + (6,5,4356,3,30,1,0,0,0,0,0,0), + (6,5,4357,3,30,1,0,0,0,0,0,0), + (6,5,4745,3,30,1,0,0,0,0,0,0), + (6,5,4746,3,30,1,0,0,0,0,0,0), + (6,5,4747,3,30,1,0,0,0,0,0,0), + (6,5,4748,3,30,1,0,0,0,0,0,0), + (6,5,4749,3,30,1,0,0,0,0,0,0), + (6,5,5122,3,30,1,0,0,0,0,0,0), + (6,5,5123,3,30,1,0,0,0,0,0,0), + (6,5,5124,3,30,1,0,0,0,0,0,0), + (6,5,5125,3,30,1,0,0,0,0,0,0), + (6,5,5126,3,30,1,0,0,0,0,0,0), + (6,5,5795,3,30,1,0,0,0,0,0,0), + (6,5,5796,3,30,1,0,0,0,0,0,0), + (6,5,5797,3,30,1,0,0,0,0,0,0), + (6,5,5798,3,30,1,0,0,0,0,0,0), + (6,5,5799,3,30,1,0,0,0,0,0,0), + (6,5,6168,3,30,1,0,0,0,0,0,0), + (6,5,6169,3,30,1,0,0,0,0,0,0), + (6,5,6170,3,30,1,0,0,0,0,0,0), + (6,5,6171,3,30,1,0,0,0,0,0,0), + (6,5,6172,3,30,1,0,0,0,0,0,0), (7,0,13190,10,1,0,0,0,0,0,0,0), (7,0,1662,10,1,0,0,0,0,0,0,0), (7,0,10179,100,1,0,0,0,0,0,0,0); From e914cf406b9dac4d4202e63c565753046d491045 Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 29 Nov 2023 21:37:41 +1100 Subject: [PATCH 14/24] limit EnumerateShop responses --- network/mhfpacket/msg_mhf_enumerate_shop.go | 4 ++-- server/channelserver/handlers_shop_gacha.go | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/network/mhfpacket/msg_mhf_enumerate_shop.go b/network/mhfpacket/msg_mhf_enumerate_shop.go index 153095db4..d57655e98 100644 --- a/network/mhfpacket/msg_mhf_enumerate_shop.go +++ b/network/mhfpacket/msg_mhf_enumerate_shop.go @@ -14,7 +14,7 @@ type MsgMhfEnumerateShop struct { AckHandle uint32 ShopType uint8 // 1 running gachas, 10 normal shop extensions, 8 Diva Defense shop ShopID uint32 - Unk2 uint16 // 00 80 running gachas, 00 20 normal shop + Limit uint16 Unk3 uint8 Unk4 uint8 Unk5 uint32 @@ -30,7 +30,7 @@ func (m *MsgMhfEnumerateShop) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clie m.AckHandle = bf.ReadUint32() m.ShopType = bf.ReadUint8() m.ShopID = bf.ReadUint32() - m.Unk2 = bf.ReadUint16() + m.Limit = bf.ReadUint16() m.Unk3 = bf.ReadUint8() if _config.ErupeConfig.RealClientMode >= _config.G2 { m.Unk4 = bf.ReadUint8() diff --git a/server/channelserver/handlers_shop_gacha.go b/server/channelserver/handlers_shop_gacha.go index c18119c6e..01c87ffbd 100644 --- a/server/channelserver/handlers_shop_gacha.go +++ b/server/channelserver/handlers_shop_gacha.go @@ -241,6 +241,9 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) { case 10: // Item shop, 0-8 bf := byteframe.NewByteFrame() items := getShopItems(s, pkt.ShopType, pkt.ShopID) + if len(items) > int(pkt.Limit) { + items = items[:pkt.Limit] + } writeShopItems(bf, items) doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } From c996975bf1b8350788a379116129ffc3063e66bc Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 29 Nov 2023 21:38:32 +1100 Subject: [PATCH 15/24] correct EnumerateShop response --- server/channelserver/handlers_shop_gacha.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/channelserver/handlers_shop_gacha.go b/server/channelserver/handlers_shop_gacha.go index 01c87ffbd..297ebb9a0 100644 --- a/server/channelserver/handlers_shop_gacha.go +++ b/server/channelserver/handlers_shop_gacha.go @@ -10,13 +10,13 @@ import ( type ShopItem struct { ID uint32 `db:"id"` - ItemID uint16 `db:"item_id"` + ItemID uint32 `db:"item_id"` Cost uint32 `db:"cost"` Quantity uint16 `db:"quantity"` MinHR uint16 `db:"min_hr"` MinSR uint16 `db:"min_sr"` MinGR uint16 `db:"min_gr"` - StoreLevel uint16 `db:"store_level"` + StoreLevel uint8 `db:"store_level"` MaxQuantity uint16 `db:"max_quantity"` UsedQuantity uint16 `db:"used_quantity"` RoadFloors uint16 `db:"road_floors"` @@ -62,14 +62,14 @@ func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem) { bf.WriteUint16(uint16(len(items))) for _, item := range items { bf.WriteUint32(item.ID) - bf.WriteUint16(0) - bf.WriteUint16(item.ItemID) + bf.WriteUint32(item.ItemID) bf.WriteUint32(item.Cost) bf.WriteUint16(item.Quantity) bf.WriteUint16(item.MinHR) bf.WriteUint16(item.MinSR) bf.WriteUint16(item.MinGR) - bf.WriteUint16(item.StoreLevel) + bf.WriteUint8(0) // Unk + bf.WriteUint8(item.StoreLevel) bf.WriteUint16(item.MaxQuantity) bf.WriteUint16(item.UsedQuantity) bf.WriteUint16(item.RoadFloors) From 4a962e2701c9068edabed5122e4e173b9b8ea94a Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 29 Nov 2023 23:14:34 +1100 Subject: [PATCH 16/24] fix SaveDecoMyset on first save --- server/channelserver/handlers_house.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 1cb47ec3e..62561c96d 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -281,6 +281,11 @@ func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint8(0) } + // Handle nil data + if len(temp) == 0 { + temp = append(bf.Data(), uint8(0)) + } + // Build a map of set data sets := make(map[uint16][]byte) oldSets := byteframe.NewByteFrameFromBytes(temp[2:]) From 15739ad0d2a1e9cab40e228af4cf9ecbaa08b905 Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 29 Nov 2023 23:15:32 +1100 Subject: [PATCH 17/24] fix PostTowerInfo not incrementing --- server/channelserver/handlers_tower.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/channelserver/handlers_tower.go b/server/channelserver/handlers_tower.go index a9bc1421c..407bc8d55 100644 --- a/server/channelserver/handlers_tower.go +++ b/server/channelserver/handlers_tower.go @@ -126,8 +126,8 @@ func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) { 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) + case 1, 7: + s.server.db.Exec(`UPDATE tower SET tr=$1, trp=COALESCE(trp, 0)+$2, block1=COALESCE(block1, 0)+$3 WHERE char_id=$4`, pkt.TR, pkt.TRP, pkt.Block1, s.charID) } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From 4376ed667836976675098360a6d84aa0181678fb Mon Sep 17 00:00:00 2001 From: wish Date: Wed, 29 Nov 2023 23:41:06 +1100 Subject: [PATCH 18/24] partial backport EnumerateShop --- server/channelserver/handlers_shop_gacha.go | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/server/channelserver/handlers_shop_gacha.go b/server/channelserver/handlers_shop_gacha.go index 297ebb9a0..3058fb632 100644 --- a/server/channelserver/handlers_shop_gacha.go +++ b/server/channelserver/handlers_shop_gacha.go @@ -61,19 +61,30 @@ func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem) { bf.WriteUint16(uint16(len(items))) bf.WriteUint16(uint16(len(items))) for _, item := range items { - bf.WriteUint32(item.ID) + if _config.ErupeConfig.RealClientMode >= _config.Z2 { + bf.WriteUint32(item.ID) + } bf.WriteUint32(item.ItemID) bf.WriteUint32(item.Cost) bf.WriteUint16(item.Quantity) bf.WriteUint16(item.MinHR) bf.WriteUint16(item.MinSR) - bf.WriteUint16(item.MinGR) + if _config.ErupeConfig.RealClientMode >= _config.Z2 { + bf.WriteUint16(item.MinGR) + } bf.WriteUint8(0) // Unk bf.WriteUint8(item.StoreLevel) - bf.WriteUint16(item.MaxQuantity) - bf.WriteUint16(item.UsedQuantity) - bf.WriteUint16(item.RoadFloors) - bf.WriteUint16(item.RoadFatalis) + if _config.ErupeConfig.RealClientMode >= _config.Z2 { + bf.WriteUint16(item.MaxQuantity) + bf.WriteUint16(item.UsedQuantity) + } + if _config.ErupeConfig.RealClientMode == _config.Z1 { + bf.WriteUint8(uint8(item.RoadFloors)) + bf.WriteUint8(uint8(item.RoadFatalis)) + } else if _config.ErupeConfig.RealClientMode >= _config.Z2 { + bf.WriteUint16(item.RoadFloors) + bf.WriteUint16(item.RoadFatalis) + } } } From 617d600f9a08f2481fd282a3b440dd736c00273f Mon Sep 17 00:00:00 2001 From: wish Date: Thu, 30 Nov 2023 00:07:09 +1100 Subject: [PATCH 19/24] test TSP accumulation --- server/channelserver/handlers_tower.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/channelserver/handlers_tower.go b/server/channelserver/handlers_tower.go index 407bc8d55..4ce0bcc9f 100644 --- a/server/channelserver/handlers_tower.go +++ b/server/channelserver/handlers_tower.go @@ -127,7 +127,8 @@ func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) { 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 1, 7: - s.server.db.Exec(`UPDATE tower SET tr=$1, trp=COALESCE(trp, 0)+$2, block1=COALESCE(block1, 0)+$3 WHERE char_id=$4`, pkt.TR, pkt.TRP, pkt.Block1, s.charID) + // This might give too much TSP? No idea what the rate is supposed to be + s.server.db.Exec(`UPDATE tower SET tr=$1, trp=COALESCE(trp, 0)+$2, tsp=COALESCE(tsp, 0)+$3, block1=COALESCE(block1, 0)+$4 WHERE char_id=$5`, pkt.TR, pkt.TRP, pkt.Cost, pkt.Block1, s.charID) } doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) } From c46a3a78f0a151465aefb9561fdaf9fc51888e0f Mon Sep 17 00:00:00 2001 From: wish Date: Thu, 30 Nov 2023 00:07:36 +1100 Subject: [PATCH 20/24] fix GetEarthStatus response --- server/channelserver/handlers.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index abba0cfe6..c94d78305 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -995,7 +995,9 @@ func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) { bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthMonsterOverride) bf.WriteInt32(0) bf.WriteInt32(0) - bf.WriteInt32(0) + if _config.ErupeConfig.RealClientMode >= _config.G91 { + bf.WriteInt32(0) + } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } From 58708eaaf2530f9b556a3962608e5d97457452fe Mon Sep 17 00:00:00 2001 From: wish Date: Thu, 30 Nov 2023 00:30:32 +1100 Subject: [PATCH 21/24] fix GetUdSchedule response --- server/channelserver/handlers_diva.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/channelserver/handlers_diva.go b/server/channelserver/handlers_diva.go index 1867bfacd..2c60e9767 100644 --- a/server/channelserver/handlers_diva.go +++ b/server/channelserver/handlers_diva.go @@ -72,7 +72,7 @@ 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 { - if s.server.erupeConfig.RealClientMode <= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z2 { doAckBufSucceed(s, pkt.AckHandle, make([]byte, 32)) } else { doAckBufSucceed(s, pkt.AckHandle, make([]byte, 36)) @@ -84,7 +84,7 @@ func handleMsgMhfGetUdSchedule(s *Session, p mhfpacket.MHFPacket) { timestamps = generateDivaTimestamps(s, start, false) } - if s.server.erupeConfig.RealClientMode <= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z2 { bf.WriteUint32(id) } for i := range timestamps { From 67e791be2be00ba27275c539757d033e981a9996 Mon Sep 17 00:00:00 2001 From: wish Date: Thu, 30 Nov 2023 00:31:09 +1100 Subject: [PATCH 22/24] parse & stub PostSeibattle --- network/mhfpacket/msg_mhf_post_seibattle.go | 29 ++++++++++++++++----- server/channelserver/handlers.go | 5 +++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/network/mhfpacket/msg_mhf_post_seibattle.go b/network/mhfpacket/msg_mhf_post_seibattle.go index 7e3e578c4..9c9101747 100644 --- a/network/mhfpacket/msg_mhf_post_seibattle.go +++ b/network/mhfpacket/msg_mhf_post_seibattle.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" ) // MsgMhfPostSeibattle represents the MSG_MHF_POST_SEIBATTLE -type MsgMhfPostSeibattle struct{} +type MsgMhfPostSeibattle struct { + AckHandle uint32 + Unk0 uint8 + Unk1 uint8 + Unk2 uint32 + Unk3 uint8 + Unk4 uint16 + Unk5 uint16 + Unk6 uint8 +} // Opcode returns the ID associated with this packet type. func (m *MsgMhfPostSeibattle) Opcode() network.PacketID { @@ -18,7 +27,15 @@ func (m *MsgMhfPostSeibattle) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfPostSeibattle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint8() + m.Unk1 = bf.ReadUint8() + m.Unk2 = bf.ReadUint32() + m.Unk3 = bf.ReadUint8() + m.Unk4 = bf.ReadUint16() + m.Unk5 = bf.ReadUint16() + m.Unk6 = bf.ReadUint8() + return nil } // Build builds a binary packet from the current data. diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index c94d78305..f4c106fcd 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -1197,7 +1197,10 @@ func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) { doAckEarthSucceed(s, pkt.AckHandle, data) } -func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) {} +func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) { + pkt := p.(*mhfpacket.MsgMhfPostSeibattle) + doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) +} func handleMsgMhfGetDailyMissionMaster(s *Session, p mhfpacket.MHFPacket) {} From a108a675224eb74e5f776f2582385b43d81c7ea7 Mon Sep 17 00:00:00 2001 From: wish Date: Thu, 30 Nov 2023 00:34:51 +1100 Subject: [PATCH 23/24] add support for multiple Conquest War targets --- config.json | 2 +- config/config.go | 2 +- server/channelserver/handlers.go | 15 ++++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/config.json b/config.json index 688a9879b..7b11421a1 100644 --- a/config.json +++ b/config.json @@ -31,7 +31,7 @@ "QuestDebugTools": false, "EarthStatusOverride": 0, "EarthIDOverride": 0, - "EarthMonsterOverride": 0, + "EarthMonsterOverride": [0, 0, 0, 0], "SaveDumps": { "Enabled": true, "OutputDir": "save-backups" diff --git a/config/config.go b/config/config.go index 12cb00316..488321357 100644 --- a/config/config.go +++ b/config/config.go @@ -112,7 +112,7 @@ type DevModeOptions struct { QuestDebugTools bool // Enable various quest debug logs EarthStatusOverride int32 EarthIDOverride int32 - EarthMonsterOverride int32 + EarthMonsterOverride []int32 SaveDumps SaveDumpOptions } diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index f4c106fcd..7886e7745 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -992,11 +992,16 @@ func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(uint32(TimeWeekNext().Unix())) // End bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthStatusOverride) bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthIDOverride) - bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthMonsterOverride) - bf.WriteInt32(0) - bf.WriteInt32(0) - if _config.ErupeConfig.RealClientMode >= _config.G91 { - bf.WriteInt32(0) + for i, m := range s.server.erupeConfig.DevModeOptions.EarthMonsterOverride { + if _config.ErupeConfig.RealClientMode >= _config.G91 { + if i == 3 { + break + } + } + if i == 4 { + break + } + bf.WriteInt32(m) } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } From 51e1860a929f97522accd94bf9583d10a6f294e6 Mon Sep 17 00:00:00 2001 From: wish Date: Thu, 30 Nov 2023 00:35:39 +1100 Subject: [PATCH 24/24] add support for multiple Conquest War targets --- server/channelserver/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 7886e7745..7445d0f2b 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -993,7 +993,7 @@ func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) { bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthStatusOverride) bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthIDOverride) for i, m := range s.server.erupeConfig.DevModeOptions.EarthMonsterOverride { - if _config.ErupeConfig.RealClientMode >= _config.G91 { + if _config.ErupeConfig.RealClientMode <= _config.G9 { if i == 3 { break }