package eq2net import ( "fmt" "testing" ) func TestGetOpcodeVersionV2(t *testing.T) { // Create a version map that matches the C++ implementation versionMap := OpcodeVersionMap{ 1: 546, 547: 889, 890: 1027, 1028: 1048, 1049: 1095, 1096: 1184, 1185: 1197, 1198: 1207, 1208: 1211, 1212: 9999, } tests := []struct { clientVersion uint16 expectedOpcode uint16 }{ // Test first range {1, 1}, {100, 1}, {546, 1}, // Test second range {547, 547}, {700, 547}, {889, 547}, // Test middle ranges {890, 890}, {1000, 890}, {1027, 890}, {1028, 1028}, {1048, 1028}, {1096, 1096}, {1100, 1096}, {1184, 1096}, {1185, 1185}, {1193, 1185}, {1197, 1185}, {1198, 1198}, {1200, 1198}, {1207, 1198}, {1208, 1208}, {1210, 1208}, {1211, 1208}, // Test last range {1212, 1212}, {2000, 1212}, {9999, 1212}, // Test out of range (should return client version) {10000, 10000}, } for _, tt := range tests { result := GetOpcodeVersion(tt.clientVersion, versionMap) if result != tt.expectedOpcode { t.Errorf("GetOpcodeVersion(%d) = %d, want %d", tt.clientVersion, result, tt.expectedOpcode) } } } func TestRegularOpcodeManagerV2(t *testing.T) { manager := NewRegularOpcodeManager(1193) // Test loading opcodes (simulating database results) opcodes := map[string]uint16{ "OP_LoginRequestMsg": 0x0001, "OP_LoginReplyMsg": 0x0002, "OP_WorldListMsg": 0x0003, "OP_PlayCharacterRequestMsg": 0x0004, } if !manager.LoadOpcodes(opcodes) { t.Fatal("Failed to load opcodes") } // Test EmuToEQ conversion eq := manager.EmuToEQ(OP_LoginRequestMsg) if eq != 0x0001 { t.Errorf("Expected EQ opcode 0x0001, got 0x%04x", eq) } // Test invalid opcode returns 0xCDCD eq = manager.EmuToEQ(OP_Unknown) if eq != 0xCDCD { t.Errorf("Expected 0xCDCD for unknown opcode, got 0x%04x", eq) } // Test EQToEmu conversion emu := manager.EQToEmu(0x0002) if emu != OP_LoginReplyMsg { t.Errorf("Expected emu opcode %v, got %v", OP_LoginReplyMsg, emu) } // Test unknown EQ opcode emu = manager.EQToEmu(0xFFFF) if emu != OP_Unknown { t.Errorf("Expected OP_Unknown for unknown EQ opcode, got %v", emu) } // Test name lookups name := manager.EmuToName(OP_LoginRequestMsg) if name != "OP_LoginRequestMsg" { t.Errorf("Expected 'OP_LoginRequestMsg', got '%s'", name) } name = manager.EQToName(0x0003) if name != "OP_WorldListMsg" { t.Errorf("Expected 'OP_WorldListMsg', got '%s'", name) } } func TestEQOpcodeManagerMapV2(t *testing.T) { // Create version map versions := OpcodeVersionMap{ 1185: 1197, 1198: 1207, 1208: 1211, } // Create opcodes for each version opcodesByVersion := map[uint16]map[string]uint16{ 1185: { "OP_LoginRequestMsg": 0x00B3, "OP_LoginReplyMsg": 0x00B6, }, 1198: { "OP_LoginRequestMsg": 0x00C1, "OP_LoginReplyMsg": 0x00C4, }, 1208: { "OP_LoginRequestMsg": 0x00D1, "OP_LoginReplyMsg": 0x00D4, }, } // Initialize the manager map managerMap := NewEQOpcodeManager() err := managerMap.LoadFromDatabase(versions, opcodesByVersion) if err != nil { t.Fatalf("Failed to load from database: %v", err) } // Test getting manager for client version 1193 (should use 1185 opcodes) manager := managerMap.GetManagerForClient(1193, versions) if manager == nil { t.Fatal("Failed to get manager for client version 1193") } eq := manager.EmuToEQ(OP_LoginRequestMsg) if eq != 0x00B3 { t.Errorf("Expected 0x00B3 for version 1193, got 0x%04x", eq) } // Test getting manager for client version 1200 (should use 1198 opcodes) manager = managerMap.GetManagerForClient(1200, versions) if manager == nil { t.Fatal("Failed to get manager for client version 1200") } eq = manager.EmuToEQ(OP_LoginRequestMsg) if eq != 0x00C1 { t.Errorf("Expected 0x00C1 for version 1200, got 0x%04x", eq) } // Test getting manager for client version 1210 (should use 1208 opcodes) manager = managerMap.GetManagerForClient(1210, versions) if manager == nil { t.Fatal("Failed to get manager for client version 1210") } eq = manager.EmuToEQ(OP_LoginRequestMsg) if eq != 0x00D1 { t.Errorf("Expected 0x00D1 for version 1210, got 0x%04x", eq) } } func TestNameSearch(t *testing.T) { // Test finding opcodes by name opcode := NameSearch("OP_LoginRequestMsg") if opcode != OP_LoginRequestMsg { t.Errorf("Expected %v, got %v", OP_LoginRequestMsg, opcode) } opcode = NameSearch("OP_WorldListMsg") if opcode != OP_WorldListMsg { t.Errorf("Expected %v, got %v", OP_WorldListMsg, opcode) } // Test unknown name opcode = NameSearch("OP_NonExistent") if opcode != OP_Unknown { t.Errorf("Expected OP_Unknown for non-existent name, got %v", opcode) } } // BenchmarkOpcodeConversionV2 benchmarks the new implementation func BenchmarkOpcodeConversionV2(b *testing.B) { manager := NewRegularOpcodeManager(1193) opcodes := make(map[string]uint16) // Add many opcodes for benchmarking for i := uint16(1); i <= 100; i++ { name := OpcodeNames[EmuOpcode(i)] if name == "" { name = fmt.Sprintf("OP_Test%d", i) OpcodeNames[EmuOpcode(i)] = name } opcodes[name] = i } manager.LoadOpcodes(opcodes) b.ResetTimer() b.Run("EmuToEQ", func(b *testing.B) { for i := 0; i < b.N; i++ { _ = manager.EmuToEQ(EmuOpcode(i%100 + 1)) } }) b.Run("EQToEmu", func(b *testing.B) { for i := 0; i < b.N; i++ { _ = manager.EQToEmu(uint16(i%100 + 1)) } }) b.Run("GetOpcodeVersion", func(b *testing.B) { versionMap := OpcodeVersionMap{ 1: 546, 547: 889, 890: 1027, 1028: 1048, 1049: 1095, 1096: 1184, 1185: 1197, 1198: 1207, 1208: 1211, 1212: 9999, } for i := 0; i < b.N; i++ { _ = GetOpcodeVersion(uint16(i%2000+1), versionMap) } }) }