mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-21 23:22:34 +01:00
RE'd putAdd_ud_point (FUN_114fd490) and putAdd_ud_tactics_point (FUN_114fe9c0) from the ZZ client DLL via Ghidra decompilation. MsgMhfAddUdPoint fields: QuestPoints (sum of 11 category accumulators earned per quest) and BonusPoints (kiju prayer song multiplier extra). MsgMhfAddUdTacticsPoint fields: QuestID and TacticsPoints. Adds diva_points table (migration 0009) for per-character per-event point tracking, with UPSERT-based atomic accumulation in the handler.
501 lines
12 KiB
Go
501 lines
12 KiB
Go
package channelserver
|
|
|
|
import (
|
|
"testing"
|
|
|
|
cfg "erupe-ce/config"
|
|
"erupe-ce/network/mhfpacket"
|
|
"time"
|
|
)
|
|
|
|
func TestHandleMsgMhfGetUdInfo(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdInfo{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdInfo(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetKijuInfo(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetKijuInfo{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetKijuInfo(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfSetKiju(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfSetKiju{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfSetKiju(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfAddUdPoint(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfAddUdPoint{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfAddUdPoint(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfAddUdPoint_AccumulatesPoints(t *testing.T) {
|
|
srv := createMockServer()
|
|
repo := &mockDivaRepo{
|
|
events: []DivaEvent{{ID: 42, StartTime: uint32(time.Now().Unix())}},
|
|
}
|
|
srv.divaRepo = repo
|
|
s := createMockSession(1, srv)
|
|
s.charID = 100
|
|
|
|
// First quest: 500 quest points + 50 bonus
|
|
pkt := &mhfpacket.MsgMhfAddUdPoint{AckHandle: 1, QuestPoints: 500, BonusPoints: 50}
|
|
handleMsgMhfAddUdPoint(s, pkt)
|
|
<-s.sendPackets
|
|
|
|
qp, bp, err := repo.GetPoints(100, 42)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if qp != 500 || bp != 50 {
|
|
t.Errorf("After first quest: quest=%d bonus=%d, want 500/50", qp, bp)
|
|
}
|
|
|
|
// Second quest: 300 quest points + 30 bonus
|
|
pkt2 := &mhfpacket.MsgMhfAddUdPoint{AckHandle: 2, QuestPoints: 300, BonusPoints: 30}
|
|
handleMsgMhfAddUdPoint(s, pkt2)
|
|
<-s.sendPackets
|
|
|
|
qp, bp, err = repo.GetPoints(100, 42)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if qp != 800 || bp != 80 {
|
|
t.Errorf("After second quest: quest=%d bonus=%d, want 800/80", qp, bp)
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfAddUdPoint_NoEvent(t *testing.T) {
|
|
srv := createMockServer()
|
|
repo := &mockDivaRepo{} // no events
|
|
srv.divaRepo = repo
|
|
s := createMockSession(1, srv)
|
|
s.charID = 100
|
|
|
|
pkt := &mhfpacket.MsgMhfAddUdPoint{AckHandle: 1, QuestPoints: 500, BonusPoints: 50}
|
|
handleMsgMhfAddUdPoint(s, pkt)
|
|
<-s.sendPackets
|
|
|
|
// Should still ACK successfully even with no event
|
|
if len(repo.points) != 0 {
|
|
t.Error("Should not store points when no event is active")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfAddUdPoint_ZeroPoints(t *testing.T) {
|
|
srv := createMockServer()
|
|
repo := &mockDivaRepo{
|
|
events: []DivaEvent{{ID: 1, StartTime: uint32(time.Now().Unix())}},
|
|
}
|
|
srv.divaRepo = repo
|
|
s := createMockSession(1, srv)
|
|
s.charID = 100
|
|
|
|
pkt := &mhfpacket.MsgMhfAddUdPoint{AckHandle: 1, QuestPoints: 0, BonusPoints: 0}
|
|
handleMsgMhfAddUdPoint(s, pkt)
|
|
<-s.sendPackets
|
|
|
|
// Should not create a row for zero points
|
|
if len(repo.points) != 0 {
|
|
t.Error("Should not store zero points")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdMyPoint(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdMyPoint{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdMyPoint(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdTotalPointInfo(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdTotalPointInfo{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdTotalPointInfo(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSelectedColorInfo(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSelectedColorInfo{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdSelectedColorInfo(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdMonsterPoint(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdMonsterPoint{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdMonsterPoint(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdDailyPresentList(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdDailyPresentList{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdDailyPresentList(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdNormaPresentList(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdNormaPresentList{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdNormaPresentList(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfAcquireUdItem(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfAcquireUdItem{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfAcquireUdItem(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdRanking(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdRanking{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdRanking(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdMyRanking(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdMyRanking{
|
|
AckHandle: 12345,
|
|
}
|
|
|
|
handleMsgMhfGetUdMyRanking(session, pkt)
|
|
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestGenerateDivaTimestamps_Debug(t *testing.T) {
|
|
// Test debug mode timestamps
|
|
tests := []struct {
|
|
name string
|
|
start uint32
|
|
}{
|
|
{"Debug_Start1", 1},
|
|
{"Debug_Start2", 2},
|
|
{"Debug_Start3", 3},
|
|
}
|
|
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
timestamps := generateDivaTimestamps(session, tt.start, true)
|
|
if len(timestamps) != 6 {
|
|
t.Errorf("Expected 6 timestamps, got %d", len(timestamps))
|
|
}
|
|
// Verify timestamps are non-zero
|
|
for i, ts := range timestamps {
|
|
if ts == 0 {
|
|
t.Errorf("Timestamp %d should not be zero", i)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGenerateDivaTimestamps_Debug_StartGreaterThan3(t *testing.T) {
|
|
// Test debug mode with start > 3 (falls through to non-debug path)
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
// With debug=true but start > 3, should fall through to non-debug path
|
|
// This will try to access DB which will panic, so we catch it
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Log("Expected panic due to nil database in test")
|
|
}
|
|
}()
|
|
|
|
timestamps := generateDivaTimestamps(session, 100, true)
|
|
if len(timestamps) != 6 {
|
|
t.Errorf("Expected 6 timestamps, got %d", len(timestamps))
|
|
}
|
|
}
|
|
|
|
func TestGenerateDivaTimestamps_NonDebug_WithValidStart(t *testing.T) {
|
|
// Test non-debug mode with valid start timestamp (not expired)
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
// Use a start time in the future (won't trigger cleanup)
|
|
futureStart := uint32(TimeAdjusted().Unix() + 1000000) // Far in the future
|
|
|
|
timestamps := generateDivaTimestamps(session, futureStart, false)
|
|
if len(timestamps) != 6 {
|
|
t.Errorf("Expected 6 timestamps, got %d", len(timestamps))
|
|
}
|
|
|
|
// Verify first timestamp matches start
|
|
if timestamps[0] != futureStart {
|
|
t.Errorf("First timestamp should match start, got %d want %d", timestamps[0], futureStart)
|
|
}
|
|
|
|
// Verify timestamp intervals
|
|
if timestamps[1] != timestamps[0]+601200 {
|
|
t.Error("Second timestamp should be start + 601200")
|
|
}
|
|
if timestamps[2] != timestamps[1]+3900 {
|
|
t.Error("Third timestamp should be second + 3900")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSchedule_DivaOverrideZero_ZZ(t *testing.T) {
|
|
srv := createMockServer()
|
|
srv.divaRepo = &mockDivaRepo{}
|
|
srv.erupeConfig.DebugOptions.DivaOverride = 0
|
|
srv.erupeConfig.RealClientMode = cfg.ZZ
|
|
s := createMockSession(100, srv)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
|
|
handleMsgMhfGetUdSchedule(s, pkt)
|
|
<-s.sendPackets
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSchedule_DivaOverrideZero_OlderClient(t *testing.T) {
|
|
srv := createMockServer()
|
|
srv.divaRepo = &mockDivaRepo{}
|
|
srv.erupeConfig.DebugOptions.DivaOverride = 0
|
|
srv.erupeConfig.RealClientMode = cfg.G10
|
|
s := createMockSession(100, srv)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
|
|
handleMsgMhfGetUdSchedule(s, pkt)
|
|
<-s.sendPackets
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSchedule_DivaOverride1(t *testing.T) {
|
|
srv := createMockServer()
|
|
srv.divaRepo = &mockDivaRepo{}
|
|
srv.erupeConfig.DebugOptions.DivaOverride = 1
|
|
srv.erupeConfig.RealClientMode = cfg.ZZ
|
|
s := createMockSession(100, srv)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
|
|
handleMsgMhfGetUdSchedule(s, pkt)
|
|
<-s.sendPackets
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSchedule_DivaOverride2(t *testing.T) {
|
|
srv := createMockServer()
|
|
srv.divaRepo = &mockDivaRepo{}
|
|
srv.erupeConfig.DebugOptions.DivaOverride = 2
|
|
s := createMockSession(100, srv)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
|
|
handleMsgMhfGetUdSchedule(s, pkt)
|
|
<-s.sendPackets
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSchedule_DivaOverride3(t *testing.T) {
|
|
srv := createMockServer()
|
|
srv.divaRepo = &mockDivaRepo{}
|
|
srv.erupeConfig.DebugOptions.DivaOverride = 3
|
|
s := createMockSession(100, srv)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
|
|
handleMsgMhfGetUdSchedule(s, pkt)
|
|
<-s.sendPackets
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSchedule_WithExistingEvent(t *testing.T) {
|
|
srv := createMockServer()
|
|
srv.divaRepo = &mockDivaRepo{
|
|
events: []DivaEvent{{ID: 1, StartTime: uint32(time.Now().Unix())}},
|
|
}
|
|
srv.erupeConfig.DebugOptions.DivaOverride = -1
|
|
srv.erupeConfig.RealClientMode = cfg.ZZ
|
|
s := createMockSession(100, srv)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
|
|
handleMsgMhfGetUdSchedule(s, pkt)
|
|
<-s.sendPackets
|
|
}
|
|
|
|
func TestHandleMsgMhfGetUdSchedule_NoEvents(t *testing.T) {
|
|
srv := createMockServer()
|
|
srv.divaRepo = &mockDivaRepo{}
|
|
srv.erupeConfig.DebugOptions.DivaOverride = -1
|
|
s := createMockSession(100, srv)
|
|
|
|
pkt := &mhfpacket.MsgMhfGetUdSchedule{AckHandle: 1}
|
|
handleMsgMhfGetUdSchedule(s, pkt)
|
|
<-s.sendPackets
|
|
}
|