1
0
Protocol/opcodes_test.go

263 lines
5.7 KiB
Go

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)
}
})
}