From 5f3c84308285d94290b8c39e7b6b5d6f22ab885f Mon Sep 17 00:00:00 2001 From: Houmgaor Date: Fri, 20 Feb 2026 17:07:42 +0100 Subject: [PATCH] refactor(config): eliminate ErupeConfig global variable Replace the mutable global `_config.ErupeConfig` with dependency injection across 79 files. Config is now threaded through existing paths: `ClientContext.RealClientMode` for packet encoding, `s.server. erupeConfig` for channel handlers, and explicit parameters for utility functions. This removes hidden coupling, enables test parallelism without global save/restore, and prevents low-level packages from reaching up to the config layer. Key changes: - Enrich ClientContext with RealClientMode for packet files - Add mode parameter to CryptConn, mhfitem, mhfcourse functions - Convert handlers_commands init() to lazy sync.Once initialization - Delete global var, init(), and helper functions from config.go - Update all tests to pass config explicitly --- common/mhfcourse/mhfcourse.go | 5 +- common/mhfcourse/mhfcourse_test.go | 67 +++-------------- common/mhfitem/mhfitem.go | 18 ++--- common/mhfitem/mhfitem_test.go | 59 +++++---------- config/config.go | 49 ------------- config/config_test.go | 15 ---- main.go | 50 +++++++------ network/clientctx/clientcontext.go | 6 +- network/crypt_conn.go | 14 ++-- network/crypt_conn_test.go | 69 +++++------------- network/mhfpacket/mhfpacket_test.go | 40 +++++------ network/mhfpacket/msg_batch_parse_test.go | 47 ++++++------ .../msg_build_coverage_extended_test.go | 5 +- network/mhfpacket/msg_build_test.go | 71 ++++++++++--------- network/mhfpacket/msg_comprehensive_test.go | 9 +-- .../mhfpacket/msg_mhf_acquire_cafe_item.go | 2 +- .../msg_mhf_acquire_cafe_item_test.go | 15 ++-- network/mhfpacket/msg_mhf_acquire_test.go | 13 ++-- network/mhfpacket/msg_mhf_apply_dist_item.go | 4 +- .../mhfpacket/msg_mhf_enumerate_dist_item.go | 2 +- network/mhfpacket/msg_mhf_enumerate_quest.go | 2 +- network/mhfpacket/msg_mhf_enumerate_shop.go | 2 +- network/mhfpacket/msg_mhf_guacot_test.go | 20 +++--- network/mhfpacket/msg_mhf_packets_test.go | 3 +- network/mhfpacket/msg_mhf_savedata.go | 2 +- network/mhfpacket/msg_mhf_stampcard_stamp.go | 4 +- .../mhfpacket/msg_mhf_update_myhouse_info.go | 6 +- network/mhfpacket/msg_mhf_update_warehouse.go | 2 +- network/mhfpacket/msg_opcode_coverage_test.go | 5 +- network/mhfpacket/msg_parse_coverage_test.go | 13 ++-- network/mhfpacket/msg_parse_large_test.go | 53 +++++++------- network/mhfpacket/msg_parse_medium_test.go | 31 ++++---- network/mhfpacket/msg_parse_small_test.go | 16 +++-- network/mhfpacket/msg_parse_test.go | 15 ++-- network/mhfpacket/msg_sys_core_test.go | 15 ++-- .../msg_sys_create_acquire_semaphore.go | 2 +- network/mhfpacket/msg_sys_create_semaphore.go | 2 +- network/mhfpacket/msg_sys_packets_test.go | 3 +- network/mhfpacket/msg_sys_stage_test.go | 17 ++--- network/mhfpacket/msg_sys_terminal_log.go | 2 +- server/channelserver/guild_model.go | 16 ++--- server/channelserver/handlers_cafe.go | 2 +- server/channelserver/handlers_campaign.go | 2 +- server/channelserver/handlers_character.go | 5 +- .../channelserver/handlers_character_test.go | 33 ++------- server/channelserver/handlers_commands.go | 32 ++++----- .../channelserver/handlers_coverage5_test.go | 32 +++------ server/channelserver/handlers_data.go | 2 +- server/channelserver/handlers_distitem.go | 18 ++--- server/channelserver/handlers_event.go | 10 +-- server/channelserver/handlers_event_test.go | 15 ++-- server/channelserver/handlers_festa.go | 10 +-- .../channelserver/handlers_guild_alliance.go | 6 +- server/channelserver/handlers_guild_info.go | 12 ++-- server/channelserver/handlers_guild_test.go | 7 +- server/channelserver/handlers_helpers.go | 2 +- server/channelserver/handlers_house.go | 8 +-- server/channelserver/handlers_house_test.go | 3 +- server/channelserver/handlers_items.go | 4 +- server/channelserver/handlers_misc.go | 12 ++-- server/channelserver/handlers_quest.go | 48 ++++++------- .../handlers_quest_backport_test.go | 41 ++--------- server/channelserver/handlers_quest_test.go | 5 +- .../handlers_savedata_integration_test.go | 5 +- server/channelserver/handlers_session.go | 24 +++---- server/channelserver/handlers_shop.go | 22 +++--- .../channelserver/handlers_shop_gacha_test.go | 7 +- server/channelserver/handlers_tower.go | 2 +- server/channelserver/integration_test.go | 11 ++- server/channelserver/model_character.go | 19 ++--- .../session_lifecycle_integration_test.go | 6 +- server/channelserver/sys_channel_server.go | 2 + server/channelserver/sys_session.go | 4 +- server/entranceserver/entrance_server.go | 2 +- server/entranceserver/make_resp.go | 4 +- server/signserver/dbutils.go | 2 +- server/signserver/dbutils_test.go | 6 +- server/signserver/session_test.go | 14 ++-- server/signserver/sign_server.go | 2 +- 79 files changed, 509 insertions(+), 723 deletions(-) diff --git a/common/mhfcourse/mhfcourse.go b/common/mhfcourse/mhfcourse.go index 0036c9a93..3d67c2d3b 100644 --- a/common/mhfcourse/mhfcourse.go +++ b/common/mhfcourse/mhfcourse.go @@ -1,7 +1,6 @@ package mhfcourse import ( - _config "erupe-ce/config" "math" "sort" "time" @@ -70,9 +69,9 @@ func CourseExists(ID uint16, c []Course) bool { } // GetCourseStruct returns a slice of Course(s) from a rights integer -func GetCourseStruct(rights uint32) ([]Course, uint32) { +func GetCourseStruct(rights uint32, defaultCourses []uint16) ([]Course, uint32) { var resp []Course - for _, c := range _config.ErupeConfig.DefaultCourses { + for _, c := range defaultCourses { resp = append(resp, Course{ID: c}) } s := Courses() diff --git a/common/mhfcourse/mhfcourse_test.go b/common/mhfcourse/mhfcourse_test.go index fb1c416d8..8eb13646f 100644 --- a/common/mhfcourse/mhfcourse_test.go +++ b/common/mhfcourse/mhfcourse_test.go @@ -1,7 +1,6 @@ package mhfcourse import ( - _config "erupe-ce/config" "math" "testing" "time" @@ -121,14 +120,7 @@ func TestCourseExists_EmptySlice(t *testing.T) { } func TestGetCourseStruct(t *testing.T) { - // Save original config and restore after test - originalDefaultCourses := _config.ErupeConfig.DefaultCourses - defer func() { - _config.ErupeConfig.DefaultCourses = originalDefaultCourses - }() - - // Set up test config - _config.ErupeConfig.DefaultCourses = []uint16{1, 2} + defaultCourses := []uint16{1, 2} tests := []struct { name string @@ -164,7 +156,7 @@ func TestGetCourseStruct(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - courses, newRights := GetCourseStruct(tt.rights) + courses, newRights := GetCourseStruct(tt.rights, defaultCourses) if len(courses) < tt.wantMinLen { t.Errorf("GetCourseStruct(%d) returned %d courses, want at least %d", tt.rights, len(courses), tt.wantMinLen) @@ -193,15 +185,8 @@ func TestGetCourseStruct(t *testing.T) { } func TestGetCourseStruct_NetcafeCourse(t *testing.T) { - // Save original config - originalDefaultCourses := _config.ErupeConfig.DefaultCourses - defer func() { - _config.ErupeConfig.DefaultCourses = originalDefaultCourses - }() - _config.ErupeConfig.DefaultCourses = []uint16{} - // Course 26 (NetCafe) should add course 25 - courses, _ := GetCourseStruct(1 << 26) + courses, _ := GetCourseStruct(1<<26, nil) hasNetcafe := false hasCafeSP := false @@ -230,15 +215,8 @@ func TestGetCourseStruct_NetcafeCourse(t *testing.T) { } func TestGetCourseStruct_NCourse(t *testing.T) { - // Save original config - originalDefaultCourses := _config.ErupeConfig.DefaultCourses - defer func() { - _config.ErupeConfig.DefaultCourses = originalDefaultCourses - }() - _config.ErupeConfig.DefaultCourses = []uint16{} - // Course 9 should add course 30 - courses, _ := GetCourseStruct(1 << 9) + courses, _ := GetCourseStruct(1<<9, nil) hasNCourse := false hasRealNetcafe := false @@ -260,15 +238,8 @@ func TestGetCourseStruct_NCourse(t *testing.T) { } func TestGetCourseStruct_HidenCourse(t *testing.T) { - // Save original config - originalDefaultCourses := _config.ErupeConfig.DefaultCourses - defer func() { - _config.ErupeConfig.DefaultCourses = originalDefaultCourses - }() - _config.ErupeConfig.DefaultCourses = []uint16{} - // Course 10 (Hiden) should add course 31 - courses, _ := GetCourseStruct(1 << 10) + courses, _ := GetCourseStruct(1<<10, nil) hasHiden := false hasHidenExtra := false @@ -290,14 +261,7 @@ func TestGetCourseStruct_HidenCourse(t *testing.T) { } func TestGetCourseStruct_ExpiryDate(t *testing.T) { - // Save original config - originalDefaultCourses := _config.ErupeConfig.DefaultCourses - defer func() { - _config.ErupeConfig.DefaultCourses = originalDefaultCourses - }() - _config.ErupeConfig.DefaultCourses = []uint16{} - - courses, _ := GetCourseStruct(1 << 3) + courses, _ := GetCourseStruct(1<<3, nil) expectedExpiry := time.Date(2030, 1, 1, 0, 0, 0, 0, time.FixedZone("UTC+9", 9*60*60)) @@ -311,14 +275,7 @@ func TestGetCourseStruct_ExpiryDate(t *testing.T) { } func TestGetCourseStruct_ReturnsRecalculatedRights(t *testing.T) { - // Save original config - originalDefaultCourses := _config.ErupeConfig.DefaultCourses - defer func() { - _config.ErupeConfig.DefaultCourses = originalDefaultCourses - }() - _config.ErupeConfig.DefaultCourses = []uint16{} - - courses, newRights := GetCourseStruct(2 + 8 + 32) // courses 1, 3, 5 + courses, newRights := GetCourseStruct(2+8+32, nil) // courses 1, 3, 5 // Calculate expected rights from returned courses var expectedRights uint32 @@ -363,17 +320,11 @@ func BenchmarkCourseExists(b *testing.B) { } func BenchmarkGetCourseStruct(b *testing.B) { - // Save original config - originalDefaultCourses := _config.ErupeConfig.DefaultCourses - defer func() { - _config.ErupeConfig.DefaultCourses = originalDefaultCourses - }() - _config.ErupeConfig.DefaultCourses = []uint16{1, 2} - + defaultCourses := []uint16{1, 2} rights := uint32(2 + 8 + 32 + 128 + 512) b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = GetCourseStruct(rights) + _, _ = GetCourseStruct(rights, defaultCourses) } } diff --git a/common/mhfitem/mhfitem.go b/common/mhfitem/mhfitem.go index 9486a6714..892ecf4f8 100644 --- a/common/mhfitem/mhfitem.go +++ b/common/mhfitem/mhfitem.go @@ -3,7 +3,7 @@ package mhfitem import ( "erupe-ce/common/byteframe" "erupe-ce/common/token" - _config "erupe-ce/config" + "erupe-ce/config" ) // MHFItem represents a single item identified by its in-game item ID. @@ -113,7 +113,7 @@ func SerializeWarehouseItems(i []MHFItemStack) []byte { // ReadWarehouseEquipment deserializes an MHFEquipment from a ByteFrame. The // binary layout varies by game version: sigils are present from G1 onward and // an additional field is present from Z1 onward. -func ReadWarehouseEquipment(bf *byteframe.ByteFrame) MHFEquipment { +func ReadWarehouseEquipment(bf *byteframe.ByteFrame, mode _config.Mode) MHFEquipment { var equipment MHFEquipment equipment.Decorations = make([]MHFItem, 3) equipment.Sigils = make([]MHFSigil, 3) @@ -131,7 +131,7 @@ func ReadWarehouseEquipment(bf *byteframe.ByteFrame) MHFEquipment { for i := 0; i < 3; i++ { equipment.Decorations[i].ItemID = bf.ReadUint16() } - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if mode >= _config.G1 { for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { equipment.Sigils[i].Effects[j].ID = bf.ReadUint16() @@ -145,14 +145,14 @@ func ReadWarehouseEquipment(bf *byteframe.ByteFrame) MHFEquipment { equipment.Sigils[i].Unk3 = bf.ReadUint8() } } - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if mode >= _config.Z1 { equipment.Unk1 = bf.ReadUint16() } return equipment } // ToBytes serializes the equipment to its binary protocol representation. -func (e MHFEquipment) ToBytes() []byte { +func (e MHFEquipment) ToBytes(mode _config.Mode) []byte { bf := byteframe.NewByteFrame() bf.WriteUint32(e.WarehouseID) bf.WriteUint8(e.ItemType) @@ -162,7 +162,7 @@ func (e MHFEquipment) ToBytes() []byte { for i := 0; i < 3; i++ { bf.WriteUint16(e.Decorations[i].ItemID) } - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if mode >= _config.G1 { for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { bf.WriteUint16(e.Sigils[i].Effects[j].ID) @@ -176,7 +176,7 @@ func (e MHFEquipment) ToBytes() []byte { bf.WriteUint8(e.Sigils[i].Unk3) } } - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if mode >= _config.Z1 { bf.WriteUint16(e.Unk1) } return bf.Data() @@ -184,12 +184,12 @@ func (e MHFEquipment) ToBytes() []byte { // SerializeWarehouseEquipment serializes a slice of equipment with a uint16 // count header for transmission in warehouse response packets. -func SerializeWarehouseEquipment(i []MHFEquipment) []byte { +func SerializeWarehouseEquipment(i []MHFEquipment, mode _config.Mode) []byte { bf := byteframe.NewByteFrame() bf.WriteUint16(uint16(len(i))) bf.WriteUint16(0) // Unused for _, j := range i { - bf.WriteBytes(j.ToBytes()) + bf.WriteBytes(j.ToBytes(mode)) } return bf.Data() } diff --git a/common/mhfitem/mhfitem_test.go b/common/mhfitem/mhfitem_test.go index 87528951e..306771c55 100644 --- a/common/mhfitem/mhfitem_test.go +++ b/common/mhfitem/mhfitem_test.go @@ -119,11 +119,11 @@ func TestSerializeWarehouseItems_Empty(t *testing.T) { func TestDiffItemStacks(t *testing.T) { tests := []struct { - name string - old []MHFItemStack - update []MHFItemStack - wantLen int - checkFn func(t *testing.T, result []MHFItemStack) + name string + old []MHFItemStack + update []MHFItemStack + wantLen int + checkFn func(t *testing.T, result []MHFItemStack) }{ { name: "update existing quantity", @@ -210,12 +210,7 @@ func TestDiffItemStacks(t *testing.T) { } func TestReadWarehouseEquipment(t *testing.T) { - // Save original config - originalMode := _config.ErupeConfig.RealClientMode - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - _config.ErupeConfig.RealClientMode = _config.Z1 + mode := _config.Z1 bf := byteframe.NewByteFrame() bf.WriteUint32(12345) // WarehouseID @@ -248,7 +243,7 @@ func TestReadWarehouseEquipment(t *testing.T) { bf.WriteUint16(9999) _, _ = bf.Seek(0, 0) - equipment := ReadWarehouseEquipment(bf) + equipment := ReadWarehouseEquipment(bf, mode) if equipment.WarehouseID != 12345 { t.Errorf("WarehouseID = %d, want 12345", equipment.WarehouseID) @@ -274,12 +269,7 @@ func TestReadWarehouseEquipment(t *testing.T) { } func TestReadWarehouseEquipment_ZeroWarehouseID(t *testing.T) { - // Save original config - originalMode := _config.ErupeConfig.RealClientMode - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - _config.ErupeConfig.RealClientMode = _config.Z1 + mode := _config.Z1 bf := byteframe.NewByteFrame() bf.WriteUint32(0) // WarehouseID = 0 @@ -304,7 +294,7 @@ func TestReadWarehouseEquipment_ZeroWarehouseID(t *testing.T) { bf.WriteUint16(0) _, _ = bf.Seek(0, 0) - equipment := ReadWarehouseEquipment(bf) + equipment := ReadWarehouseEquipment(bf, mode) if equipment.WarehouseID == 0 { t.Error("WarehouseID should be replaced with random value when input is 0") @@ -312,12 +302,7 @@ func TestReadWarehouseEquipment_ZeroWarehouseID(t *testing.T) { } func TestMHFEquipment_ToBytes(t *testing.T) { - // Save original config - originalMode := _config.ErupeConfig.RealClientMode - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - _config.ErupeConfig.RealClientMode = _config.Z1 + mode := _config.Z1 equipment := MHFEquipment{ WarehouseID: 12345, @@ -333,9 +318,9 @@ func TestMHFEquipment_ToBytes(t *testing.T) { equipment.Sigils[i].Effects = make([]MHFSigilEffect, 3) } - data := equipment.ToBytes() + data := equipment.ToBytes(mode) bf := byteframe.NewByteFrameFromBytes(data) - readEquipment := ReadWarehouseEquipment(bf) + readEquipment := ReadWarehouseEquipment(bf, mode) if readEquipment.WarehouseID != equipment.WarehouseID { t.Errorf("WarehouseID = %d, want %d", readEquipment.WarehouseID, equipment.WarehouseID) @@ -352,12 +337,7 @@ func TestMHFEquipment_ToBytes(t *testing.T) { } func TestSerializeWarehouseEquipment(t *testing.T) { - // Save original config - originalMode := _config.ErupeConfig.RealClientMode - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - _config.ErupeConfig.RealClientMode = _config.Z1 + mode := _config.Z1 equipment := []MHFEquipment{ { @@ -383,7 +363,7 @@ func TestSerializeWarehouseEquipment(t *testing.T) { } } - data := SerializeWarehouseEquipment(equipment) + data := SerializeWarehouseEquipment(equipment, mode) bf := byteframe.NewByteFrameFromBytes(data) count := bf.ReadUint16() @@ -393,12 +373,7 @@ func TestSerializeWarehouseEquipment(t *testing.T) { } func TestMHFEquipment_RoundTrip(t *testing.T) { - // Test that we can write and read back the same equipment - originalMode := _config.ErupeConfig.RealClientMode - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - _config.ErupeConfig.RealClientMode = _config.Z1 + mode := _config.Z1 original := MHFEquipment{ WarehouseID: 99999, @@ -419,11 +394,11 @@ func TestMHFEquipment_RoundTrip(t *testing.T) { } // Write to bytes - data := original.ToBytes() + data := original.ToBytes(mode) // Read back bf := byteframe.NewByteFrameFromBytes(data) - recovered := ReadWarehouseEquipment(bf) + recovered := ReadWarehouseEquipment(bf, mode) // Compare if recovered.WarehouseID != original.WarehouseID { diff --git a/config/config.go b/config/config.go index 6c26798aa..73f47bc98 100644 --- a/config/config.go +++ b/config/config.go @@ -1,12 +1,9 @@ package _config import ( - "fmt" "log" "net" - "os" "strings" - "time" "github.com/spf13/viper" ) @@ -308,36 +305,6 @@ func (c *EntranceChannelInfo) IsEnabled() bool { return *c.Enabled } -var ErupeConfig *Config - -func init() { - var err error - ErupeConfig, err = LoadConfig() - if err != nil { - // In test environments or when config.toml is missing, use defaults - ErupeConfig = &Config{ - ClientMode: "ZZ", - RealClientMode: ZZ, - } - // Only call preventClose if it's not a test environment - if !isTestEnvironment() { - preventClose(fmt.Sprintf("Failed to load config: %s", err.Error())) - } - } -} - -func isTestEnvironment() bool { - // Check if we're running under test - for _, arg := range os.Args { - if arg == "-test.v" || arg == "-test.run" || arg == "-test.timeout" { - return true - } - if strings.Contains(arg, "test") { - return true - } - } - return false -} // getOutboundIP4 gets the preferred outbound ip4 of this machine // From https://stackoverflow.com/a/37382208 @@ -399,19 +366,3 @@ func LoadConfig() (*Config, error) { return c, nil } -func preventClose(text string) { - if ErupeConfig != nil && ErupeConfig.DisableSoftCrash { - os.Exit(0) - } - fmt.Println("\nFailed to start Erupe:\n" + text) - go wait() - fmt.Println("\nPress Enter/Return to exit...") - _, _ = fmt.Scanln() - os.Exit(0) -} - -func wait() { - for { - time.Sleep(time.Millisecond * 100) - } -} diff --git a/config/config_test.go b/config/config_test.go index cbad553ec..d7ca42a24 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -94,14 +94,6 @@ func TestModeConstants(t *testing.T) { } } -// TestIsTestEnvironment tests the isTestEnvironment function -func TestIsTestEnvironment(t *testing.T) { - result := isTestEnvironment() - if !result { - t.Error("isTestEnvironment() should return true when running tests") - } -} - // TestVersionStringsLength verifies versionStrings has correct length func TestVersionStringsLength(t *testing.T) { expectedCount := 41 // S1 through ZZ = 41 versions @@ -708,10 +700,3 @@ func BenchmarkGetOutboundIP4(b *testing.B) { } } -// BenchmarkIsTestEnvironment benchmarks test environment detection -func BenchmarkIsTestEnvironment(b *testing.B) { - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = isTestEnvironment() - } -} diff --git a/main.go b/main.go index c6da1c977..82becbddf 100644 --- a/main.go +++ b/main.go @@ -42,26 +42,26 @@ var Commit = func() string { return "unknown" } -func setupDiscordBot(logger *zap.Logger) *discordbot.DiscordBot { +func setupDiscordBot(config *_config.Config, logger *zap.Logger) *discordbot.DiscordBot { bot, err := discordbot.NewDiscordBot(discordbot.Options{ Logger: logger, - Config: _config.ErupeConfig, + Config: config, }) if err != nil { - preventClose(fmt.Sprintf("Discord: Failed to start, %s", err.Error())) + preventClose(config, fmt.Sprintf("Discord: Failed to start, %s", err.Error())) } // Discord bot err = bot.Start() if err != nil { - preventClose(fmt.Sprintf("Discord: Failed to start, %s", err.Error())) + preventClose(config, fmt.Sprintf("Discord: Failed to start, %s", err.Error())) } _, err = bot.Session.ApplicationCommandBulkOverwrite(bot.Session.State.User.ID, "", discordbot.Commands) if err != nil { - preventClose(fmt.Sprintf("Discord: Failed to start, %s", err.Error())) + preventClose(config, fmt.Sprintf("Discord: Failed to start, %s", err.Error())) } return bot @@ -71,17 +71,25 @@ func main() { var err error var zapLogger *zap.Logger - config := _config.ErupeConfig zapLogger, _ = zap.NewDevelopment() defer func() { _ = zapLogger.Sync() }() logger := zapLogger.Named("main") + config, cfgErr := _config.LoadConfig() + if cfgErr != nil { + fmt.Println("\nFailed to start Erupe:\n" + fmt.Sprintf("Failed to load config: %s", cfgErr.Error())) + go wait() + fmt.Println("\nPress Enter/Return to exit...") + _, _ = fmt.Scanln() + os.Exit(0) + } + logger.Info(fmt.Sprintf("Starting Erupe (9.3b-%s)", Commit())) logger.Info(fmt.Sprintf("Client Mode: %s (%d)", config.ClientMode, config.RealClientMode)) if config.Database.Password == "" { - preventClose("Database password is blank") + preventClose(config, "Database password is blank") } if net.ParseIP(config.Host) == nil { @@ -93,7 +101,7 @@ func main() { } } if net.ParseIP(config.Host) == nil { - preventClose("Invalid host address") + preventClose(config, "Invalid host address") } } @@ -101,7 +109,7 @@ func main() { var discordBot *discordbot.DiscordBot = nil if config.Discord.Enabled { - discordBot = setupDiscordBot(logger) + discordBot = setupDiscordBot(config, logger) logger.Info("Discord: Started successfully") } else { @@ -120,13 +128,13 @@ func main() { db, err := sqlx.Open("postgres", connectString) if err != nil { - preventClose(fmt.Sprintf("Database: Failed to open, %s", err.Error())) + preventClose(config, fmt.Sprintf("Database: Failed to open, %s", err.Error())) } // Test the DB connection. err = db.Ping() if err != nil { - preventClose(fmt.Sprintf("Database: Failed to ping, %s", err.Error())) + preventClose(config, fmt.Sprintf("Database: Failed to ping, %s", err.Error())) } logger.Info("Database: Started successfully") @@ -174,12 +182,12 @@ func main() { entranceServer = entranceserver.NewServer( &entranceserver.Config{ Logger: logger.Named("entrance"), - ErupeConfig: _config.ErupeConfig, + ErupeConfig: config, DB: db, }) err = entranceServer.Start() if err != nil { - preventClose(fmt.Sprintf("Entrance: Failed to start, %s", err.Error())) + preventClose(config, fmt.Sprintf("Entrance: Failed to start, %s", err.Error())) } logger.Info("Entrance: Started successfully") } else { @@ -193,12 +201,12 @@ func main() { signServer = signserver.NewServer( &signserver.Config{ Logger: logger.Named("sign"), - ErupeConfig: _config.ErupeConfig, + ErupeConfig: config, DB: db, }) err = signServer.Start() if err != nil { - preventClose(fmt.Sprintf("Sign: Failed to start, %s", err.Error())) + preventClose(config, fmt.Sprintf("Sign: Failed to start, %s", err.Error())) } logger.Info("Sign: Started successfully") } else { @@ -211,12 +219,12 @@ func main() { ApiServer = api.NewAPIServer( &api.Config{ Logger: logger.Named("sign"), - ErupeConfig: _config.ErupeConfig, + ErupeConfig: config, DB: db, }) err = ApiServer.Start() if err != nil { - preventClose(fmt.Sprintf("API: Failed to start, %s", err.Error())) + preventClose(config, fmt.Sprintf("API: Failed to start, %s", err.Error())) } logger.Info("API: Started successfully") } else { @@ -242,7 +250,7 @@ func main() { c := *channelserver.NewServer(&channelserver.Config{ ID: uint16(sid), Logger: logger.Named("channel-" + fmt.Sprint(count)), - ErupeConfig: _config.ErupeConfig, + ErupeConfig: config, DB: db, DiscordBot: discordBot, }) @@ -255,7 +263,7 @@ func main() { c.GlobalID = fmt.Sprintf("%02d%02d", j+1, i+1) err = c.Start() if err != nil { - preventClose(fmt.Sprintf("Channel: Failed to start, %s", err.Error())) + preventClose(config, fmt.Sprintf("Channel: Failed to start, %s", err.Error())) } else { channelQuery += fmt.Sprintf( `INSERT INTO servers (server_id, current_players, world_name, world_description, land) VALUES (%d, 0, '%s', '%s', %d);`, @@ -326,8 +334,8 @@ func wait() { } } -func preventClose(text string) { - if _config.ErupeConfig.DisableSoftCrash { +func preventClose(config *_config.Config, text string) { + if config != nil && config.DisableSoftCrash { os.Exit(0) } fmt.Println("\nFailed to start Erupe:\n" + text) diff --git a/network/clientctx/clientcontext.go b/network/clientctx/clientcontext.go index 95245888b..6afe33bf4 100644 --- a/network/clientctx/clientcontext.go +++ b/network/clientctx/clientcontext.go @@ -1,4 +1,8 @@ package clientctx +import "erupe-ce/config" + // ClientContext holds contextual data required for packet encoding/decoding. -type ClientContext struct{} +type ClientContext struct { + RealClientMode _config.Mode +} diff --git a/network/crypt_conn.go b/network/crypt_conn.go index a1793200c..011877da1 100644 --- a/network/crypt_conn.go +++ b/network/crypt_conn.go @@ -3,7 +3,7 @@ package network import ( "encoding/hex" "errors" - _config "erupe-ce/config" + "erupe-ce/config" "erupe-ce/network/crypto" "fmt" "io" @@ -24,6 +24,7 @@ type Conn interface { // it automatically handles encryption, decryption, and key rotation via it's methods. type CryptConn struct { conn net.Conn + realClientMode _config.Mode readKeyRot uint32 sendKeyRot uint32 sentPackets int32 @@ -32,11 +33,12 @@ type CryptConn struct { } // NewCryptConn creates a new CryptConn with proper default values. -func NewCryptConn(conn net.Conn) *CryptConn { +func NewCryptConn(conn net.Conn, mode _config.Mode) *CryptConn { cc := &CryptConn{ - conn: conn, - readKeyRot: 995117, - sendKeyRot: 995117, + conn: conn, + realClientMode: mode, + readKeyRot: 995117, + sendKeyRot: 995117, } return cc } @@ -61,7 +63,7 @@ func (cc *CryptConn) ReadPacket() ([]byte, error) { var encryptedPacketBody []byte // Don't know when support for this was added, works in Forward.4, doesn't work in Season 6.0 - if _config.ErupeConfig.RealClientMode < _config.F1 { + if cc.realClientMode < _config.F1 { encryptedPacketBody = make([]byte, cph.DataSize) } else { encryptedPacketBody = make([]byte, uint32(cph.DataSize)+(uint32(cph.Pf0-0x03)*0x1000)) diff --git a/network/crypt_conn_test.go b/network/crypt_conn_test.go index b1893714e..61b107ee1 100644 --- a/network/crypt_conn_test.go +++ b/network/crypt_conn_test.go @@ -54,7 +54,7 @@ func (m *mockConn) SetWriteDeadline(t time.Time) error { return nil } func TestNewCryptConn(t *testing.T) { mockConn := newMockConn(nil) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.ZZ) if cc == nil { t.Fatal("NewCryptConn() returned nil") @@ -83,15 +83,13 @@ func TestNewCryptConn(t *testing.T) { if cc.prevSendPacketCombinedCheck != 0 { t.Errorf("prevSendPacketCombinedCheck = %d, want 0", cc.prevSendPacketCombinedCheck) } + + if cc.realClientMode != _config.ZZ { + t.Errorf("realClientMode = %d, want %d", cc.realClientMode, _config.ZZ) + } } func TestCryptConn_SendPacket(t *testing.T) { - // Save original config and restore after test - originalMode := _config.ErupeConfig.RealClientMode - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - tests := []struct { name string data []byte @@ -113,7 +111,7 @@ func TestCryptConn_SendPacket(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mockConn := newMockConn(nil) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.ZZ) err := cc.SendPacket(tt.data) if err != nil { @@ -157,7 +155,7 @@ func TestCryptConn_SendPacket(t *testing.T) { func TestCryptConn_SendPacket_MultiplePackets(t *testing.T) { mockConn := newMockConn(nil) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.ZZ) // Send first packet err := cc.SendPacket([]byte{0x01, 0x02}) @@ -192,7 +190,7 @@ func TestCryptConn_SendPacket_MultiplePackets(t *testing.T) { func TestCryptConn_SendPacket_KeyRotation(t *testing.T) { mockConn := newMockConn(nil) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.ZZ) initialKey := cc.sendKeyRot @@ -211,7 +209,7 @@ func TestCryptConn_SendPacket_KeyRotation(t *testing.T) { func TestCryptConn_SendPacket_WriteError(t *testing.T) { mockConn := newMockConn(nil) mockConn.writeErr = errors.New("write error") - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.ZZ) err := cc.SendPacket([]byte{0x01, 0x02, 0x03}) // Note: Current implementation doesn't return write error @@ -222,13 +220,6 @@ func TestCryptConn_SendPacket_WriteError(t *testing.T) { } func TestCryptConn_ReadPacket_Success(t *testing.T) { - // Save original config and restore after test - originalMode := _config.ErupeConfig.RealClientMode - _config.ErupeConfig.RealClientMode = _config.Z1 // Use older mode for simpler test - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - testData := []byte{0x74, 0x65, 0x73, 0x74} // "test" key := uint32(0) @@ -253,7 +244,7 @@ func TestCryptConn_ReadPacket_Success(t *testing.T) { packet := append(headerBytes, encryptedData...) mockConn := newMockConn(packet) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.Z1) // Set the key to match what we used for encryption cc.readKeyRot = key @@ -273,13 +264,6 @@ func TestCryptConn_ReadPacket_Success(t *testing.T) { } func TestCryptConn_ReadPacket_KeyRotation(t *testing.T) { - // Save original config and restore after test - originalMode := _config.ErupeConfig.RealClientMode - _config.ErupeConfig.RealClientMode = _config.Z1 - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - testData := []byte{0x01, 0x02, 0x03, 0x04} key := uint32(995117) keyRotDelta := byte(3) @@ -306,7 +290,7 @@ func TestCryptConn_ReadPacket_KeyRotation(t *testing.T) { packet := append(headerBytes, encryptedData...) mockConn := newMockConn(packet) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.Z1) cc.readKeyRot = key result, err := cc.ReadPacket() @@ -325,13 +309,6 @@ func TestCryptConn_ReadPacket_KeyRotation(t *testing.T) { } func TestCryptConn_ReadPacket_NoKeyRotation(t *testing.T) { - // Save original config and restore after test - originalMode := _config.ErupeConfig.RealClientMode - _config.ErupeConfig.RealClientMode = _config.Z1 - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - testData := []byte{0x01, 0x02} key := uint32(12345) @@ -353,7 +330,7 @@ func TestCryptConn_ReadPacket_NoKeyRotation(t *testing.T) { packet := append(headerBytes, encryptedData...) mockConn := newMockConn(packet) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.Z1) cc.readKeyRot = key originalKeyRot := cc.readKeyRot @@ -375,7 +352,7 @@ func TestCryptConn_ReadPacket_NoKeyRotation(t *testing.T) { func TestCryptConn_ReadPacket_HeaderReadError(t *testing.T) { mockConn := newMockConn([]byte{0x01, 0x02}) // Only 2 bytes, header needs 14 - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.ZZ) _, err := cc.ReadPacket() if err == nil { @@ -391,7 +368,7 @@ func TestCryptConn_ReadPacket_InvalidHeader(t *testing.T) { // Create invalid header data (wrong endianness or malformed) invalidHeader := []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} mockConn := newMockConn(invalidHeader) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.ZZ) _, err := cc.ReadPacket() if err == nil { @@ -400,13 +377,6 @@ func TestCryptConn_ReadPacket_InvalidHeader(t *testing.T) { } func TestCryptConn_ReadPacket_BodyReadError(t *testing.T) { - // Save original config and restore after test - originalMode := _config.ErupeConfig.RealClientMode - _config.ErupeConfig.RealClientMode = _config.Z1 - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - // Create valid header but incomplete body header := &CryptPacketHeader{ Pf0: 0x03, @@ -425,7 +395,7 @@ func TestCryptConn_ReadPacket_BodyReadError(t *testing.T) { packet := append(headerBytes, incompleteBody...) mockConn := newMockConn(packet) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.Z1) _, err := cc.ReadPacket() if err == nil { @@ -434,13 +404,6 @@ func TestCryptConn_ReadPacket_BodyReadError(t *testing.T) { } func TestCryptConn_ReadPacket_ChecksumMismatch(t *testing.T) { - // Save original config and restore after test - originalMode := _config.ErupeConfig.RealClientMode - _config.ErupeConfig.RealClientMode = _config.Z1 - defer func() { - _config.ErupeConfig.RealClientMode = originalMode - }() - testData := []byte{0x01, 0x02, 0x03, 0x04} key := uint32(0) @@ -462,7 +425,7 @@ func TestCryptConn_ReadPacket_ChecksumMismatch(t *testing.T) { packet := append(headerBytes, encryptedData...) mockConn := newMockConn(packet) - cc := NewCryptConn(mockConn) + cc := NewCryptConn(mockConn, _config.Z1) cc.readKeyRot = key _, err := cc.ReadPacket() diff --git a/network/mhfpacket/mhfpacket_test.go b/network/mhfpacket/mhfpacket_test.go index a31493563..83e4a6df2 100644 --- a/network/mhfpacket/mhfpacket_test.go +++ b/network/mhfpacket/mhfpacket_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" "erupe-ce/network/clientctx" ) @@ -63,7 +64,7 @@ func TestMsgSysPingRoundTrip(t *testing.T) { AckHandle: 0x12345678, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build bf := byteframe.NewByteFrame() @@ -105,7 +106,7 @@ func TestMsgSysTimeRoundTrip(t *testing.T) { Timestamp: tt.timestamp, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build bf := byteframe.NewByteFrame() @@ -239,7 +240,7 @@ func TestParserInterface(t *testing.T) { bf.WriteUint32(123) _, _ = bf.Seek(0, io.SeekStart) - err := p.Parse(bf, &clientctx.ClientContext{}) + err := p.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Errorf("Parse() error = %v", err) } @@ -250,7 +251,7 @@ func TestBuilderInterface(t *testing.T) { var b Builder = &MsgSysPing{AckHandle: 456} bf := byteframe.NewByteFrame() - err := b.Build(bf, &clientctx.ClientContext{}) + err := b.Build(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Errorf("Build() error = %v", err) } @@ -269,24 +270,21 @@ func TestOpcoderInterface(t *testing.T) { } } -func TestClientContextNilSafe(t *testing.T) { - // Some packets may need to handle nil ClientContext +func TestClientContextBuildSafe(t *testing.T) { pkt := &MsgSysPing{AckHandle: 123} bf := byteframe.NewByteFrame() - // This should not panic even with nil context (implementation dependent) - // Note: The actual behavior depends on implementation - err := pkt.Build(bf, nil) + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} + err := pkt.Build(bf, ctx) if err != nil { - // Error is acceptable if nil context is not supported - t.Logf("Build() with nil context returned error: %v", err) + t.Logf("Build() returned error: %v", err) } } func TestMsgSysPingBuildFormat(t *testing.T) { pkt := &MsgSysPing{AckHandle: 0x12345678} bf := byteframe.NewByteFrame() - _ = pkt.Build(bf, &clientctx.ClientContext{}) + _ = pkt.Build(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) data := bf.Data() if len(data) != 4 { @@ -305,7 +303,7 @@ func TestMsgSysTimeBuildFormat(t *testing.T) { Timestamp: 0xDEADBEEF, } bf := byteframe.NewByteFrame() - _ = pkt.Build(bf, &clientctx.ClientContext{}) + _ = pkt.Build(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) data := bf.Data() if len(data) != 5 { @@ -504,7 +502,7 @@ func TestMsgSysCreateStageParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCreateStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -556,7 +554,7 @@ func TestMsgSysEnterStageParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysEnterStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -605,7 +603,7 @@ func TestMsgSysMoveStageParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysMoveStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -651,7 +649,7 @@ func TestMsgSysLockStageParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLockStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -678,7 +676,7 @@ func TestMsgSysUnlockStageRoundTrip(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build (returns NOT IMPLEMENTED) original := &MsgSysUnlockStage{} @@ -719,7 +717,7 @@ func TestMsgSysBackStageParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysBackStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -749,7 +747,7 @@ func TestMsgSysLogoutParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLogout{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -803,7 +801,7 @@ func TestMsgSysLoginParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLogin{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } diff --git a/network/mhfpacket/msg_batch_parse_test.go b/network/mhfpacket/msg_batch_parse_test.go index 012af407d..f24621921 100644 --- a/network/mhfpacket/msg_batch_parse_test.go +++ b/network/mhfpacket/msg_batch_parse_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -52,7 +53,7 @@ func TestBatchParseAckHandleOnly(t *testing.T) { {"MsgMhfLoadPlateMyset", &MsgMhfLoadPlateMyset{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tc := range packets { t.Run(tc.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -97,7 +98,7 @@ func TestBatchParseTwoUint32(t *testing.T) { {"MsgMhfInfoJoint", &MsgMhfInfoJoint{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tc := range packets { t.Run(tc.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -116,7 +117,7 @@ func TestBatchParseTwoUint32(t *testing.T) { // TestBatchParseMultiField tests packets with various field combinations. func TestBatchParseMultiField(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgMhfGetRengokuBinary", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -1041,7 +1042,7 @@ func TestBatchParseMultiField(t *testing.T) { // TestBatchParseVariableLength tests packets with variable-length data. func TestBatchParseVariableLength(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgMhfSaveFavoriteQuest", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -1344,7 +1345,7 @@ func TestBatchParseArrangeGuildMember(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfArrangeGuildMember{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } if len(pkt.CharIDs) != 3 || pkt.CharIDs[2] != 30 { @@ -1373,7 +1374,7 @@ func TestBatchParseUpdateGuildIcon(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfUpdateGuildIcon{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } if len(pkt.IconParts) != 1 || pkt.IconParts[0].Red != 0xFF { @@ -1392,7 +1393,7 @@ func TestBatchParseSysLoadRegister(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLoadRegister{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } if pkt.RegisterID != 2 || pkt.Values != 3 { @@ -1412,7 +1413,7 @@ func TestBatchParseSysLoadRegisterNonZeroPadding(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLoadRegister{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1438,7 +1439,7 @@ func TestBatchParseSysOperateRegister(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysOperateRegister{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } if len(pkt.RawDataPayload) != 3 { @@ -1457,7 +1458,7 @@ func TestBatchParseSysOperateRegisterNonZeroPadding(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysOperateRegister{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1474,7 +1475,7 @@ func TestBatchParseSysOperateRegisterNonZeroPadding(t *testing.T) { // TestBatchParseSysGetFile tests the conditional scenario file packet. func TestBatchParseSysGetFile(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("non-scenario", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -1529,7 +1530,7 @@ func TestBatchParseSysTerminalLog(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysTerminalLog{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } if len(pkt.Entries) != 1 || pkt.Entries[0].Type1 != 1 { @@ -1539,7 +1540,7 @@ func TestBatchParseSysTerminalLog(t *testing.T) { // TestBatchParseNoOpPackets tests packets with empty Parse (return nil). func TestBatchParseNoOpPackets(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() packets := []struct { @@ -1563,7 +1564,7 @@ func TestBatchParseNoOpPackets(t *testing.T) { // TestBatchParseNotImplemented tests that Parse returns NOT IMPLEMENTED for stub packets. func TestBatchParseNotImplemented(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() packets := []MHFPacket{ @@ -1609,7 +1610,7 @@ func TestBatchParseNotImplemented(t *testing.T) { // TestBatchBuildNotImplemented tests that Build returns NOT IMPLEMENTED for many packets. func TestBatchBuildNotImplemented(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() packets := []MHFPacket{ @@ -1720,7 +1721,7 @@ func TestBatchBuildNotImplemented(t *testing.T) { // TestBatchParseReserve188and18B tests reserve packets with AckHandle. func TestBatchParseReserve188and18B(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tc := range []struct { name string @@ -1742,7 +1743,7 @@ func TestBatchParseReserve188and18B(t *testing.T) { // TestBatchParseStageStringPackets tests packets that read a stage ID string. func TestBatchParseStageStringPackets(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgSysGetStageBinary", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -1848,7 +1849,7 @@ func TestBatchParseStampcardStamp(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfStampcardStamp{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } if pkt.HR != 2 || pkt.GR != 3 || pkt.Stamps != 4 || pkt.Reward1 != 5 { @@ -1869,7 +1870,7 @@ func TestBatchParseAnnounce(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAnnounce{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } if pkt.IPAddress != 0x7F000001 || pkt.Port != 54001 { @@ -1879,7 +1880,7 @@ func TestBatchParseAnnounce(t *testing.T) { // TestBatchParseOprtMail tests conditional parsing. func TestBatchParseOprtMail(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("delete", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -1925,7 +1926,7 @@ func TestBatchParsePostTowerInfo(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfPostTowerInfo{} - if err := pkt.Parse(bf, &clientctx.ClientContext{}); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatal(err) } } @@ -1933,7 +1934,7 @@ func TestBatchParsePostTowerInfo(t *testing.T) { // TestBatchParseGuildHuntdata tests conditional guild huntdata. // TestBatchParseAdditionalMultiField tests Parse for more packets with multiple fields. func TestBatchParseAdditionalMultiField(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgMhfAcquireFesta", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -2202,7 +2203,7 @@ func TestBatchParseAdditionalMultiField(t *testing.T) { } func TestBatchParseGuildHuntdata(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("operation_0", func(t *testing.T) { bf := byteframe.NewByteFrame() diff --git a/network/mhfpacket/msg_build_coverage_extended_test.go b/network/mhfpacket/msg_build_coverage_extended_test.go index 65bf1e7f6..d3002069a 100644 --- a/network/mhfpacket/msg_build_coverage_extended_test.go +++ b/network/mhfpacket/msg_build_coverage_extended_test.go @@ -4,6 +4,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -302,7 +303,7 @@ func TestBuildCoverage_NotImplemented_Extended(t *testing.T) { {"MsgMhfEnumerateCampaign", &MsgMhfEnumerateCampaign{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -346,7 +347,7 @@ func TestParseCoverage_NotImplemented_Extended(t *testing.T) { {"MsgMhfRegistGuildAdventureDiva", &MsgMhfRegistGuildAdventureDiva{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/network/mhfpacket/msg_build_test.go b/network/mhfpacket/msg_build_test.go index b3842497d..479c5749c 100644 --- a/network/mhfpacket/msg_build_test.go +++ b/network/mhfpacket/msg_build_test.go @@ -6,6 +6,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -25,7 +26,7 @@ func TestBuildParseDuplicateObject(t *testing.T) { {"negative coords", 1, -1.0, -2.0, -3.0, 100, 200}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysDuplicateObject{ @@ -83,7 +84,7 @@ func TestBuildParsePositionObject(t *testing.T) { {"max object id", 0xFFFFFFFF, 999.999, -999.999, 0.001}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysPositionObject{ @@ -136,7 +137,7 @@ func TestBuildParseCastedBinary(t *testing.T) { {"larger payload", 42, 3, 4, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysCastedBinary{ @@ -187,7 +188,7 @@ func TestBuildParseLoadRegister(t *testing.T) { {"max values", 0xFFFFFFFF, 0xFFFFFFFF, 255}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -230,7 +231,7 @@ func TestBuildParseOperateRegister(t *testing.T) { {"large payload", 0xFFFFFFFF, 0xDEADBEEF, make([]byte, 256)}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -271,7 +272,7 @@ func TestBuildParseNotifyUserBinary(t *testing.T) { {"max", 0xFFFFFFFF, 255}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysNotifyUserBinary{ @@ -314,7 +315,7 @@ func TestBuildParseTime(t *testing.T) { {"typical timestamp", false, 1700000000}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysTime{ @@ -355,7 +356,7 @@ func TestBuildParseUpdateObjectBinary(t *testing.T) { {"max", 0xFFFFFFFF, 0xFFFFFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysUpdateObjectBinary{ @@ -400,7 +401,7 @@ func TestBuildParseArrangeGuildMember(t *testing.T) { {"many members", 999, 400, []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -451,7 +452,7 @@ func TestBuildParseEnumerateGuildMember(t *testing.T) { {"large values", 0xFFFFFFFF, 0xDEADBEEF, 0xCAFEBABE}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -494,7 +495,7 @@ func TestBuildParseStateCampaign(t *testing.T) { {"max", 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -536,7 +537,7 @@ func TestBuildParseApplyCampaign(t *testing.T) { {"max", 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF, make([]byte, 16)}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -579,7 +580,7 @@ func TestBuildParseEnumerateCampaign(t *testing.T) { {"zero", 0, 0, 0}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgMhfEnumerateCampaign{ @@ -622,7 +623,7 @@ func TestBuildParseEnumerateEvent(t *testing.T) { {"nonzero", 42}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgMhfEnumerateEvent{ @@ -661,7 +662,7 @@ func TestBuildParseAddUdTacticsPoint(t *testing.T) { {"max", 0xFFFFFFFF, 0xFFFF, 0xFFFFFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgMhfAddUdTacticsPoint{ @@ -712,7 +713,7 @@ func TestBuildParseApplyDistItem(t *testing.T) { {"max", 0xFFFFFFFF, 255, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -760,7 +761,7 @@ func TestBuildParseEnumerateDistItem(t *testing.T) { {"zero", 0, 0, 0, 0}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgMhfEnumerateDistItem{ @@ -813,7 +814,7 @@ func TestBuildParseAcquireExchangeShop(t *testing.T) { {"larger payload", 0xDEADBEEF, []byte{0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgMhfAcquireExchangeShop{ @@ -849,7 +850,7 @@ func TestBuildParseAcquireExchangeShop(t *testing.T) { // TestBuildParseDisplayedAchievement verifies Parse for MsgMhfDisplayedAchievement. // This struct has no exported fields; Parse only discards a single zeroed byte. func TestBuildParseDisplayedAchievement(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() bf.WriteUint8(0) // Zeroed (discarded by Parse) _, _ = bf.Seek(0, io.SeekStart) @@ -872,7 +873,7 @@ func TestBuildParseAddKouryouPoint(t *testing.T) { {"max", 0xFFFFFFFF, 0xFFFFFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgMhfAddKouryouPoint{ @@ -913,7 +914,7 @@ func TestBuildParseCheckDailyCafepoint(t *testing.T) { {"zero", 0, 0}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -947,7 +948,7 @@ func TestBuildParsePing(t *testing.T) { {"max", 0xFFFFFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysPing{ @@ -983,7 +984,7 @@ func TestBuildParseDeleteObject(t *testing.T) { {"max", 0xFFFFFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysDeleteObject{ @@ -1019,7 +1020,7 @@ func TestBuildParseNotifyRegister(t *testing.T) { {"max", 0xFFFFFFFF}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysNotifyRegister{ @@ -1047,7 +1048,7 @@ func TestBuildParseNotifyRegister(t *testing.T) { // TestBuildParseUnlockStage verifies Parse for MsgSysUnlockStage. // This struct has no exported fields; Parse only discards a single zeroed uint16. func TestBuildParseUnlockStage(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() bf.WriteUint16(0) // Zeroed (discarded by Parse) _, _ = bf.Seek(0, io.SeekStart) @@ -1068,7 +1069,7 @@ func TestBuildParseUnlockGlobalSema(t *testing.T) { {"zero", 0}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { original := &MsgSysUnlockGlobalSema{ @@ -1096,7 +1097,7 @@ func TestBuildParseUnlockGlobalSema(t *testing.T) { // TestBuildParseStageDestruct verifies Build/Parse round-trip for MsgSysStageDestruct. // This packet has no fields at all. func TestBuildParseStageDestruct(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} original := &MsgSysStageDestruct{} bf := byteframe.NewByteFrame() @@ -1117,7 +1118,7 @@ func TestBuildParseStageDestruct(t *testing.T) { // TestBuildParseCastedBinaryPayloadIntegrity verifies that a large payload is preserved // exactly through Build/Parse for MsgSysCastedBinary. func TestBuildParseCastedBinaryPayloadIntegrity(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build a payload with recognizable pattern payload := make([]byte, 1024) @@ -1159,7 +1160,7 @@ func TestBuildParseCastedBinaryPayloadIntegrity(t *testing.T) { // manual-build/Parse for MsgSysOperateRegister. // Build is NOT IMPLEMENTED, so we manually write the binary representation. func TestBuildParseOperateRegisterPayloadIntegrity(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} payload := make([]byte, 512) for i := range payload { @@ -1189,7 +1190,7 @@ func TestBuildParseOperateRegisterPayloadIntegrity(t *testing.T) { // Build is NOT IMPLEMENTED, so we manually write the binary representation. // Parse reads: uint32 AckHandle, uint32 GuildID, uint8 zeroed, uint8 charCount. func TestBuildParseArrangeGuildMemberEmptySlice(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() bf.WriteUint32(1) // AckHandle @@ -1216,7 +1217,7 @@ func TestBuildParseArrangeGuildMemberEmptySlice(t *testing.T) { // TestBuildBinaryFormat verifies the exact binary output format of a Build call // for MsgSysDuplicateObject to ensure correct endianness and field ordering. func TestBuildBinaryFormat(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} pkt := &MsgSysDuplicateObject{ ObjID: 0x00000001, X: 0, @@ -1256,7 +1257,7 @@ func TestBuildBinaryFormat(t *testing.T) { // TestBuildParseTimeBooleanEncoding verifies that the boolean field in MsgSysTime // is encoded/decoded correctly for both true and false. func TestBuildParseTimeBooleanEncoding(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, val := range []bool{true, false} { t.Run("GetRemoteTime="+boolStr(val), func(t *testing.T) { @@ -1302,7 +1303,7 @@ func boolStr(b bool) string { // TestBuildParseSysAckBufferSmall verifies MsgSysAck round-trip with buffer response // using the normal (non-extended) size field. func TestBuildParseSysAckBufferSmall(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} payload := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08} original := &MsgSysAck{ @@ -1340,7 +1341,7 @@ func TestBuildParseSysAckBufferSmall(t *testing.T) { // TestBuildParseSysAckExtendedSize verifies MsgSysAck round-trip with a payload // large enough to trigger the extended size field (>= 0xFFFF bytes). func TestBuildParseSysAckExtendedSize(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} payload := make([]byte, 0x10000) // 65536 bytes, triggers extended size for i := range payload { payload[i] = byte(i % 256) @@ -1375,7 +1376,7 @@ func TestBuildParseSysAckExtendedSize(t *testing.T) { // TestBuildParseSysAckNonBuffer verifies MsgSysAck round-trip with non-buffer response // (exactly 4 bytes of data always read in Parse). func TestBuildParseSysAckNonBuffer(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} original := &MsgSysAck{ AckHandle: 100, IsBufferResponse: false, diff --git a/network/mhfpacket/msg_comprehensive_test.go b/network/mhfpacket/msg_comprehensive_test.go index 9c87414b9..a875f3c70 100644 --- a/network/mhfpacket/msg_comprehensive_test.go +++ b/network/mhfpacket/msg_comprehensive_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" "erupe-ce/network/clientctx" ) @@ -496,7 +497,7 @@ func TestAckHandlePacketsParse(t *testing.T) { {"MsgMhfGetKijuInfo", network.MSG_MHF_GET_KIJU_INFO}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -546,7 +547,7 @@ func TestAddAchievementParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAddAchievement{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -586,7 +587,7 @@ func TestGetAchievementParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfGetAchievement{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -629,7 +630,7 @@ func TestBuildNotImplemented(t *testing.T) { for _, pkt := range packetsToTest { t.Run(pkt.Opcode().String(), func(t *testing.T) { bf := byteframe.NewByteFrame() - err := pkt.Build(bf, &clientctx.ClientContext{}) + err := pkt.Build(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err == nil { t.Logf("Build() did not return error (implementation may exist)") } else { diff --git a/network/mhfpacket/msg_mhf_acquire_cafe_item.go b/network/mhfpacket/msg_mhf_acquire_cafe_item.go index 9122d2796..bd4d2b16b 100644 --- a/network/mhfpacket/msg_mhf_acquire_cafe_item.go +++ b/network/mhfpacket/msg_mhf_acquire_cafe_item.go @@ -31,7 +31,7 @@ func (m *MsgMhfAcquireCafeItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl m.ItemType = bf.ReadUint16() m.ItemID = bf.ReadUint16() m.Quant = bf.ReadUint16() - if _config.ErupeConfig.RealClientMode >= _config.G6 { + if ctx.RealClientMode >= _config.G6 { m.PointCost = bf.ReadUint32() } else { m.PointCost = uint32(bf.ReadUint16()) diff --git a/network/mhfpacket/msg_mhf_acquire_cafe_item_test.go b/network/mhfpacket/msg_mhf_acquire_cafe_item_test.go index dde6c45d0..972ebe85b 100644 --- a/network/mhfpacket/msg_mhf_acquire_cafe_item_test.go +++ b/network/mhfpacket/msg_mhf_acquire_cafe_item_test.go @@ -10,13 +10,6 @@ import ( "erupe-ce/network/clientctx" ) -func init() { - // Initialize ErupeConfig for tests that access it - _config.ErupeConfig = &_config.Config{ - RealClientMode: _config.ZZ, // Default to ZZ for tests - } -} - func TestMsgMhfAcquireCafeItemOpcode(t *testing.T) { pkt := &MsgMhfAcquireCafeItem{} if pkt.Opcode() != network.MSG_MHF_ACQUIRE_CAFE_ITEM { @@ -38,7 +31,7 @@ func TestMsgMhfAcquireCafeItemParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireCafeItem{} - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} err := pkt.Parse(bf, ctx) if err != nil { @@ -97,7 +90,7 @@ func TestMsgMhfAcquireCafeItemParseUint32PointCost(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireCafeItem{} - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} err := pkt.Parse(bf, ctx) if err != nil { @@ -126,7 +119,7 @@ func TestMsgMhfAcquireCafeItemParseFieldOrder(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireCafeItem{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -161,7 +154,7 @@ func TestMsgMhfAcquireCafeItemBuildNotImplemented(t *testing.T) { } bf := byteframe.NewByteFrame() - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} err := pkt.Build(bf, ctx) if err == nil { diff --git a/network/mhfpacket/msg_mhf_acquire_test.go b/network/mhfpacket/msg_mhf_acquire_test.go index c80aca530..d4515b92a 100644 --- a/network/mhfpacket/msg_mhf_acquire_test.go +++ b/network/mhfpacket/msg_mhf_acquire_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" "erupe-ce/network/clientctx" ) @@ -51,7 +52,7 @@ func TestMsgMhfAcquireGuildTresureParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireGuildTresure{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -92,7 +93,7 @@ func TestMsgMhfAcquireTitleParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireTitle{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -133,7 +134,7 @@ func TestMsgMhfAcquireDistItemParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireDistItem{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -177,7 +178,7 @@ func TestMsgMhfAcquireMonthlyItemParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireMonthlyItem{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -231,7 +232,7 @@ func TestAcquirePacketEdgeCases(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireGuildTresure{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -250,7 +251,7 @@ func TestAcquirePacketEdgeCases(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAcquireDistItem{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v for type %d", err, i) } diff --git a/network/mhfpacket/msg_mhf_apply_dist_item.go b/network/mhfpacket/msg_mhf_apply_dist_item.go index a68354d2b..e31cdfd0c 100644 --- a/network/mhfpacket/msg_mhf_apply_dist_item.go +++ b/network/mhfpacket/msg_mhf_apply_dist_item.go @@ -27,10 +27,10 @@ func (m *MsgMhfApplyDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clie m.AckHandle = bf.ReadUint32() m.DistributionType = bf.ReadUint8() m.DistributionID = bf.ReadUint32() - if _config.ErupeConfig.RealClientMode >= _config.G8 { + if ctx.RealClientMode >= _config.G8 { m.Unk2 = bf.ReadUint32() } - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if ctx.RealClientMode >= _config.G10 { m.Unk3 = bf.ReadUint32() } return nil diff --git a/network/mhfpacket/msg_mhf_enumerate_dist_item.go b/network/mhfpacket/msg_mhf_enumerate_dist_item.go index cef5612c0..733193f45 100644 --- a/network/mhfpacket/msg_mhf_enumerate_dist_item.go +++ b/network/mhfpacket/msg_mhf_enumerate_dist_item.go @@ -28,7 +28,7 @@ func (m *MsgMhfEnumerateDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx. m.DistType = bf.ReadUint8() m.Unk1 = bf.ReadUint8() m.MaxCount = bf.ReadUint16() // Hardcoded to 256 - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if ctx.RealClientMode >= _config.Z1 { m.Unk3 = bf.ReadBytes(uint(bf.ReadUint8())) } return nil diff --git a/network/mhfpacket/msg_mhf_enumerate_quest.go b/network/mhfpacket/msg_mhf_enumerate_quest.go index 243dffcfa..5cfe70784 100644 --- a/network/mhfpacket/msg_mhf_enumerate_quest.go +++ b/network/mhfpacket/msg_mhf_enumerate_quest.go @@ -30,7 +30,7 @@ func (m *MsgMhfEnumerateQuest) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli m.Unk0 = bf.ReadUint8() m.World = bf.ReadUint8() m.Counter = bf.ReadUint16() - if _config.ErupeConfig.RealClientMode <= _config.Z1 { + if ctx.RealClientMode <= _config.Z1 { m.Offset = uint16(bf.ReadUint8()) } else { m.Offset = bf.ReadUint16() diff --git a/network/mhfpacket/msg_mhf_enumerate_shop.go b/network/mhfpacket/msg_mhf_enumerate_shop.go index d57655e98..fa729536c 100644 --- a/network/mhfpacket/msg_mhf_enumerate_shop.go +++ b/network/mhfpacket/msg_mhf_enumerate_shop.go @@ -32,7 +32,7 @@ func (m *MsgMhfEnumerateShop) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clie m.ShopID = bf.ReadUint32() m.Limit = bf.ReadUint16() m.Unk3 = bf.ReadUint8() - if _config.ErupeConfig.RealClientMode >= _config.G2 { + if ctx.RealClientMode >= _config.G2 { m.Unk4 = bf.ReadUint8() m.Unk5 = bf.ReadUint32() } diff --git a/network/mhfpacket/msg_mhf_guacot_test.go b/network/mhfpacket/msg_mhf_guacot_test.go index 2bba03bea..6eaac748e 100644 --- a/network/mhfpacket/msg_mhf_guacot_test.go +++ b/network/mhfpacket/msg_mhf_guacot_test.go @@ -4,7 +4,9 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" + "erupe-ce/network/clientctx" ) func TestMsgMhfUpdateGuacotOpcode_Guacot(t *testing.T) { @@ -39,7 +41,7 @@ func TestMsgMhfUpdateGuacotParse_SingleEntry(t *testing.T) { pkt := &MsgMhfUpdateGuacot{} _, _ = bf.Seek(0, 0) - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error: %v", err) } @@ -100,7 +102,7 @@ func TestMsgMhfUpdateGuacotParse_MultipleEntries(t *testing.T) { pkt := &MsgMhfUpdateGuacot{} _, _ = bf.Seek(0, 0) - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error: %v", err) } @@ -130,7 +132,7 @@ func TestMsgMhfUpdateGuacotParse_ZeroEntries(t *testing.T) { pkt := &MsgMhfUpdateGuacot{} _, _ = bf.Seek(0, 0) - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error: %v", err) } @@ -161,7 +163,7 @@ func TestMsgMhfUpdateGuacotParse_DeletionEntry(t *testing.T) { pkt := &MsgMhfUpdateGuacot{} _, _ = bf.Seek(0, 0) - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error: %v", err) } @@ -188,7 +190,7 @@ func TestMsgMhfUpdateGuacotParse_EmptyName(t *testing.T) { pkt := &MsgMhfUpdateGuacot{} _, _ = bf.Seek(0, 0) - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error: %v", err) } @@ -206,7 +208,7 @@ func TestMsgMhfEnumerateGuacotParse(t *testing.T) { pkt := &MsgMhfEnumerateGuacot{} _, _ = bf.Seek(0, 0) - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error: %v", err) } @@ -221,7 +223,7 @@ func TestMsgMhfEnumerateGuacotParse(t *testing.T) { func TestMsgMhfUpdateGuacotBuild_NotImplemented(t *testing.T) { pkt := &MsgMhfUpdateGuacot{} - err := pkt.Build(byteframe.NewByteFrame(), nil) + err := pkt.Build(byteframe.NewByteFrame(), &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err == nil { t.Error("Build() should return error (not implemented)") } @@ -229,7 +231,7 @@ func TestMsgMhfUpdateGuacotBuild_NotImplemented(t *testing.T) { func TestMsgMhfEnumerateGuacotBuild_NotImplemented(t *testing.T) { pkt := &MsgMhfEnumerateGuacot{} - err := pkt.Build(byteframe.NewByteFrame(), nil) + err := pkt.Build(byteframe.NewByteFrame(), &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err == nil { t.Error("Build() should return error (not implemented)") } @@ -252,7 +254,7 @@ func TestGoocooStruct_Data1Size(t *testing.T) { pkt := &MsgMhfUpdateGuacot{} _, _ = bf.Seek(0, 0) - _ = pkt.Parse(bf, nil) + _ = pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) g := pkt.Goocoos[0] diff --git a/network/mhfpacket/msg_mhf_packets_test.go b/network/mhfpacket/msg_mhf_packets_test.go index ba612f50b..66f830ad8 100644 --- a/network/mhfpacket/msg_mhf_packets_test.go +++ b/network/mhfpacket/msg_mhf_packets_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" "erupe-ce/network/clientctx" ) @@ -520,7 +521,7 @@ func TestAchievementPacketParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAddAchievement{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } diff --git a/network/mhfpacket/msg_mhf_savedata.go b/network/mhfpacket/msg_mhf_savedata.go index cf41416f3..60cbe15dd 100644 --- a/network/mhfpacket/msg_mhf_savedata.go +++ b/network/mhfpacket/msg_mhf_savedata.go @@ -30,7 +30,7 @@ func (m *MsgMhfSavedata) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon m.AllocMemSize = bf.ReadUint32() m.SaveType = bf.ReadUint8() m.Unk1 = bf.ReadUint32() - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if ctx.RealClientMode >= _config.G1 { m.DataSize = bf.ReadUint32() } if m.DataSize == 0 { // seems to be used when DataSize = 0 rather than on savetype? diff --git a/network/mhfpacket/msg_mhf_stampcard_stamp.go b/network/mhfpacket/msg_mhf_stampcard_stamp.go index 281134c9d..e4505ce10 100644 --- a/network/mhfpacket/msg_mhf_stampcard_stamp.go +++ b/network/mhfpacket/msg_mhf_stampcard_stamp.go @@ -32,12 +32,12 @@ func (m *MsgMhfStampcardStamp) Opcode() network.PacketID { func (m *MsgMhfStampcardStamp) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.HR = bf.ReadUint16() - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if ctx.RealClientMode >= _config.G1 { m.GR = bf.ReadUint16() } m.Stamps = bf.ReadUint16() bf.ReadUint16() // Zeroed - if _config.ErupeConfig.RealClientMode >= _config.Z2 { + if ctx.RealClientMode >= _config.Z2 { m.Reward1 = uint16(bf.ReadUint32()) m.Reward2 = uint16(bf.ReadUint32()) m.Item1 = uint16(bf.ReadUint32()) diff --git a/network/mhfpacket/msg_mhf_update_myhouse_info.go b/network/mhfpacket/msg_mhf_update_myhouse_info.go index c5bf26d7a..b91fdbf59 100644 --- a/network/mhfpacket/msg_mhf_update_myhouse_info.go +++ b/network/mhfpacket/msg_mhf_update_myhouse_info.go @@ -23,11 +23,11 @@ func (m *MsgMhfUpdateMyhouseInfo) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfUpdateMyhouseInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if ctx.RealClientMode >= _config.G10 { m.Data = bf.ReadBytes(362) - } else if _config.ErupeConfig.RealClientMode >= _config.GG { + } else if ctx.RealClientMode >= _config.GG { m.Data = bf.ReadBytes(338) - } else if _config.ErupeConfig.RealClientMode >= _config.F5 { + } else if ctx.RealClientMode >= _config.F5 { // G1 is a guess m.Data = bf.ReadBytes(314) } else { diff --git a/network/mhfpacket/msg_mhf_update_warehouse.go b/network/mhfpacket/msg_mhf_update_warehouse.go index 9d264cf89..6627b7708 100644 --- a/network/mhfpacket/msg_mhf_update_warehouse.go +++ b/network/mhfpacket/msg_mhf_update_warehouse.go @@ -35,7 +35,7 @@ func (m *MsgMhfUpdateWarehouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl case 0: m.UpdatedItems = append(m.UpdatedItems, mhfitem.ReadWarehouseItem(bf)) case 1: - m.UpdatedEquipment = append(m.UpdatedEquipment, mhfitem.ReadWarehouseEquipment(bf)) + m.UpdatedEquipment = append(m.UpdatedEquipment, mhfitem.ReadWarehouseEquipment(bf, ctx.RealClientMode)) } } return nil diff --git a/network/mhfpacket/msg_opcode_coverage_test.go b/network/mhfpacket/msg_opcode_coverage_test.go index b88070d17..7d802733f 100644 --- a/network/mhfpacket/msg_opcode_coverage_test.go +++ b/network/mhfpacket/msg_opcode_coverage_test.go @@ -4,6 +4,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -245,7 +246,7 @@ func TestBuildCoverage_NotImplemented(t *testing.T) { {"MsgSysReserve1AF", &MsgSysReserve1AF{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -282,7 +283,7 @@ func TestParseCoverage_NotImplemented(t *testing.T) { {"MsgMhfUpdateGuild", &MsgMhfUpdateGuild{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/network/mhfpacket/msg_parse_coverage_test.go b/network/mhfpacket/msg_parse_coverage_test.go index 6f436a4c2..f495e9cc3 100644 --- a/network/mhfpacket/msg_parse_coverage_test.go +++ b/network/mhfpacket/msg_parse_coverage_test.go @@ -5,6 +5,7 @@ import ( "erupe-ce/common/byteframe" "erupe-ce/common/mhfcourse" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -12,7 +13,7 @@ import ( // method is implemented (reads from ByteFrame) but was not yet covered by tests. // Each test provides a ByteFrame with enough bytes for the Parse to succeed. func TestParseCoverage_Implemented(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} tests := []struct { name string @@ -75,7 +76,7 @@ func TestParseCoverage_Implemented(t *testing.T) { // TestParseCoverage_VariableLength tests Parse for variable-length packets // that require specific data layouts. func TestParseCoverage_VariableLength(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgMhfAcquireItem_EmptyList", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -239,7 +240,7 @@ func TestParseCoverage_VariableLength(t *testing.T) { // TestBuildCoverage_Implemented tests Build() on packet types whose Build method // is implemented (writes to ByteFrame) but was not yet covered. func TestBuildCoverage_Implemented(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgSysDeleteUser", func(t *testing.T) { pkt := &MsgSysDeleteUser{CharID: 123} @@ -306,7 +307,7 @@ func TestBuildCoverage_Implemented(t *testing.T) { // TestParseCoverage_EmptyPackets tests Parse() for packets with no payload fields. func TestParseCoverage_EmptyPackets(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgSysCleanupObject_Parse", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -343,7 +344,7 @@ func TestParseCoverage_EmptyPackets(t *testing.T) { // TestParseCoverage_NotImplemented2 tests Parse/Build for packets that return NOT IMPLEMENTED. func TestParseCoverage_NotImplemented2(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("MsgSysGetObjectOwner_Parse", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -366,7 +367,7 @@ func TestParseCoverage_NotImplemented2(t *testing.T) { // TestParseCoverage_UpdateWarehouse tests MsgMhfUpdateWarehouse.Parse with different box types. func TestParseCoverage_UpdateWarehouse(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("EmptyChanges", func(t *testing.T) { bf := byteframe.NewByteFrame() diff --git a/network/mhfpacket/msg_parse_large_test.go b/network/mhfpacket/msg_parse_large_test.go index 6c31263e8..fe97a007b 100644 --- a/network/mhfpacket/msg_parse_large_test.go +++ b/network/mhfpacket/msg_parse_large_test.go @@ -6,12 +6,13 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) // TestParseLargeMsgSysUpdateRightBuild tests Build for MsgSysUpdateRight (no Parse implementation). func TestParseLargeMsgSysUpdateRightBuild(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} original := &MsgSysUpdateRight{ ClientRespAckHandle: 0x12345678, Bitfield: 0xDEADBEEF, @@ -57,7 +58,7 @@ func TestParseLargeMsgMhfOperateWarehouse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfOperateWarehouse{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -92,7 +93,7 @@ func TestParseLargeMsgMhfOperateWarehouseEquip(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfOperateWarehouse{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -132,7 +133,7 @@ func TestParseLargeMsgMhfLoadHouse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfLoadHouse{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -171,7 +172,7 @@ func TestParseLargeMsgMhfSendMail(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfSendMail{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -232,7 +233,7 @@ func TestParseLargeMsgMhfApplyBbsArticle(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfApplyBbsArticle{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -270,7 +271,7 @@ func TestParseLargeMsgMhfChargeFesta(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfChargeFesta{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -305,7 +306,7 @@ func TestParseLargeMsgMhfChargeFestaZeroSouls(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfChargeFesta{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } if len(pkt.Souls) != 0 { @@ -328,7 +329,7 @@ func TestParseLargeMsgMhfOperateJoint(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfOperateJoint{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -364,7 +365,7 @@ func TestParseLargeMsgMhfOperationInvGuild(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfOperationInvGuild{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -403,7 +404,7 @@ func TestParseLargeMsgMhfSaveMercenary(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfSaveMercenary{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -445,7 +446,7 @@ func TestParseLargeMsgMhfUpdateHouse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfUpdateHouse{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -480,7 +481,7 @@ func TestParseLargeMsgSysCreateAcquireSemaphore(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCreateAcquireSemaphore{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -512,7 +513,7 @@ func TestParseLargeMsgMhfOperateGuild(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfOperateGuild{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -552,7 +553,7 @@ func TestParseLargeMsgMhfReadBeatLevel(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfReadBeatLevel{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -596,7 +597,7 @@ func TestParseLargeMsgSysCreateObject(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCreateObject{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -632,7 +633,7 @@ func TestParseLargeMsgSysLockGlobalSema(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLockGlobalSema{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -664,7 +665,7 @@ func TestParseLargeMsgMhfCreateJoint(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfCreateJoint{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -689,7 +690,7 @@ func TestParseLargeMsgMhfGetUdTacticsRemainingPoint(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfGetUdTacticsRemainingPoint{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -718,7 +719,7 @@ func TestParseLargeMsgMhfPostCafeDurationBonusReceived(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfPostCafeDurationBonusReceived{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -744,7 +745,7 @@ func TestParseLargeMsgMhfPostCafeDurationBonusReceivedEmpty(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfPostCafeDurationBonusReceived{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } if len(pkt.CafeBonusID) != 0 { @@ -762,7 +763,7 @@ func TestParseLargeMsgMhfRegistGuildAdventureDiva(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfRegistGuildAdventureDiva{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -787,7 +788,7 @@ func TestParseLargeMsgMhfStateFestaG(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfStateFestaG{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -812,7 +813,7 @@ func TestParseLargeMsgMhfStateFestaU(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfStateFestaU{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -838,7 +839,7 @@ func TestParseLargeMsgSysEnumerateStage(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysEnumerateStage{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -864,7 +865,7 @@ func TestParseLargeMsgSysReserveStage(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysReserveStage{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } diff --git a/network/mhfpacket/msg_parse_medium_test.go b/network/mhfpacket/msg_parse_medium_test.go index e2e967488..1c02a55fe 100644 --- a/network/mhfpacket/msg_parse_medium_test.go +++ b/network/mhfpacket/msg_parse_medium_test.go @@ -6,6 +6,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -36,7 +37,7 @@ func TestParseMediumVoteFesta(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfVoteFesta{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -81,7 +82,7 @@ func TestParseMediumAcquireSemaphore(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysAcquireSemaphore{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -119,7 +120,7 @@ func TestParseMediumCheckSemaphore(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCheckSemaphore{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -156,7 +157,7 @@ func TestParseMediumGetUserBinary(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysGetUserBinary{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -195,7 +196,7 @@ func TestParseMediumSetObjectBinary(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysSetObjectBinary{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -234,7 +235,7 @@ func TestParseMediumSetUserBinary(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysSetUserBinary{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -274,7 +275,7 @@ func TestParseMediumGetUdRanking(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfGetUdRanking{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -309,7 +310,7 @@ func TestParseMediumGetUdTacticsRanking(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfGetUdTacticsRanking{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -346,7 +347,7 @@ func TestParseMediumRegistGuildTresure(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfRegistGuildTresure{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -377,7 +378,7 @@ func TestParseMediumUpdateMyhouseInfo(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfUpdateMyhouseInfo{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -399,7 +400,7 @@ func TestParseMediumUpdateMyhouseInfo(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfUpdateMyhouseInfo{} - if err := pkt.Parse(bf, nil); err != nil { + if err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}); err != nil { t.Fatalf("Parse() error = %v", err) } @@ -517,7 +518,7 @@ func TestParseMediumAckHandleOnlyBatch(t *testing.T) { }, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} ackValues := []uint32{0x12345678, 0, 0xFFFFFFFF, 0xDEADBEEF} for _, tc := range packets { @@ -539,7 +540,7 @@ func TestParseMediumAckHandleOnlyBatch(t *testing.T) { // TestParseMediumAckHandleOnlyVerifyValues tests each 3-stmt AckHandle-only // packet individually, verifying that the AckHandle field is correctly populated. func TestParseMediumAckHandleOnlyVerifyValues(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} ack := uint32(0xCAFEBABE) makeFrame := func() *byteframe.ByteFrame { @@ -738,7 +739,7 @@ func TestParseMediumDeleteUser(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysDeleteUser{} - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err == nil { t.Fatal("Parse() should return error for NOT IMPLEMENTED") } @@ -755,7 +756,7 @@ func TestParseMediumInsertUser(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysInsertUser{} - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err == nil { t.Fatal("Parse() should return error for NOT IMPLEMENTED") } diff --git a/network/mhfpacket/msg_parse_small_test.go b/network/mhfpacket/msg_parse_small_test.go index 78da32c9c..5e47c0a44 100644 --- a/network/mhfpacket/msg_parse_small_test.go +++ b/network/mhfpacket/msg_parse_small_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -59,7 +60,7 @@ func TestParseSmallNotImplemented(t *testing.T) { {"MsgSysTransBinary", &MsgSysTransBinary{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tc := range packets { t.Run(tc.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -88,7 +89,7 @@ func TestParseSmallNoData(t *testing.T) { {"MsgSysUnreserveStage", &MsgSysUnreserveStage{}}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tc := range packets { t.Run(tc.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -111,7 +112,7 @@ func TestParseSmallLogout(t *testing.T) { {"max", 255}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -133,7 +134,7 @@ func TestParseSmallLogout(t *testing.T) { // TestParseSmallEnumerateHouse tests Parse for MsgMhfEnumerateHouse which reads // AckHandle, CharID, Method, Unk, lenName, and optional Name. func TestParseSmallEnumerateHouse(t *testing.T) { - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} t.Run("no name", func(t *testing.T) { bf := byteframe.NewByteFrame() @@ -196,7 +197,7 @@ func TestParseSmallEnumerateHouse(t *testing.T) { } // TestParseSmallNotImplementedDoesNotPanic ensures that calling Parse on NOT IMPLEMENTED -// packets with a nil ClientContext does not cause a nil pointer dereference panic. +// packets returns an error and does not panic. func TestParseSmallNotImplementedDoesNotPanic(t *testing.T) { packets := []MHFPacket{ &MsgMhfAcceptReadReward{}, @@ -204,10 +205,11 @@ func TestParseSmallNotImplementedDoesNotPanic(t *testing.T) { &MsgSysSerialize{}, } + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} for _, pkt := range packets { - t.Run("nil_ctx", func(t *testing.T) { + t.Run("not_implemented", func(t *testing.T) { bf := byteframe.NewByteFrame() - err := pkt.Parse(bf, nil) + err := pkt.Parse(bf, ctx) if err == nil { t.Fatal("expected error, got nil") } diff --git a/network/mhfpacket/msg_parse_test.go b/network/mhfpacket/msg_parse_test.go index d8510e94c..fe43c217a 100644 --- a/network/mhfpacket/msg_parse_test.go +++ b/network/mhfpacket/msg_parse_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/clientctx" ) @@ -17,7 +18,7 @@ func TestMsgMhfGetAchievementDetailedParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfGetAchievement{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -39,7 +40,7 @@ func TestMsgMhfAddAchievementDetailedParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgMhfAddAchievement{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -81,7 +82,7 @@ func TestMsgSysCastBinaryDetailedParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCastBinary{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -119,7 +120,7 @@ func TestMsgSysLogoutDetailedParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLogout{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -147,7 +148,7 @@ func TestMsgSysBackStageDetailedParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysBackStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -174,7 +175,7 @@ func TestMsgSysPingDetailedParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysPing{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -203,7 +204,7 @@ func TestMsgSysTimeDetailedParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysTime{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } diff --git a/network/mhfpacket/msg_sys_core_test.go b/network/mhfpacket/msg_sys_core_test.go index 659472336..7702d579f 100644 --- a/network/mhfpacket/msg_sys_core_test.go +++ b/network/mhfpacket/msg_sys_core_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" "erupe-ce/network/clientctx" ) @@ -55,7 +56,7 @@ func TestMsgSysAckRoundTrip(t *testing.T) { ErrorCode: tt.errorCode, AckData: tt.ackData, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build bf := byteframe.NewByteFrame() @@ -99,7 +100,7 @@ func TestMsgSysAckLargePayload(t *testing.T) { ErrorCode: 0, AckData: largeData, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build bf := byteframe.NewByteFrame() @@ -130,7 +131,7 @@ func TestMsgSysAckOpcode(t *testing.T) { func TestMsgSysNopRoundTrip(t *testing.T) { original := &MsgSysNop{} - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build bf := byteframe.NewByteFrame() @@ -161,7 +162,7 @@ func TestMsgSysNopOpcode(t *testing.T) { func TestMsgSysEndRoundTrip(t *testing.T) { original := &MsgSysEnd{} - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} // Build bf := byteframe.NewByteFrame() @@ -198,7 +199,7 @@ func TestMsgSysAckNonBufferResponse(t *testing.T) { ErrorCode: 0, AckData: []byte{0xAA, 0xBB, 0xCC, 0xDD}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() err := original.Build(bf, ctx) @@ -227,7 +228,7 @@ func TestMsgSysAckNonBufferShortData(t *testing.T) { ErrorCode: 0, AckData: []byte{0x01}, // Only 1 byte } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() err := original.Build(bf, ctx) @@ -255,7 +256,7 @@ func TestMsgSysAckBuildFormat(t *testing.T) { ErrorCode: 0x55, AckData: []byte{0xAA, 0xBB}, } - ctx := &clientctx.ClientContext{} + ctx := &clientctx.ClientContext{RealClientMode: _config.ZZ} bf := byteframe.NewByteFrame() _ = pkt.Build(bf, ctx) diff --git a/network/mhfpacket/msg_sys_create_acquire_semaphore.go b/network/mhfpacket/msg_sys_create_acquire_semaphore.go index 9e22c50e7..1b06eabad 100644 --- a/network/mhfpacket/msg_sys_create_acquire_semaphore.go +++ b/network/mhfpacket/msg_sys_create_acquire_semaphore.go @@ -25,7 +25,7 @@ func (m *MsgSysCreateAcquireSemaphore) Opcode() network.PacketID { func (m *MsgSysCreateAcquireSemaphore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.Unk0 = bf.ReadUint16() - if _config.ErupeConfig.RealClientMode >= _config.S7 { // Assuming this was added with Ravi? + if ctx.RealClientMode >= _config.S7 { // Assuming this was added with Ravi? m.PlayerCount = bf.ReadUint8() } bf.ReadUint8() // SemaphoreID length diff --git a/network/mhfpacket/msg_sys_create_semaphore.go b/network/mhfpacket/msg_sys_create_semaphore.go index c9b29d2ab..1d15f4518 100644 --- a/network/mhfpacket/msg_sys_create_semaphore.go +++ b/network/mhfpacket/msg_sys_create_semaphore.go @@ -26,7 +26,7 @@ func (m *MsgSysCreateSemaphore) Opcode() network.PacketID { func (m *MsgSysCreateSemaphore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.Unk0 = bf.ReadUint16() - if _config.ErupeConfig.RealClientMode >= _config.S7 { // Assuming this was added with Ravi? + if ctx.RealClientMode >= _config.S7 { // Assuming this was added with Ravi? m.PlayerCount = bf.ReadUint8() } bf.ReadUint8() // SemaphoreID length diff --git a/network/mhfpacket/msg_sys_packets_test.go b/network/mhfpacket/msg_sys_packets_test.go index 406dd64e9..45a288938 100644 --- a/network/mhfpacket/msg_sys_packets_test.go +++ b/network/mhfpacket/msg_sys_packets_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" "erupe-ce/network/clientctx" ) @@ -34,7 +35,7 @@ func TestMsgSysCastBinaryParse(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCastBinary{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } diff --git a/network/mhfpacket/msg_sys_stage_test.go b/network/mhfpacket/msg_sys_stage_test.go index 76d810204..0f4231147 100644 --- a/network/mhfpacket/msg_sys_stage_test.go +++ b/network/mhfpacket/msg_sys_stage_test.go @@ -5,6 +5,7 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network" "erupe-ce/network/clientctx" ) @@ -58,7 +59,7 @@ func TestMsgSysCreateStageFields(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCreateStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -102,7 +103,7 @@ func TestMsgSysEnterStageFields(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysEnterStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -142,7 +143,7 @@ func TestMsgSysMoveStageFields(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysMoveStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -184,7 +185,7 @@ func TestMsgSysLockStageFields(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysLockStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -218,7 +219,7 @@ func TestMsgSysUnlockStageFields(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysUnlockStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -245,7 +246,7 @@ func TestMsgSysBackStageFields(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysBackStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -274,7 +275,7 @@ func TestStageIDEdgeCases(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysCreateStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } @@ -296,7 +297,7 @@ func TestStageIDEdgeCases(t *testing.T) { _, _ = bf.Seek(0, io.SeekStart) pkt := &MsgSysEnterStage{} - err := pkt.Parse(bf, &clientctx.ClientContext{}) + err := pkt.Parse(bf, &clientctx.ClientContext{RealClientMode: _config.ZZ}) if err != nil { t.Fatalf("Parse() error = %v", err) } diff --git a/network/mhfpacket/msg_sys_terminal_log.go b/network/mhfpacket/msg_sys_terminal_log.go index bad160a73..aef2a2c2d 100644 --- a/network/mhfpacket/msg_sys_terminal_log.go +++ b/network/mhfpacket/msg_sys_terminal_log.go @@ -49,7 +49,7 @@ func (m *MsgSysTerminalLog) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Client e.Unk1 = bf.ReadInt32() e.Unk2 = bf.ReadInt32() e.Unk3 = bf.ReadInt32() - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if ctx.RealClientMode >= _config.G1 { for j := 0; j < 4; j++ { e.Unk4 = append(e.Unk4, bf.ReadInt32()) } diff --git a/server/channelserver/guild_model.go b/server/channelserver/guild_model.go index ba6988b4d..7d33b657d 100644 --- a/server/channelserver/guild_model.go +++ b/server/channelserver/guild_model.go @@ -118,12 +118,12 @@ func (gi *GuildIcon) Value() (valuer driver.Value, err error) { return json.Marshal(gi) } -func (g *Guild) Rank() uint16 { +func (g *Guild) Rank(mode _config.Mode) uint16 { rpMap := []uint32{ 24, 48, 96, 144, 192, 240, 288, 360, 432, 504, 600, 696, 792, 888, 984, 1080, 1200, } - if _config.ErupeConfig.RealClientMode <= _config.Z2 { + if mode <= _config.Z2 { rpMap = []uint32{ 3500, 6000, 8500, 11000, 13500, 16000, 20000, 24000, 28000, 33000, 38000, 43000, 48000, 55000, 70000, 90000, 120000, @@ -131,21 +131,21 @@ func (g *Guild) Rank() uint16 { } for i, u := range rpMap { if g.RankRP < u { - if _config.ErupeConfig.RealClientMode <= _config.S6 && i >= 12 { + if mode <= _config.S6 && i >= 12 { return 12 - } else if _config.ErupeConfig.RealClientMode <= _config.F5 && i >= 13 { + } else if mode <= _config.F5 && i >= 13 { return 13 - } else if _config.ErupeConfig.RealClientMode <= _config.G32 && i >= 14 { + } else if mode <= _config.G32 && i >= 14 { return 14 } return uint16(i) } } - if _config.ErupeConfig.RealClientMode <= _config.S6 { + if mode <= _config.S6 { return 12 - } else if _config.ErupeConfig.RealClientMode <= _config.F5 { + } else if mode <= _config.F5 { return 13 - } else if _config.ErupeConfig.RealClientMode <= _config.G32 { + } else if mode <= _config.G32 { return 14 } return 17 diff --git a/server/channelserver/handlers_cafe.go b/server/channelserver/handlers_cafe.go index b283d4f1c..f99c94124 100644 --- a/server/channelserver/handlers_cafe.go +++ b/server/channelserver/handlers_cafe.go @@ -102,7 +102,7 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) { cafeTime = uint32(TimeAdjusted().Unix()) - uint32(s.sessionStart) + cafeTime } bf.WriteUint32(cafeTime) - if _config.ErupeConfig.RealClientMode >= _config.ZZ { + if s.server.erupeConfig.RealClientMode >= _config.ZZ { bf.WriteUint16(0) ps.Uint16(bf, fmt.Sprintf(s.server.i18n.cafe.reset, int(cafeReset.Month()), cafeReset.Day()), true) } diff --git a/server/channelserver/handlers_campaign.go b/server/channelserver/handlers_campaign.go index df3079617..45bc45093 100644 --- a/server/channelserver/handlers_campaign.go +++ b/server/channelserver/handlers_campaign.go @@ -71,7 +71,7 @@ func handleMsgMhfEnumerateCampaign(s *Session, p mhfpacket.MHFPacket) { bf.WriteInt16(event.MaxHR) bf.WriteInt16(event.MinSR) bf.WriteInt16(event.MaxSR) - if _config.ErupeConfig.RealClientMode >= _config.G3 { + if s.server.erupeConfig.RealClientMode >= _config.G3 { bf.WriteInt16(event.MinGR) bf.WriteInt16(event.MaxGR) } diff --git a/server/channelserver/handlers_character.go b/server/channelserver/handlers_character.go index 14cd59084..c43f3f036 100644 --- a/server/channelserver/handlers_character.go +++ b/server/channelserver/handlers_character.go @@ -24,7 +24,8 @@ func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error) } saveData := &CharacterSaveData{ - Pointers: getPointers(), + Mode: s.server.erupeConfig.RealClientMode, + Pointers: getPointers(s.server.erupeConfig.RealClientMode), } err = result.Scan(&saveData.CharID, &saveData.compSave, &saveData.IsNewCharacter, &saveData.Name) if err != nil { @@ -63,7 +64,7 @@ func (save *CharacterSaveData) Save(s *Session) { save.updateSaveDataWithStruct() - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if s.server.erupeConfig.RealClientMode >= _config.G1 { err := save.Compress() if err != nil { s.logger.Error("Failed to compress savedata", zap.Error(err)) diff --git a/server/channelserver/handlers_character_test.go b/server/channelserver/handlers_character_test.go index 63a85fe35..257004ce3 100644 --- a/server/channelserver/handlers_character_test.go +++ b/server/channelserver/handlers_character_test.go @@ -52,12 +52,7 @@ func TestGetPointers(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Save and restore original config - originalMode := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = originalMode }() - - _config.ErupeConfig.RealClientMode = tt.clientMode - pointers := getPointers() + pointers := getPointers(tt.clientMode) if pointers[pGender] != tt.wantGender { t.Errorf("pGender = %d, want %d", pointers[pGender], tt.wantGender) @@ -216,10 +211,6 @@ func TestCharacterSaveData_RoundTrip(t *testing.T) { // TestCharacterSaveData_updateStructWithSaveData tests parsing save data func TestCharacterSaveData_updateStructWithSaveData(t *testing.T) { - originalMode := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = originalMode }() - _config.ErupeConfig.RealClientMode = _config.Z2 - tests := []struct { name string isNewCharacter bool @@ -267,7 +258,8 @@ func TestCharacterSaveData_updateStructWithSaveData(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { save := &CharacterSaveData{ - Pointers: getPointers(), + Mode: _config.Z2, + Pointers: getPointers(_config.Z2), decompSave: tt.setupSaveData(), IsNewCharacter: tt.isNewCharacter, } @@ -287,10 +279,6 @@ func TestCharacterSaveData_updateStructWithSaveData(t *testing.T) { // TestCharacterSaveData_updateSaveDataWithStruct tests writing struct to save data func TestCharacterSaveData_updateSaveDataWithStruct(t *testing.T) { - originalMode := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = originalMode }() - _config.ErupeConfig.RealClientMode = _config.G10 - tests := []struct { name string rp uint16 @@ -320,7 +308,8 @@ func TestCharacterSaveData_updateSaveDataWithStruct(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { save := &CharacterSaveData{ - Pointers: getPointers(), + Mode: _config.G10, + Pointers: getPointers(_config.G10), decompSave: make([]byte, 150000), RP: tt.rp, KQF: tt.kqf, @@ -388,11 +377,6 @@ func TestGetCharacterSaveData_Integration(t *testing.T) { db := SetupTestDB(t) defer TeardownTestDB(t, db) - // Save original config mode - originalMode := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = originalMode }() - _config.ErupeConfig.RealClientMode = _config.Z2 - tests := []struct { name string charName string @@ -430,6 +414,7 @@ func TestGetCharacterSaveData_Integration(t *testing.T) { s := createTestSession(mock) s.charID = charID s.server.db = db + s.server.erupeConfig.RealClientMode = _config.Z2 // Get character save data saveData, err := GetCharacterSaveData(s, charID) @@ -464,11 +449,6 @@ func TestCharacterSaveData_Save_Integration(t *testing.T) { db := SetupTestDB(t) defer TeardownTestDB(t, db) - // Save original config mode - originalMode := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = originalMode }() - _config.ErupeConfig.RealClientMode = _config.Z2 - // Create test user and character userID := CreateTestUser(t, db, "savetest") charID := CreateTestCharacter(t, db, userID, "SaveChar") @@ -478,6 +458,7 @@ func TestCharacterSaveData_Save_Integration(t *testing.T) { s := createTestSession(mock) s.charID = charID s.server.db = db + s.server.erupeConfig.RealClientMode = _config.Z2 // Load character save data saveData, err := GetCharacterSaveData(s, charID) diff --git a/server/channelserver/handlers_commands.go b/server/channelserver/handlers_commands.go index 34777222b..d18927971 100644 --- a/server/channelserver/handlers_commands.go +++ b/server/channelserver/handlers_commands.go @@ -15,29 +15,29 @@ import ( "slices" "strconv" "strings" + "sync" "time" "go.uber.org/zap" ) -var commands map[string]_config.Command +var ( + commands map[string]_config.Command + commandsOnce sync.Once +) -func init() { - commands = make(map[string]_config.Command) - zapConfig := zap.NewDevelopmentConfig() - zapConfig.DisableCaller = true - zapLogger, _ := zapConfig.Build() - defer func() { _ = zapLogger.Sync() }() - logger := zapLogger.Named("commands") - cmds := _config.ErupeConfig.Commands - for _, cmd := range cmds { - commands[cmd.Name] = cmd - if cmd.Enabled { - logger.Info(fmt.Sprintf("Command %s: Enabled, prefix: %s", cmd.Name, cmd.Prefix)) - } else { - logger.Info(fmt.Sprintf("Command %s: Disabled", cmd.Name)) +func initCommands(cmds []_config.Command, logger *zap.Logger) { + commandsOnce.Do(func() { + commands = make(map[string]_config.Command) + for _, cmd := range cmds { + commands[cmd.Name] = cmd + if cmd.Enabled { + logger.Info(fmt.Sprintf("Command %s: Enabled, prefix: %s", cmd.Name, cmd.Prefix)) + } else { + logger.Info(fmt.Sprintf("Command %s: Disabled", cmd.Name)) + } } - } + }) } func sendDisabledCommandMessage(s *Session, cmd _config.Command) { diff --git a/server/channelserver/handlers_coverage5_test.go b/server/channelserver/handlers_coverage5_test.go index 5f0bb629d..dd0868487 100644 --- a/server/channelserver/handlers_coverage5_test.go +++ b/server/channelserver/handlers_coverage5_test.go @@ -12,46 +12,30 @@ import ( // ============================================================================= func TestEquipSkinHistSize_Default(t *testing.T) { - orig := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = orig }() - - _config.ErupeConfig.RealClientMode = _config.ZZ - got := equipSkinHistSize() + got := equipSkinHistSize(_config.ZZ) if got != 3200 { - t.Errorf("equipSkinHistSize() with ZZ = %d, want 3200", got) + t.Errorf("equipSkinHistSize(ZZ) = %d, want 3200", got) } } func TestEquipSkinHistSize_Z2(t *testing.T) { - orig := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = orig }() - - _config.ErupeConfig.RealClientMode = _config.Z2 - got := equipSkinHistSize() + got := equipSkinHistSize(_config.Z2) if got != 2560 { - t.Errorf("equipSkinHistSize() with Z2 = %d, want 2560", got) + t.Errorf("equipSkinHistSize(Z2) = %d, want 2560", got) } } func TestEquipSkinHistSize_Z1(t *testing.T) { - orig := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = orig }() - - _config.ErupeConfig.RealClientMode = _config.Z1 - got := equipSkinHistSize() + got := equipSkinHistSize(_config.Z1) if got != 1280 { - t.Errorf("equipSkinHistSize() with Z1 = %d, want 1280", got) + t.Errorf("equipSkinHistSize(Z1) = %d, want 1280", got) } } func TestEquipSkinHistSize_OlderMode(t *testing.T) { - orig := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = orig }() - - _config.ErupeConfig.RealClientMode = _config.G1 - got := equipSkinHistSize() + got := equipSkinHistSize(_config.G1) if got != 1280 { - t.Errorf("equipSkinHistSize() with G1 = %d, want 1280", got) + t.Errorf("equipSkinHistSize(G1) = %d, want 1280", got) } } diff --git a/server/channelserver/handlers_data.go b/server/channelserver/handlers_data.go index bc7e34896..5b85f2d01 100644 --- a/server/channelserver/handlers_data.go +++ b/server/channelserver/handlers_data.go @@ -70,7 +70,7 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) { characterSaveData.updateSaveDataWithStruct() } - if characterSaveData.Name == s.Name || _config.ErupeConfig.RealClientMode <= _config.S10 { + if characterSaveData.Name == s.Name || s.server.erupeConfig.RealClientMode <= _config.S10 { characterSaveData.Save(s) s.logger.Info("Wrote recompressed savedata back to DB.") } else { diff --git a/server/channelserver/handlers_distitem.go b/server/channelserver/handlers_distitem.go index 8c10a648d..81675997e 100644 --- a/server/channelserver/handlers_distitem.go +++ b/server/channelserver/handlers_distitem.go @@ -65,7 +65,7 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(dist.Rights) bf.WriteUint16(dist.TimesAcceptable) bf.WriteUint16(dist.TimesAccepted) - if _config.ErupeConfig.RealClientMode >= _config.G9 { + if s.server.erupeConfig.RealClientMode >= _config.G9 { bf.WriteUint16(0) // Unk } bf.WriteInt16(dist.MinHR) @@ -74,29 +74,29 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { bf.WriteInt16(dist.MaxSR) bf.WriteInt16(dist.MinGR) bf.WriteInt16(dist.MaxGR) - if _config.ErupeConfig.RealClientMode >= _config.G7 { + if s.server.erupeConfig.RealClientMode >= _config.G7 { bf.WriteUint8(0) // Unk } - if _config.ErupeConfig.RealClientMode >= _config.G6 { + if s.server.erupeConfig.RealClientMode >= _config.G6 { bf.WriteUint16(0) // Unk } - if _config.ErupeConfig.RealClientMode >= _config.G8 { + if s.server.erupeConfig.RealClientMode >= _config.G8 { if dist.Selection { bf.WriteUint8(2) // Selection } else { bf.WriteUint8(0) } } - if _config.ErupeConfig.RealClientMode >= _config.G7 { + if s.server.erupeConfig.RealClientMode >= _config.G7 { bf.WriteUint16(0) // Unk bf.WriteUint16(0) // Unk } - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if s.server.erupeConfig.RealClientMode >= _config.G10 { bf.WriteUint8(0) // Unk } ps.Uint8(bf, dist.EventName, true) k := 6 - if _config.ErupeConfig.RealClientMode >= _config.G8 { + if s.server.erupeConfig.RealClientMode >= _config.G8 { k = 13 } for i := 0; i < 6; i++ { @@ -105,7 +105,7 @@ func handleMsgMhfEnumerateDistItem(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(0) } } - if _config.ErupeConfig.RealClientMode >= _config.Z2 { + if s.server.erupeConfig.RealClientMode >= _config.Z2 { i := uint8(0) bf.WriteUint8(i) if i <= 10 { @@ -154,7 +154,7 @@ func handleMsgMhfApplyDistItem(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint8(item.ItemType) bf.WriteUint32(item.ItemID) bf.WriteUint32(item.Quantity) - if _config.ErupeConfig.RealClientMode >= _config.G8 { + if s.server.erupeConfig.RealClientMode >= _config.G8 { bf.WriteUint32(item.ID) } } diff --git a/server/channelserver/handlers_event.go b/server/channelserver/handlers_event.go index 12751ee40..8b0bfaf0d 100644 --- a/server/channelserver/handlers_event.go +++ b/server/channelserver/handlers_event.go @@ -69,7 +69,7 @@ func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) { err := s.server.db.QueryRowx(`SELECT start_time, featured FROM feature_weapon WHERE start_time=$1`, t).StructScan(&temp) if err != nil || temp.StartTime.IsZero() { weapons := token.RNG.Intn(s.server.erupeConfig.GameplayOptions.MaxFeatureWeapons-s.server.erupeConfig.GameplayOptions.MinFeatureWeapons+1) + s.server.erupeConfig.GameplayOptions.MinFeatureWeapons - temp = generateFeatureWeapons(weapons) + temp = generateFeatureWeapons(weapons, s.server.erupeConfig.RealClientMode) temp.StartTime = t if _, err := s.server.db.Exec(`INSERT INTO feature_weapon VALUES ($1, $2)`, temp.StartTime, temp.ActiveFeatures); err != nil { s.logger.Error("Failed to insert feature weapon", zap.Error(err)) @@ -89,15 +89,15 @@ func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) { doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } -func generateFeatureWeapons(count int) activeFeature { +func generateFeatureWeapons(count int, mode _config.Mode) activeFeature { _max := 14 - if _config.ErupeConfig.RealClientMode < _config.ZZ { + if mode < _config.ZZ { _max = 13 } - if _config.ErupeConfig.RealClientMode < _config.G10 { + if mode < _config.G10 { _max = 12 } - if _config.ErupeConfig.RealClientMode < _config.GG { + if mode < _config.GG { _max = 11 } if count > _max { diff --git a/server/channelserver/handlers_event_test.go b/server/channelserver/handlers_event_test.go index 60fd66713..900423b82 100644 --- a/server/channelserver/handlers_event_test.go +++ b/server/channelserver/handlers_event_test.go @@ -4,6 +4,7 @@ import ( "math/bits" "testing" + _config "erupe-ce/config" "erupe-ce/network/mhfpacket" ) @@ -121,7 +122,7 @@ func TestGenerateFeatureWeapons(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := generateFeatureWeapons(tt.count) + result := generateFeatureWeapons(tt.count, _config.ZZ) // Result should be non-zero for positive counts if tt.count > 0 && result.ActiveFeatures == 0 { @@ -142,7 +143,7 @@ func TestGenerateFeatureWeapons_Randomness(t *testing.T) { iterations := 100 for i := 0; i < iterations; i++ { - result := generateFeatureWeapons(5) + result := generateFeatureWeapons(5, _config.ZZ) results[result.ActiveFeatures]++ } @@ -153,7 +154,7 @@ func TestGenerateFeatureWeapons_Randomness(t *testing.T) { } func TestGenerateFeatureWeapons_ZeroCount(t *testing.T) { - result := generateFeatureWeapons(0) + result := generateFeatureWeapons(0, _config.ZZ) // Should return 0 for no weapons if result.ActiveFeatures != 0 { @@ -180,7 +181,7 @@ func TestGenerateFeatureWeapons_BitCount(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := generateFeatureWeapons(tt.count) + result := generateFeatureWeapons(tt.count, _config.ZZ) setBits := bits.OnesCount32(result.ActiveFeatures) if setBits != tt.wantBits { t.Errorf("Set bits = %d, want %d (ActiveFeatures=0b%032b)", @@ -194,7 +195,7 @@ func TestGenerateFeatureWeapons_BitCount(t *testing.T) { // bits 0-13 (no bits above bit 13 should be set). func TestGenerateFeatureWeapons_BitsInRange(t *testing.T) { for i := 0; i < 50; i++ { - result := generateFeatureWeapons(7) + result := generateFeatureWeapons(7, _config.ZZ) // Bits 14+ should never be set if result.ActiveFeatures&^uint32(0x3FFF) != 0 { t.Errorf("Bits above 13 are set: 0x%08X", result.ActiveFeatures) @@ -205,7 +206,7 @@ func TestGenerateFeatureWeapons_BitsInRange(t *testing.T) { // TestGenerateFeatureWeapons_MaxYieldsAllBits verifies that requesting 14 // weapons sets exactly bits 0-13 (the value 16383 = 0x3FFF). func TestGenerateFeatureWeapons_MaxYieldsAllBits(t *testing.T) { - result := generateFeatureWeapons(14) + result := generateFeatureWeapons(14, _config.ZZ) if result.ActiveFeatures != 0x3FFF { t.Errorf("ActiveFeatures = 0x%04X, want 0x3FFF (all 14 bits set)", result.ActiveFeatures) } @@ -214,7 +215,7 @@ func TestGenerateFeatureWeapons_MaxYieldsAllBits(t *testing.T) { // TestGenerateFeatureWeapons_StartTimeZero verifies that the returned // activeFeature has a zero StartTime (not set by generateFeatureWeapons). func TestGenerateFeatureWeapons_StartTimeZero(t *testing.T) { - result := generateFeatureWeapons(5) + result := generateFeatureWeapons(5, _config.ZZ) if !result.StartTime.IsZero() { t.Errorf("StartTime should be zero, got %v", result.StartTime) } diff --git a/server/channelserver/handlers_festa.go b/server/channelserver/handlers_festa.go index e0452b385..b51277b5c 100644 --- a/server/channelserver/handlers_festa.go +++ b/server/channelserver/handlers_festa.go @@ -276,7 +276,7 @@ func handleMsgMhfInfoFesta(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(trial.Locale) bf.WriteUint16(trial.Reward) bf.WriteInt16(FestivalColorCodes[trial.Monopoly]) - if _config.ErupeConfig.RealClientMode >= _config.F4 { // Not in S6.0 + if s.server.erupeConfig.RealClientMode >= _config.F4 { // Not in S6.0 bf.WriteUint16(trial.Unk) } } @@ -320,13 +320,13 @@ func handleMsgMhfInfoFesta(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(reward.Quantity) bf.WriteUint16(reward.ItemID) // Confirmed present in G3 via Wii U disassembly of import_festa_info - if _config.ErupeConfig.RealClientMode >= _config.G3 { + if s.server.erupeConfig.RealClientMode >= _config.G3 { bf.WriteUint16(reward.MinHR) bf.WriteUint16(reward.MinSR) bf.WriteUint8(reward.MinGR) } } - if _config.ErupeConfig.RealClientMode <= _config.G61 { + if s.server.erupeConfig.RealClientMode <= _config.G61 { if s.server.erupeConfig.GameplayOptions.MaximumFP > 0xFFFF { s.server.erupeConfig.GameplayOptions.MaximumFP = 0xFFFF } @@ -393,7 +393,7 @@ func handleMsgMhfInfoFesta(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(100) // Normal rate bf.WriteUint16(50) // 50% penalty - if _config.ErupeConfig.RealClientMode >= _config.G52 { + if s.server.erupeConfig.RealClientMode >= _config.G52 { ps.Uint16(bf, "", false) } doAckBufSucceed(s, pkt.AckHandle, bf.Data()) @@ -480,7 +480,7 @@ func handleMsgMhfEnumerateFestaMember(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(0) // Unk for _, member := range validMembers { bf.WriteUint32(member.CharID) - if _config.ErupeConfig.RealClientMode <= _config.Z1 { + if s.server.erupeConfig.RealClientMode <= _config.Z1 { bf.WriteUint16(uint16(member.Souls)) bf.WriteUint16(0) } else { diff --git a/server/channelserver/handlers_guild_alliance.go b/server/channelserver/handlers_guild_alliance.go index e52cb1164..5d21c063b 100644 --- a/server/channelserver/handlers_guild_alliance.go +++ b/server/channelserver/handlers_guild_alliance.go @@ -223,14 +223,14 @@ func handleMsgMhfInfoJoint(s *Session, p mhfpacket.MHFPacket) { } bf.WriteUint32(alliance.ParentGuildID) bf.WriteUint32(alliance.ParentGuild.LeaderCharID) - bf.WriteUint16(alliance.ParentGuild.Rank()) + bf.WriteUint16(alliance.ParentGuild.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint16(alliance.ParentGuild.MemberCount) ps.Uint16(bf, alliance.ParentGuild.Name, true) ps.Uint16(bf, alliance.ParentGuild.LeaderName, true) if alliance.SubGuild1ID > 0 { bf.WriteUint32(alliance.SubGuild1ID) bf.WriteUint32(alliance.SubGuild1.LeaderCharID) - bf.WriteUint16(alliance.SubGuild1.Rank()) + bf.WriteUint16(alliance.SubGuild1.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint16(alliance.SubGuild1.MemberCount) ps.Uint16(bf, alliance.SubGuild1.Name, true) ps.Uint16(bf, alliance.SubGuild1.LeaderName, true) @@ -238,7 +238,7 @@ func handleMsgMhfInfoJoint(s *Session, p mhfpacket.MHFPacket) { if alliance.SubGuild2ID > 0 { bf.WriteUint32(alliance.SubGuild2ID) bf.WriteUint32(alliance.SubGuild2.LeaderCharID) - bf.WriteUint16(alliance.SubGuild2.Rank()) + bf.WriteUint16(alliance.SubGuild2.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint16(alliance.SubGuild2.MemberCount) ps.Uint16(bf, alliance.SubGuild2.Name, true) ps.Uint16(bf, alliance.SubGuild2.LeaderName, true) diff --git a/server/channelserver/handlers_guild_info.go b/server/channelserver/handlers_guild_info.go index e2b228973..68551813b 100644 --- a/server/channelserver/handlers_guild_info.go +++ b/server/channelserver/handlers_guild_info.go @@ -51,7 +51,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(guild.ID) bf.WriteUint32(guild.LeaderCharID) - bf.WriteUint16(guild.Rank()) + bf.WriteUint16(guild.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint16(guild.MemberCount) bf.WriteUint8(guild.MainMotto) @@ -114,7 +114,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { limit := s.server.erupeConfig.GameplayOptions.ClanMemberLimits[0][1] for _, j := range s.server.erupeConfig.GameplayOptions.ClanMemberLimits { - if guild.Rank() >= uint16(j[0]) { + if guild.Rank(s.server.erupeConfig.RealClientMode) >= uint16(j[0]) { limit = j[1] } } @@ -155,7 +155,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { } else { bf.WriteUint16(0) } - bf.WriteUint16(alliance.ParentGuild.Rank()) + bf.WriteUint16(alliance.ParentGuild.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint16(alliance.ParentGuild.MemberCount) ps.Uint16(bf, alliance.ParentGuild.Name, true) ps.Uint16(bf, alliance.ParentGuild.LeaderName, true) @@ -167,7 +167,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { } else { bf.WriteUint16(0) } - bf.WriteUint16(alliance.SubGuild1.Rank()) + bf.WriteUint16(alliance.SubGuild1.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint16(alliance.SubGuild1.MemberCount) ps.Uint16(bf, alliance.SubGuild1.Name, true) ps.Uint16(bf, alliance.SubGuild1.LeaderName, true) @@ -180,7 +180,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) { } else { bf.WriteUint16(0) } - bf.WriteUint16(alliance.SubGuild2.Rank()) + bf.WriteUint16(alliance.SubGuild2.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint16(alliance.SubGuild2.MemberCount) ps.Uint16(bf, alliance.SubGuild2.Name, true) ps.Uint16(bf, alliance.SubGuild2.LeaderName, true) @@ -460,7 +460,7 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint32(guild.LeaderCharID) bf.WriteUint16(guild.MemberCount) bf.WriteUint16(0x0000) // Unk - bf.WriteUint16(guild.Rank()) + bf.WriteUint16(guild.Rank(s.server.erupeConfig.RealClientMode)) bf.WriteUint32(uint32(guild.CreatedAt.Unix())) ps.Uint8(bf, guild.Name, true) ps.Uint8(bf, guild.LeaderName, true) diff --git a/server/channelserver/handlers_guild_test.go b/server/channelserver/handlers_guild_test.go index 35a3b6b5b..30e1daafa 100644 --- a/server/channelserver/handlers_guild_test.go +++ b/server/channelserver/handlers_guild_test.go @@ -117,16 +117,11 @@ func TestGuildRankCalculation(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - originalConfig := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = originalConfig }() - - _config.ErupeConfig.RealClientMode = tt.config - guild := &Guild{ RankRP: tt.rankRP, } - rank := guild.Rank() + rank := guild.Rank(tt.config) if rank != tt.wantRank { t.Errorf("guild rank calculation: got %d, want %d for RP %d", rank, tt.wantRank, tt.rankRP) } diff --git a/server/channelserver/handlers_helpers.go b/server/channelserver/handlers_helpers.go index 859942ebb..f2c30121b 100644 --- a/server/channelserver/handlers_helpers.go +++ b/server/channelserver/handlers_helpers.go @@ -65,7 +65,7 @@ func doAckSimpleFail(s *Session, ackHandle uint32, data []byte) { func updateRights(s *Session) { rightsInt := uint32(2) _ = s.server.db.QueryRow("SELECT rights FROM users u INNER JOIN characters c ON u.id = c.user_id WHERE c.id = $1", s.charID).Scan(&rightsInt) - s.courses, rightsInt = mhfcourse.GetCourseStruct(rightsInt) + s.courses, rightsInt = mhfcourse.GetCourseStruct(rightsInt, s.server.erupeConfig.DefaultCourses) update := &mhfpacket.MsgSysUpdateRight{ ClientRespAckHandle: 0, Bitfield: rightsInt, diff --git a/server/channelserver/handlers_house.go b/server/channelserver/handlers_house.go index 323676edd..2903c760d 100644 --- a/server/channelserver/handlers_house.go +++ b/server/channelserver/handlers_house.go @@ -133,7 +133,7 @@ func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint8(0) } bf.WriteUint16(house.HR) - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if s.server.erupeConfig.RealClientMode >= _config.G10 { bf.WriteUint16(house.GR) } ps.Uint8(bf, house.Name, true) @@ -516,7 +516,7 @@ func warehouseGetEquipment(s *Session, index uint8) []mhfitem.MHFEquipment { numStacks := box.ReadUint16() box.ReadUint16() // Unused for i := 0; i < int(numStacks); i++ { - equipment = append(equipment, mhfitem.ReadWarehouseEquipment(box)) + equipment = append(equipment, mhfitem.ReadWarehouseEquipment(box, s.server.erupeConfig.RealClientMode)) } } return equipment @@ -531,7 +531,7 @@ func handleMsgMhfEnumerateWarehouse(s *Session, p mhfpacket.MHFPacket) { bf.WriteBytes(mhfitem.SerializeWarehouseItems(items)) case 1: equipment := warehouseGetEquipment(s, pkt.BoxIndex) - bf.WriteBytes(mhfitem.SerializeWarehouseEquipment(equipment)) + bf.WriteBytes(mhfitem.SerializeWarehouseEquipment(equipment, s.server.erupeConfig.RealClientMode)) } if bf.Index() > 0 { doAckBufSucceed(s, pkt.AckHandle, bf.Data()) @@ -602,7 +602,7 @@ func handleMsgMhfUpdateWarehouse(s *Session, p mhfpacket.MHFPacket) { } } - serialized := mhfitem.SerializeWarehouseEquipment(fEquip) + serialized := mhfitem.SerializeWarehouseEquipment(fEquip, s.server.erupeConfig.RealClientMode) dataSize = len(serialized) s.logger.Debug("Warehouse save request", diff --git a/server/channelserver/handlers_house_test.go b/server/channelserver/handlers_house_test.go index d83480c1c..7a787335d 100644 --- a/server/channelserver/handlers_house_test.go +++ b/server/channelserver/handlers_house_test.go @@ -1,6 +1,7 @@ package channelserver import ( + _config "erupe-ce/config" "erupe-ce/common/mhfitem" "erupe-ce/common/token" "testing" @@ -92,7 +93,7 @@ func TestWarehouseEquipmentSerialization(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Serialize - serialized := mhfitem.SerializeWarehouseEquipment(tt.equipment) + serialized := mhfitem.SerializeWarehouseEquipment(tt.equipment, _config.ZZ) // Basic validation if serialized == nil { diff --git a/server/channelserver/handlers_items.go b/server/channelserver/handlers_items.go index 475111b42..2d2bd3d87 100644 --- a/server/channelserver/handlers_items.go +++ b/server/channelserver/handlers_items.go @@ -307,7 +307,7 @@ func handleMsgMhfStampcardStamp(s *Session, p mhfpacket.MHFPacket) { {300, 5392, 1, 5392, 3}, {999, 5392, 1, 5392, 4}, } - if _config.ErupeConfig.RealClientMode <= _config.Z1 { + if s.server.erupeConfig.RealClientMode <= _config.Z1 { for _, reward := range rewards { if pkt.HR >= reward.HR { pkt.Item1 = reward.Item1 @@ -320,7 +320,7 @@ func handleMsgMhfStampcardStamp(s *Session, p mhfpacket.MHFPacket) { bf := byteframe.NewByteFrame() bf.WriteUint16(pkt.HR) - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if s.server.erupeConfig.RealClientMode >= _config.G1 { bf.WriteUint16(pkt.GR) } var stamps, rewardTier, rewardUnk uint16 diff --git a/server/channelserver/handlers_misc.go b/server/channelserver/handlers_misc.go index 970a2bab9..473ede91d 100644 --- a/server/channelserver/handlers_misc.go +++ b/server/channelserver/handlers_misc.go @@ -79,7 +79,7 @@ func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) { bf.WriteInt32(s.server.erupeConfig.EarthStatus) bf.WriteInt32(s.server.erupeConfig.EarthID) for i, m := range s.server.erupeConfig.EarthMonsters { - if _config.ErupeConfig.RealClientMode <= _config.G9 { + if s.server.erupeConfig.RealClientMode <= _config.G9 { if i == 3 { break } @@ -156,12 +156,12 @@ func handleMsgMhfGetDailyMissionPersonal(s *Session, p mhfpacket.MHFPacket) {} func handleMsgMhfSetDailyMissionPersonal(s *Session, p mhfpacket.MHFPacket) {} -func equipSkinHistSize() int { +func equipSkinHistSize(mode _config.Mode) int { size := 3200 - if _config.ErupeConfig.RealClientMode <= _config.Z2 { + if mode <= _config.Z2 { size = 2560 } - if _config.ErupeConfig.RealClientMode <= _config.Z1 { + if mode <= _config.Z1 { size = 1280 } return size @@ -169,7 +169,7 @@ func equipSkinHistSize() int { func handleMsgMhfGetEquipSkinHist(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfGetEquipSkinHist) - size := equipSkinHistSize() + size := equipSkinHistSize(s.server.erupeConfig.RealClientMode) var data []byte err := s.server.db.QueryRow("SELECT COALESCE(skin_hist::bytea, $2::bytea) FROM characters WHERE id = $1", s.charID, make([]byte, size)).Scan(&data) if err != nil { @@ -181,7 +181,7 @@ func handleMsgMhfGetEquipSkinHist(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfUpdateEquipSkinHist(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfUpdateEquipSkinHist) - size := equipSkinHistSize() + size := equipSkinHistSize(s.server.erupeConfig.RealClientMode) var data []byte err := s.server.db.QueryRow("SELECT COALESCE(skin_hist, $2) FROM characters WHERE id = $1", s.charID, make([]byte, size)).Scan(&data) if err != nil { diff --git a/server/channelserver/handlers_quest.go b/server/channelserver/handlers_quest.go index 2a6610c13..48620b5a8 100644 --- a/server/channelserver/handlers_quest.go +++ b/server/channelserver/handlers_quest.go @@ -49,7 +49,7 @@ func equal(a, b []byte) bool { } // BackportQuest converts a quest binary to an older format. -func BackportQuest(data []byte) []byte { +func BackportQuest(data []byte, mode _config.Mode) []byte { wp := binary.LittleEndian.Uint32(data[0:4]) + 96 rp := wp + 4 for i := uint32(0); i < 6; i++ { @@ -61,16 +61,16 @@ func BackportQuest(data []byte) []byte { } fillLength := uint32(108) - if _config.ErupeConfig.RealClientMode <= _config.S6 { + if mode <= _config.S6 { fillLength = 44 - } else if _config.ErupeConfig.RealClientMode <= _config.F5 { + } else if mode <= _config.F5 { fillLength = 52 - } else if _config.ErupeConfig.RealClientMode <= _config.G101 { + } else if mode <= _config.G101 { fillLength = 76 } copy(data[wp:wp+fillLength], data[rp:rp+fillLength]) - if _config.ErupeConfig.RealClientMode <= _config.G91 { + if mode <= _config.G91 { patterns := [][]byte{ {0x0A, 0x00, 0x01, 0x33, 0xD7, 0x00}, // 10% Armor Sphere -> Stone {0x06, 0x00, 0x02, 0x33, 0xD8, 0x00}, // 6% Armor Sphere+ -> Iron Ore @@ -87,7 +87,7 @@ func BackportQuest(data []byte) []byte { } } - if _config.ErupeConfig.RealClientMode <= _config.S6 { + if mode <= _config.S6 { binary.LittleEndian.PutUint32(data[16:20], binary.LittleEndian.Uint32(data[8:12])) } return data @@ -133,8 +133,8 @@ func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) { doAckBufFail(s, pkt.AckHandle, nil) return } - if _config.ErupeConfig.RealClientMode <= _config.Z1 && s.server.erupeConfig.DebugOptions.AutoQuestBackport { - data = BackportQuest(decryption.UnpackSimple(data)) + if s.server.erupeConfig.RealClientMode <= _config.Z1 && s.server.erupeConfig.DebugOptions.AutoQuestBackport { + data = BackportQuest(decryption.UnpackSimple(data), s.server.erupeConfig.RealClientMode) } doAckBufSucceed(s, pkt.AckHandle, data) } @@ -230,21 +230,21 @@ func loadQuestFile(s *Session, questId int) []byte { } decrypted := decryption.UnpackSimple(file) - if _config.ErupeConfig.RealClientMode <= _config.Z1 && s.server.erupeConfig.DebugOptions.AutoQuestBackport { - decrypted = BackportQuest(decrypted) + if s.server.erupeConfig.RealClientMode <= _config.Z1 && s.server.erupeConfig.DebugOptions.AutoQuestBackport { + decrypted = BackportQuest(decrypted, s.server.erupeConfig.RealClientMode) } fileBytes := byteframe.NewByteFrameFromBytes(decrypted) fileBytes.SetLE() _, _ = fileBytes.Seek(int64(fileBytes.ReadUint32()), 0) bodyLength := 320 - if _config.ErupeConfig.RealClientMode <= _config.S6 { + if s.server.erupeConfig.RealClientMode <= _config.S6 { bodyLength = 160 - } else if _config.ErupeConfig.RealClientMode <= _config.F5 { + } else if s.server.erupeConfig.RealClientMode <= _config.F5 { bodyLength = 168 - } else if _config.ErupeConfig.RealClientMode <= _config.G101 { + } else if s.server.erupeConfig.RealClientMode <= _config.G101 { bodyLength = 192 - } else if _config.ErupeConfig.RealClientMode <= _config.Z1 { + } else if s.server.erupeConfig.RealClientMode <= _config.Z1 { bodyLength = 224 } @@ -318,7 +318,7 @@ func makeEventQuest(s *Session, rows *sql.Rows) ([]byte, error) { bf.WriteBool(true) } bf.WriteUint16(0) // Unk - if _config.ErupeConfig.RealClientMode >= _config.G2 { + if s.server.erupeConfig.RealClientMode >= _config.G2 { bf.WriteUint32(mark) } bf.WriteUint16(0) // Unk @@ -616,23 +616,23 @@ func handleMsgMhfEnumerateQuest(s *Session, p mhfpacket.MHFPacket) { tuneValues = temp tuneLimit := 770 - if _config.ErupeConfig.RealClientMode <= _config.G1 { + if s.server.erupeConfig.RealClientMode <= _config.G1 { tuneLimit = 256 - } else if _config.ErupeConfig.RealClientMode <= _config.G3 { + } else if s.server.erupeConfig.RealClientMode <= _config.G3 { tuneLimit = 283 - } else if _config.ErupeConfig.RealClientMode <= _config.GG { + } else if s.server.erupeConfig.RealClientMode <= _config.GG { tuneLimit = 315 - } else if _config.ErupeConfig.RealClientMode <= _config.G61 { + } else if s.server.erupeConfig.RealClientMode <= _config.G61 { tuneLimit = 332 - } else if _config.ErupeConfig.RealClientMode <= _config.G7 { + } else if s.server.erupeConfig.RealClientMode <= _config.G7 { tuneLimit = 339 - } else if _config.ErupeConfig.RealClientMode <= _config.G81 { + } else if s.server.erupeConfig.RealClientMode <= _config.G81 { tuneLimit = 396 - } else if _config.ErupeConfig.RealClientMode <= _config.G91 { + } else if s.server.erupeConfig.RealClientMode <= _config.G91 { tuneLimit = 694 - } else if _config.ErupeConfig.RealClientMode <= _config.G101 { + } else if s.server.erupeConfig.RealClientMode <= _config.G101 { tuneLimit = 704 - } else if _config.ErupeConfig.RealClientMode <= _config.Z2 { + } else if s.server.erupeConfig.RealClientMode <= _config.Z2 { tuneLimit = 750 } if len(tuneValues) > tuneLimit { diff --git a/server/channelserver/handlers_quest_backport_test.go b/server/channelserver/handlers_quest_backport_test.go index b07bca4c3..73dffc61f 100644 --- a/server/channelserver/handlers_quest_backport_test.go +++ b/server/channelserver/handlers_quest_backport_test.go @@ -8,13 +8,6 @@ import ( ) func TestBackportQuest_Basic(t *testing.T) { - // Set up config for the test - oldConfig := _config.ErupeConfig - defer func() { _config.ErupeConfig = oldConfig }() - - _config.ErupeConfig = &_config.Config{} - _config.ErupeConfig.RealClientMode = _config.ZZ - // Create a quest data buffer large enough for BackportQuest to work with. // The function reads a uint32 from data[0:4] as offset, then works at offset+96. // We need at least offset + 96 + 108 + 6*8 bytes. @@ -27,7 +20,7 @@ func TestBackportQuest_Basic(t *testing.T) { data[i] = byte(i & 0xFF) } - result := BackportQuest(data) + result := BackportQuest(data, _config.ZZ) if result == nil { t.Fatal("BackportQuest returned nil") } @@ -37,12 +30,6 @@ func TestBackportQuest_Basic(t *testing.T) { } func TestBackportQuest_S6Mode(t *testing.T) { - oldConfig := _config.ErupeConfig - defer func() { _config.ErupeConfig = oldConfig }() - - _config.ErupeConfig = &_config.Config{} - _config.ErupeConfig.RealClientMode = _config.S6 - data := make([]byte, 512) binary.LittleEndian.PutUint32(data[0:4], 0) @@ -56,7 +43,7 @@ func TestBackportQuest_S6Mode(t *testing.T) { // Set some values at data[8:12] so we can check they get copied to data[16:20] binary.LittleEndian.PutUint32(data[8:12], 0xDEADBEEF) - result := BackportQuest(data) + result := BackportQuest(data, _config.S6) if result == nil { t.Fatal("BackportQuest returned nil") } @@ -69,12 +56,6 @@ func TestBackportQuest_S6Mode(t *testing.T) { } func TestBackportQuest_G91Mode_PatternReplacement(t *testing.T) { - oldConfig := _config.ErupeConfig - defer func() { _config.ErupeConfig = oldConfig }() - - _config.ErupeConfig = &_config.Config{} - _config.ErupeConfig.RealClientMode = _config.G91 - data := make([]byte, 512) binary.LittleEndian.PutUint32(data[0:4], 0) @@ -86,7 +67,7 @@ func TestBackportQuest_G91Mode_PatternReplacement(t *testing.T) { data[offset+2] = 0x01 data[offset+3] = 0x33 - result := BackportQuest(data) + result := BackportQuest(data, _config.G91) // After BackportQuest, the pattern's last 2 bytes should be replaced if result[offset+2] != 0xD7 || result[offset+3] != 0x00 { @@ -96,32 +77,20 @@ func TestBackportQuest_G91Mode_PatternReplacement(t *testing.T) { } func TestBackportQuest_F5Mode(t *testing.T) { - oldConfig := _config.ErupeConfig - defer func() { _config.ErupeConfig = oldConfig }() - - _config.ErupeConfig = &_config.Config{} - _config.ErupeConfig.RealClientMode = _config.F5 - data := make([]byte, 512) binary.LittleEndian.PutUint32(data[0:4], 0) - result := BackportQuest(data) + result := BackportQuest(data, _config.F5) if result == nil { t.Fatal("BackportQuest returned nil") } } func TestBackportQuest_G101Mode(t *testing.T) { - oldConfig := _config.ErupeConfig - defer func() { _config.ErupeConfig = oldConfig }() - - _config.ErupeConfig = &_config.Config{} - _config.ErupeConfig.RealClientMode = _config.G101 - data := make([]byte, 512) binary.LittleEndian.PutUint32(data[0:4], 0) - result := BackportQuest(data) + result := BackportQuest(data, _config.G101) if result == nil { t.Fatal("BackportQuest returned nil") } diff --git a/server/channelserver/handlers_quest_test.go b/server/channelserver/handlers_quest_test.go index e4db7981b..e781cc5a0 100644 --- a/server/channelserver/handlers_quest_test.go +++ b/server/channelserver/handlers_quest_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/binary" "erupe-ce/common/byteframe" + _config "erupe-ce/config" "erupe-ce/network/mhfpacket" "os" "path/filepath" @@ -61,7 +62,7 @@ func TestBackportQuestBasic(t *testing.T) { } }() - result := BackportQuest(data) + result := BackportQuest(data, _config.ZZ) if result != nil && !tc.verify(result) { t.Errorf("BackportQuest verification failed for result: %d bytes", len(result)) } @@ -685,7 +686,7 @@ func BenchmarkBackportQuest(b *testing.B) { binary.LittleEndian.PutUint32(data[0:4], 100) for i := 0; i < b.N; i++ { - _ = BackportQuest(data) + _ = BackportQuest(data, _config.ZZ) } } diff --git a/server/channelserver/handlers_savedata_integration_test.go b/server/channelserver/handlers_savedata_integration_test.go index b44c5f4a6..ce0a92e69 100644 --- a/server/channelserver/handlers_savedata_integration_test.go +++ b/server/channelserver/handlers_savedata_integration_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + _config "erupe-ce/config" "erupe-ce/common/mhfitem" "erupe-ce/network/mhfpacket" "erupe-ce/server/channelserver/compression/nullcomp" @@ -214,7 +215,7 @@ func TestSaveLoad_Warehouse(t *testing.T) { } // Serialize and save to warehouse - serializedEquip := mhfitem.SerializeWarehouseEquipment(equipment) + serializedEquip := mhfitem.SerializeWarehouseEquipment(equipment, _config.ZZ) // Initialize warehouse row then update _, _ = db.Exec("INSERT INTO warehouse (character_id) VALUES ($1) ON CONFLICT DO NOTHING", charID) @@ -425,7 +426,7 @@ func TestSaveLoad_CraftedEquipment(t *testing.T) { } equipment := []mhfitem.MHFEquipment{equip} - serialized := mhfitem.SerializeWarehouseEquipment(equipment) + serialized := mhfitem.SerializeWarehouseEquipment(equipment, _config.ZZ) // Save to warehouse _, _ = db.Exec("INSERT INTO warehouse (character_id) VALUES ($1) ON CONFLICT DO NOTHING", charID) diff --git a/server/channelserver/handlers_session.go b/server/channelserver/handlers_session.go index ab39c6b95..e52510995 100644 --- a/server/channelserver/handlers_session.go +++ b/server/channelserver/handlers_session.go @@ -378,7 +378,7 @@ func handleMsgSysIssueLogkey(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysRecordLog(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysRecordLog) - if _config.ErupeConfig.RealClientMode == _config.ZZ { + if s.server.erupeConfig.RealClientMode == _config.ZZ { bf := byteframe.NewByteFrameFromBytes(pkt.Data) _, _ = bf.Seek(32, 0) var val uint8 @@ -536,7 +536,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { resp.WriteUint16(uint16(len(r.userBin3))) // TODO: This case might be <=G2 - if _config.ErupeConfig.RealClientMode <= _config.G1 { + if s.server.erupeConfig.RealClientMode <= _config.G1 { resp.WriteBytes(make([]byte, 8)) } else { resp.WriteBytes(make([]byte, 40)) @@ -566,7 +566,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { case 0: values := bf.ReadUint8() for i := uint8(0); i < values; i++ { - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { findPartyParams.RankRestriction = bf.ReadInt16() } else { findPartyParams.RankRestriction = int16(bf.ReadInt8()) @@ -575,7 +575,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { case 1: values := bf.ReadUint8() for i := uint8(0); i < values; i++ { - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { findPartyParams.Targets = append(findPartyParams.Targets, bf.ReadInt16()) } else { findPartyParams.Targets = append(findPartyParams.Targets, int16(bf.ReadInt8())) @@ -585,7 +585,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { values := bf.ReadUint8() for i := uint8(0); i < values; i++ { var value int16 - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { value = bf.ReadInt16() } else { value = int16(bf.ReadInt8()) @@ -606,7 +606,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { case 3: // Unknown values := bf.ReadUint8() for i := uint8(0); i < values; i++ { - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { findPartyParams.Unk0 = append(findPartyParams.Unk0, bf.ReadInt16()) } else { findPartyParams.Unk0 = append(findPartyParams.Unk0, int16(bf.ReadInt8())) @@ -615,7 +615,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { case 4: // Looking for n or already have n values := bf.ReadUint8() for i := uint8(0); i < values; i++ { - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { findPartyParams.Unk1 = append(findPartyParams.Unk1, bf.ReadInt16()) } else { findPartyParams.Unk1 = append(findPartyParams.Unk1, int16(bf.ReadInt8())) @@ -624,7 +624,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { case 5: values := bf.ReadUint8() for i := uint8(0); i < values; i++ { - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { findPartyParams.QuestID = append(findPartyParams.QuestID, bf.ReadInt16()) } else { findPartyParams.QuestID = append(findPartyParams.QuestID, int16(bf.ReadInt8())) @@ -661,15 +661,15 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { _, _ = sb3.Seek(4, 0) stageDataParams := 7 - if _config.ErupeConfig.RealClientMode <= _config.G10 { + if s.server.erupeConfig.RealClientMode <= _config.G10 { stageDataParams = 4 - } else if _config.ErupeConfig.RealClientMode <= _config.Z1 { + } else if s.server.erupeConfig.RealClientMode <= _config.Z1 { stageDataParams = 6 } var stageData []int16 for i := 0; i < stageDataParams; i++ { - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { stageData = append(stageData, sb3.ReadInt16()) } else { stageData = append(stageData, int16(sb3.ReadInt8())) @@ -746,7 +746,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { resp.WriteUint8(uint8(len(sr.rawBinData1))) for i := range sr.stageData { - if _config.ErupeConfig.RealClientMode >= _config.Z1 { + if s.server.erupeConfig.RealClientMode >= _config.Z1 { resp.WriteInt16(sr.stageData[i]) } else { resp.WriteInt8(int8(sr.stageData[i])) diff --git a/server/channelserver/handlers_shop.go b/server/channelserver/handlers_shop.go index 2b1d3e5e6..5555c53de 100644 --- a/server/channelserver/handlers_shop.go +++ b/server/channelserver/handlers_shop.go @@ -25,11 +25,11 @@ type ShopItem struct { RoadFatalis uint16 `db:"road_fatalis"` } -func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem) { +func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem, mode _config.Mode) { bf.WriteUint16(uint16(len(items))) bf.WriteUint16(uint16(len(items))) for _, item := range items { - if _config.ErupeConfig.RealClientMode >= _config.Z2 { + if mode >= _config.Z2 { bf.WriteUint32(item.ID) } bf.WriteUint32(item.ItemID) @@ -37,19 +37,19 @@ func writeShopItems(bf *byteframe.ByteFrame, items []ShopItem) { bf.WriteUint16(item.Quantity) bf.WriteUint16(item.MinHR) bf.WriteUint16(item.MinSR) - if _config.ErupeConfig.RealClientMode >= _config.Z2 { + if mode >= _config.Z2 { bf.WriteUint16(item.MinGR) } bf.WriteUint8(0) // Unk bf.WriteUint8(item.StoreLevel) - if _config.ErupeConfig.RealClientMode >= _config.Z2 { + if mode >= _config.Z2 { bf.WriteUint16(item.MaxQuantity) bf.WriteUint16(item.UsedQuantity) } - if _config.ErupeConfig.RealClientMode == _config.Z1 { + if mode == _config.Z1 { bf.WriteUint8(uint8(item.RoadFloors)) bf.WriteUint8(uint8(item.RoadFatalis)) - } else if _config.ErupeConfig.RealClientMode >= _config.Z2 { + } else if mode >= _config.Z2 { bf.WriteUint16(item.RoadFloors) bf.WriteUint16(item.RoadFatalis) } @@ -90,7 +90,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) { switch pkt.ShopType { case 1: // Running gachas // Fundamentally, gacha works completely differently, just hide it for now. - if _config.ErupeConfig.RealClientMode <= _config.G7 { + if s.server.erupeConfig.RealClientMode <= _config.G7 { doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) return } @@ -123,7 +123,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) { ps.Uint8(bf, g.Name, true) ps.Uint8(bf, g.URLBanner, false) ps.Uint8(bf, g.URLFeature, false) - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if s.server.erupeConfig.RealClientMode >= _config.G10 { bf.WriteBool(g.Wide) ps.Uint8(bf, g.URLThumbnail, false) } @@ -133,7 +133,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) { bf.WriteUint16(0) } bf.WriteUint8(g.GachaType) - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if s.server.erupeConfig.RealClientMode >= _config.G10 { bf.WriteBool(g.Hidden) } } @@ -223,7 +223,7 @@ func handleMsgMhfEnumerateShop(s *Session, p mhfpacket.MHFPacket) { if len(items) > int(pkt.Limit) { items = items[:pkt.Limit] } - writeShopItems(bf, items) + writeShopItems(bf, items, s.server.erupeConfig.RealClientMode) doAckBufSucceed(s, pkt.AckHandle, bf.Data()) } } @@ -303,7 +303,7 @@ func handleMsgMhfGetFpointExchangeList(s *Session, p mhfpacket.MHFPacket) { exchanges = append(exchanges, exchange) } } - if _config.ErupeConfig.RealClientMode <= _config.Z2 { + if s.server.erupeConfig.RealClientMode <= _config.Z2 { bf.WriteUint8(uint8(len(exchanges))) bf.WriteUint8(uint8(buyables)) } else { diff --git a/server/channelserver/handlers_shop_gacha_test.go b/server/channelserver/handlers_shop_gacha_test.go index 787a860bb..3000925c2 100644 --- a/server/channelserver/handlers_shop_gacha_test.go +++ b/server/channelserver/handlers_shop_gacha_test.go @@ -4,13 +4,14 @@ import ( "testing" "erupe-ce/common/byteframe" + _config "erupe-ce/config" ) func TestWriteShopItems_Empty(t *testing.T) { bf := byteframe.NewByteFrame() items := []ShopItem{} - writeShopItems(bf, items) + writeShopItems(bf, items, _config.ZZ) result := byteframe.NewByteFrameFromBytes(bf.Data()) count1 := result.ReadUint16() @@ -43,7 +44,7 @@ func TestWriteShopItems_SingleItem(t *testing.T) { }, } - writeShopItems(bf, items) + writeShopItems(bf, items, _config.ZZ) result := byteframe.NewByteFrameFromBytes(bf.Data()) count1 := result.ReadUint16() @@ -117,7 +118,7 @@ func TestWriteShopItems_MultipleItems(t *testing.T) { {ID: 3, ItemID: 300, Cost: 2000, Quantity: 1}, } - writeShopItems(bf, items) + writeShopItems(bf, items, _config.ZZ) result := byteframe.NewByteFrameFromBytes(bf.Data()) count1 := result.ReadUint16() diff --git a/server/channelserver/handlers_tower.go b/server/channelserver/handlers_tower.go index 3114d8dfd..dec9e4202 100644 --- a/server/channelserver/handlers_tower.go +++ b/server/channelserver/handlers_tower.go @@ -75,7 +75,7 @@ func handleMsgMhfGetTowerInfo(s *Session, p mhfpacket.MHFPacket) { } } - if _config.ErupeConfig.RealClientMode <= _config.G7 { + if s.server.erupeConfig.RealClientMode <= _config.G7 { towerInfo.Level = towerInfo.Level[:1] } diff --git a/server/channelserver/integration_test.go b/server/channelserver/integration_test.go index f1bd5a12e..b7b445014 100644 --- a/server/channelserver/integration_test.go +++ b/server/channelserver/integration_test.go @@ -621,16 +621,13 @@ func IntegrationTest_ClientVersionCompatibility(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - originalVersion := _config.ErupeConfig.RealClientMode - defer func() { _config.ErupeConfig.RealClientMode = originalVersion }() - - _config.ErupeConfig.RealClientMode = tt.clientVersion - mock := &MockCryptConn{sentPackets: make([][]byte, 0)} s := &Session{ sendPackets: make(chan packet, 100), - server: &Server{ - erupeConfig: _config.ErupeConfig, + server: &Server{ + erupeConfig: &_config.Config{ + RealClientMode: tt.clientVersion, + }, }, } s.cryptConn = mock diff --git a/server/channelserver/model_character.go b/server/channelserver/model_character.go index a70d59076..f8b2eb5f8 100644 --- a/server/channelserver/model_character.go +++ b/server/channelserver/model_character.go @@ -35,6 +35,7 @@ type CharacterSaveData struct { CharID uint32 Name string IsNewCharacter bool + Mode _config.Mode Pointers map[SavePointer]int Gender bool @@ -56,9 +57,9 @@ type CharacterSaveData struct { decompSave []byte } -func getPointers() map[SavePointer]int { +func getPointers(mode _config.Mode) map[SavePointer]int { pointers := map[SavePointer]int{pGender: 81, lBookshelfData: 5576} - switch _config.ErupeConfig.RealClientMode { + switch mode { case _config.ZZ: pointers[pPlaytime] = 128356 pointers[pWeaponID] = 128522 @@ -114,9 +115,9 @@ func getPointers() map[SavePointer]int { pointers[pGardenData] = 26424 pointers[pRP] = 26614 } - if _config.ErupeConfig.RealClientMode == _config.G5 { + if mode == _config.G5 { pointers[lBookshelfData] = 5548 - } else if _config.ErupeConfig.RealClientMode <= _config.GG { + } else if mode <= _config.GG { pointers[lBookshelfData] = 4520 } return pointers @@ -144,10 +145,10 @@ func (save *CharacterSaveData) Decompress() error { func (save *CharacterSaveData) updateSaveDataWithStruct() { rpBytes := make([]byte, 2) binary.LittleEndian.PutUint16(rpBytes, save.RP) - if _config.ErupeConfig.RealClientMode >= _config.F4 { + if save.Mode >= _config.F4 { copy(save.decompSave[save.Pointers[pRP]:save.Pointers[pRP]+2], rpBytes) } - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if save.Mode >= _config.G10 { copy(save.decompSave[save.Pointers[pKQF]:save.Pointers[pKQF]+8], save.KQF) } } @@ -161,7 +162,7 @@ func (save *CharacterSaveData) updateStructWithSaveData() { save.Gender = false } if !save.IsNewCharacter { - if _config.ErupeConfig.RealClientMode >= _config.S6 { + if save.Mode >= _config.S6 { save.RP = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pRP] : save.Pointers[pRP]+2]) save.HouseTier = save.decompSave[save.Pointers[pHouseTier] : save.Pointers[pHouseTier]+5] save.HouseData = save.decompSave[save.Pointers[pHouseData] : save.Pointers[pHouseData]+195] @@ -173,12 +174,12 @@ func (save *CharacterSaveData) updateStructWithSaveData() { save.WeaponType = save.decompSave[save.Pointers[pWeaponType]] save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pWeaponID] : save.Pointers[pWeaponID]+2]) save.HR = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pHR] : save.Pointers[pHR]+2]) - if _config.ErupeConfig.RealClientMode >= _config.G1 { + if save.Mode >= _config.G1 { if save.HR == uint16(999) { save.GR = grpToGR(int(binary.LittleEndian.Uint32(save.decompSave[save.Pointers[pGRP] : save.Pointers[pGRP]+4]))) } } - if _config.ErupeConfig.RealClientMode >= _config.G10 { + if save.Mode >= _config.G10 { save.KQF = save.decompSave[save.Pointers[pKQF] : save.Pointers[pKQF]+8] } } diff --git a/server/channelserver/session_lifecycle_integration_test.go b/server/channelserver/session_lifecycle_integration_test.go index d433e5307..e94d9b276 100644 --- a/server/channelserver/session_lifecycle_integration_test.go +++ b/server/channelserver/session_lifecycle_integration_test.go @@ -176,7 +176,7 @@ func TestSessionLifecycle_WarehouseDataPersistence(t *testing.T) { createTestEquipmentItem(102, 3), } - serializedEquip := mhfitem.SerializeWarehouseEquipment(equipment) + serializedEquip := mhfitem.SerializeWarehouseEquipment(equipment, _config.ZZ) // Save to warehouse directly (simulating a save handler) _, _ = db.Exec("INSERT INTO warehouse (character_id) VALUES ($1) ON CONFLICT DO NOTHING", charID) @@ -586,7 +586,9 @@ func createTestServerWithDB(t *testing.T, db *sqlx.DB) *Server { userBinaryParts: make(map[userBinaryPartID][]byte), minidataParts: make(map[uint32][]byte), semaphore: make(map[string]*Semaphore), - erupeConfig: _config.ErupeConfig, + erupeConfig: &_config.Config{ + RealClientMode: _config.ZZ, + }, isShuttingDown: false, } diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index bfd22414d..50e321801 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -145,6 +145,8 @@ func (s *Server) Start() error { } s.listener = l + initCommands(s.erupeConfig.Commands, s.logger) + go s.acceptClients() go s.manageSessions() go s.invalidateSessions() diff --git a/server/channelserver/sys_session.go b/server/channelserver/sys_session.go index b30190aec..7a3a9245c 100644 --- a/server/channelserver/sys_session.go +++ b/server/channelserver/sys_session.go @@ -81,9 +81,9 @@ func NewSession(server *Server, conn net.Conn) *Session { logger: server.logger.Named(conn.RemoteAddr().String()), server: server, rawConn: conn, - cryptConn: network.NewCryptConn(conn), + cryptConn: network.NewCryptConn(conn, server.erupeConfig.RealClientMode), sendPackets: make(chan packet, 20), - clientContext: &clientctx.ClientContext{}, + clientContext: &clientctx.ClientContext{RealClientMode: server.erupeConfig.RealClientMode}, lastPacket: time.Now(), objectID: server.getObjectId(), sessionStart: TimeAdjusted().Unix(), diff --git a/server/entranceserver/entrance_server.go b/server/entranceserver/entrance_server.go index 67d92b103..2af049605 100644 --- a/server/entranceserver/entrance_server.go +++ b/server/entranceserver/entrance_server.go @@ -104,7 +104,7 @@ func (s *Server) handleEntranceServerConnection(conn net.Conn) { } // Create a new encrypted connection handler and read a packet from it. - cc := network.NewCryptConn(conn) + cc := network.NewCryptConn(conn, s.erupeConfig.RealClientMode) pkt, err := cc.ReadPacket() if err != nil { s.logger.Warn("Error reading packet", zap.Error(err)) diff --git a/server/entranceserver/make_resp.go b/server/entranceserver/make_resp.go index bf461cfaa..dd78baea0 100644 --- a/server/entranceserver/make_resp.go +++ b/server/entranceserver/make_resp.go @@ -63,8 +63,8 @@ func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte { for channelIdx, ci := range si.Channels { sid := (serverIdx<<8 | 4096) + (channelIdx | 16) - if _config.ErupeConfig.DebugOptions.ProxyPort != 0 { - bf.WriteUint16(_config.ErupeConfig.DebugOptions.ProxyPort) + if config.DebugOptions.ProxyPort != 0 { + bf.WriteUint16(config.DebugOptions.ProxyPort) } else { bf.WriteUint16(ci.Port) } diff --git a/server/signserver/dbutils.go b/server/signserver/dbutils.go index cf2e713f6..c6930bf15 100644 --- a/server/signserver/dbutils.go +++ b/server/signserver/dbutils.go @@ -105,7 +105,7 @@ func (s *Server) getUserRights(uid uint32) uint32 { var rights uint32 if uid != 0 { _ = s.db.QueryRow("SELECT rights FROM users WHERE id=$1", uid).Scan(&rights) - _, rights = mhfcourse.GetCourseStruct(rights) + _, rights = mhfcourse.GetCourseStruct(rights, s.erupeConfig.DefaultCourses) } return rights } diff --git a/server/signserver/dbutils_test.go b/server/signserver/dbutils_test.go index b3c18443f..b1cf2492a 100644 --- a/server/signserver/dbutils_test.go +++ b/server/signserver/dbutils_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "erupe-ce/config" "github.com/DATA-DOG/go-sqlmock" "github.com/jmoiron/sqlx" "go.uber.org/zap" @@ -301,8 +302,9 @@ func newTestServerWithMock(t *testing.T) (*Server, sqlmock.Sqlmock) { sqlxDB := sqlx.NewDb(db, "sqlmock") server := &Server{ - logger: zap.NewNop(), - db: sqlxDB, + logger: zap.NewNop(), + db: sqlxDB, + erupeConfig: &_config.Config{}, } return server, mock diff --git a/server/signserver/session_test.go b/server/signserver/session_test.go index 8142e3a2b..4a27bf604 100644 --- a/server/signserver/session_test.go +++ b/server/signserver/session_test.go @@ -75,7 +75,7 @@ func TestSessionStruct(t *testing.T) { logger: logger, server: nil, rawConn: conn, - cryptConn: network.NewCryptConn(conn), + cryptConn: network.NewCryptConn(conn, _config.ZZ), } if s.logger != logger { @@ -145,7 +145,7 @@ func TestHandlePacketUnknownRequest(t *testing.T) { logger: logger, server: server, rawConn: conn, - cryptConn: network.NewCryptConn(conn), + cryptConn: network.NewCryptConn(conn, _config.ZZ), } bf := byteframe.NewByteFrame() @@ -176,7 +176,7 @@ func TestHandlePacketWithDevModeLogging(t *testing.T) { logger: logger, server: server, rawConn: conn, - cryptConn: network.NewCryptConn(conn), + cryptConn: network.NewCryptConn(conn, _config.ZZ), } bf := byteframe.NewByteFrame() @@ -214,7 +214,7 @@ func TestHandlePacketRequestTypes(t *testing.T) { logger: logger, server: server, rawConn: conn, - cryptConn: network.NewCryptConn(conn), + cryptConn: network.NewCryptConn(conn, _config.ZZ), } bf := byteframe.NewByteFrame() @@ -324,7 +324,7 @@ func TestMockConnDeadlines(t *testing.T) { func TestSessionWithCryptConn(t *testing.T) { conn := newMockConn() - cryptConn := network.NewCryptConn(conn) + cryptConn := network.NewCryptConn(conn, _config.ZZ) if cryptConn == nil { t.Fatal("NewCryptConn() returned nil") @@ -361,7 +361,7 @@ func TestSessionWorkWithDevModeLogging(t *testing.T) { logger: logger, server: server, rawConn: serverConn, - cryptConn: network.NewCryptConn(serverConn), + cryptConn: network.NewCryptConn(serverConn, _config.ZZ), } _ = clientConn.Close() @@ -386,7 +386,7 @@ func TestSessionWorkWithEmptyRead(t *testing.T) { logger: logger, server: server, rawConn: serverConn, - cryptConn: network.NewCryptConn(serverConn), + cryptConn: network.NewCryptConn(serverConn, _config.ZZ), } _ = clientConn.Close() diff --git a/server/signserver/sign_server.go b/server/signserver/sign_server.go index 4eae7ecea..be6957ce6 100644 --- a/server/signserver/sign_server.go +++ b/server/signserver/sign_server.go @@ -101,7 +101,7 @@ func (s *Server) handleConnection(conn net.Conn) { logger: s.logger, server: s, rawConn: conn, - cryptConn: network.NewCryptConn(conn), + cryptConn: network.NewCryptConn(conn, s.erupeConfig.RealClientMode), } // Do the session's work.