Skip to content
This repository was archived by the owner on Oct 11, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion libs/gw2_analytics/src/gw2_analytics/ei_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,12 +540,16 @@ def player_agent_ids(agent: Agent) -> set[int]:
for event in event_list
)
account_last_slice: dict[str, object] = {}
account_names: dict[str, set[str]] = defaultdict(set)
for entry in expected_players:
if isinstance(entry, dict) and isinstance(entry.get("account"), str):
first = entry.get("firstAware")
previous = account_last_slice.get(entry["account"])
if isinstance(first, int) and (not isinstance(previous, int) or first > previous):
account_last_slice[entry["account"]] = first
name = entry.get("name")
if isinstance(name, str):
account_names[entry["account"]].add(name)
account_entry_count: Counter[str] = Counter(
entry["account"]
for entry in expected_players
Expand Down Expand Up @@ -622,7 +626,9 @@ def in_slice(event: Event, _lo: int = slice_lo, _hi: int = slice_hi) -> bool:
"group": 51 if anonymous else int(agent.subgroup or 0),
"instanceID": agent.instance_id,
"teamID": _team_for_entry(
player.get("firstAware") == account_last_slice.get(account), agent.team_id
len(account_names[account]) > 1
or player.get("firstAware") == account_last_slice.get(account),
agent.team_id,
),
}
_compare_fields(prefix, player, values, differences)
Expand Down
1 change: 1 addition & 0 deletions libs/gw2_analytics/src/gw2_analytics/rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
}
_MISSILE_CASTS = {26261, 29889, 42163}
_PENDING_EXPECTED_DURATION_SKILLS = {
1066,
1097,
5526,
9086,
Expand Down
97 changes: 97 additions & 0 deletions libs/gw2_analytics/tests/test_ei_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,103 @@ def test_compare_elite_insights_selects_split_account_agent_by_name() -> None:
assert result["differences"] == {}


def test_compare_elite_insights_keeps_team_for_character_swap_slices() -> None:
fight = Fight(
id="fight",
header=EvtcHeader(build_version="20260224", agent_count=2, duration_ms=10_000),
agents=[
Agent(
id=1,
name="First Character",
profession=Profession.NECROMANCER,
elite=EliteSpec.RITUALIST,
is_player=True,
account_name=":Player.1234",
subgroup="1",
instance_id=1111,
team_id=2767,
),
Agent(
id=1,
name="Second Character",
profession=Profession.WARRIOR,
elite=EliteSpec.SPELLBREAKER,
is_player=True,
account_name=":Player.1234",
subgroup="1",
instance_id=1111,
team_id=2767,
),
],
)
expected: dict[str, Any] = {
"players": [
{
"account": "Player.1234",
"instanceID": 1111,
"firstAware": 0,
"name": "First Character",
"profession": "Ritualist",
"teamID": 2767,
},
{
"account": "Player.1234",
"instanceID": 1111,
"firstAware": 1,
"name": "Second Character",
"profession": "Spellbreaker",
"teamID": 2767,
},
]
}

result = compare_elite_insights(fight, expected, [])

assert result["differences"] == {}


def test_compare_elite_insights_keeps_team_on_last_same_character_slice_only() -> None:
fight = Fight(
id="fight",
header=EvtcHeader(build_version="20260424", agent_count=1, duration_ms=10_000),
agents=[
Agent(
id=1,
name="Same Character",
profession=Profession.GUARDIAN,
elite=EliteSpec.FIREBRAND,
is_player=True,
account_name=":Player.1234",
subgroup="5",
instance_id=1111,
team_id=2767,
),
],
)
expected: dict[str, Any] = {
"players": [
{
"account": "Player.1234",
"instanceID": 1111,
"firstAware": 0,
"name": "Same Character",
"teamID": 0,
},
{
"account": "Player.1234",
"instanceID": 1111,
"firstAware": 1,
"name": "Same Character",
"teamID": 2767,
},
]
}

result = compare_elite_insights(fight, expected, [])

assert result["differences"] == {}


def test_compare_elite_insights_does_not_merge_shared_instance_buffs() -> None:
fight = Fight(
id="fight",
Expand Down
20 changes: 20 additions & 0 deletions libs/gw2_analytics/tests/test_rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,26 @@ def test_build_skill_rotation_uses_expected_duration_for_pending_all_in() -> Non
] == [(9265, 200, 2_240)]


def test_build_skill_rotation_uses_expected_duration_for_pending_resurrect() -> None:
origin = 42_000_000
events = [
SkillActivationEvent(
time_ms=origin + 200,
source_agent_id=7,
target_agent_id=0,
skill_id=1066,
activation=ActivationType.NORMAL,
duration_ms=700,
expected_duration_ms=800,
)
]

assert [
(cast.skill_id, cast.time_ms, cast.duration_ms)
for cast in build_skill_rotation(events, duration_ms=3_000, start_time_ms=origin)
] == [(1066, 200, 800)]


def test_build_skill_rotation_clamps_endless_night_to_next_activation() -> None:
origin = 42_000_000
events = [
Expand Down
Loading