OK so as I said in my comment above, after 12 hours failing to get this to work I found an answer within 15 minutes of posting here! Noting this reply so maybe it will help someone else in the future, and I'll also reply on the link as well.
This link gives the answer (https://www.phpbb.com/community/viewtopic.php?f=46&t=2092813#p12800435) but doesn't allow for permissions, so you need to add the code I wrote below in addition. The full code is therefore:
// Step 1: get all topics the user has access to. Assuing all of them are unread until we prove otherwise
$usertopicsallowed = $forumdb->get_results("SELECT DISTINCT t.topic_id, t.forum_id, t.topic_last_post_time FROM $forumdbname.phpbb_users u
INNER JOIN $forumdbname.phpbb_user_group ug ON u.user_id = ug.user_id
INNER JOIN $forumdbname.phpbb_groups g ON g.group_id = ug.group_id
INNER JOIN $forumdbname.phpbb_acl_groups acl ON acl.group_id = ug.group_id
INNER JOIN $forumdbname.phpbb_forums f ON f.forum_id = acl.forum_id
INNER JOIN $forumdbname.phpbb_topics t ON f.forum_id = t.forum_id
WHERE u.user_id = " . $forumuserid . ";");
// Step 2: Calculate unread posts in all forums (regardless of permissions)
$phpbbv2 = $forumdb->get_results("SELECT t.topic_id, t.topic_last_post_time, tt.mark_time as topic_mark_time, ft.mark_time as forum_mark_time FROM (phpbb_topics t)
LEFT JOIN phpbb_topics_track tt ON (tt.user_id = " . $forumuserid . " AND t.topic_id = tt.topic_id)
LEFT JOIN phpbb_forums_track ft ON (ft.user_id = " . $forumuserid . " AND t.forum_id = ft.forum_id)
WHERE ( (tt.mark_time IS NOT NULL AND t.topic_last_post_time > tt.mark_time)
OR (tt.mark_time IS NULL AND ft.mark_time IS NOT NULL AND t.topic_last_post_time > ft.mark_time)
OR (tt.mark_time IS NULL AND ft.mark_time IS NULL AND t.topic_last_post_time > " . $forumuserlastmark . ") ) AND t.topic_moved_id = 0 AND t.topic_approved = 1 ORDER BY t.topic_last_post_time DESC;");
// Step 3: Loop through step 2 and only increment the counter for every topic the user has permission to view
$unreadcounter=0;
if (!empty($phpbbv2))
{
foreach($phpbbv2 as $key => $phpbbv2a)
{
if (!empty($usertopicsallowed))
{
foreach($usertopicsallowed as $key2 => $usertopicallowed)
{
if ($phpbbv2[$key]->topic_id == $usertopicsallowed[$key2]->topic_id)
{
$unreadcounter++;
}
}
}
}
}
$unreadpost=$unreadcounter;
I'm sure it could be better, I'm not the most experienced in php but its working for me.