I'd asked about this here, so I'll just present my solution.
I have users segregated into public and private users, or "members" and "trons". I want the trons to have access to everything, and the members only the first two forums. This is covered by the engine. However, I also was the non-accessible forums to show up in the index listing, and a special message to show up when they're accessed by a non-tron.
In Index.php, around line 40, there's a big huge query. The entire WHERE condition needs to go, so it becomes this:
$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.forum_desc, f.redirect_url, f.moderators, f.num_topics, f.num_posts, f.last_post, f.last_post_id, f.last_poster FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
In Viewforum.php, also around line 40, there's a condition immediately following the big query, which sends you to the "Bad Request" screen if you don't have permission or the forum doesn't exist. We want to split this so that it differentiates the two types of errors:
if (!$db->num_rows($result))
{
$result = $db->query('SELECT f.forum_name FROM '.$db->prefix.'forums AS f WHERE f.id='.$id);
if (!$db->num_rows($result))
message($lang_common['Bad request']);
else
message($lang_common['No view']);
}
Okay, you're done, unless you want to give the user a special message. In that case, change 'No view' above to 'Nope', and then add your custom line to the /lang/English/common.php file right below 'No view'.
You can see it all in action here: http://dev.tron09.com/forum/ (unless it's broken... this is a live dev site)