{"action":"created","issue":{"url":"https://api.github.com/repos/Pryaxis/TShock/issues/1470","repository_url":"https://api.github.com/repos/Pryaxis/TShock","labels_url":"https://api.github.com/repos/Pryaxis/TShock/issues/1470/labels{/name}","comments_url":"https://api.github.com/repos/Pryaxis/TShock/issues/1470/comments","events_url":"https://api.github.com/repos/Pryaxis/TShock/issues/1470/events","html_url":"https://github.com/Pryaxis/TShock/issues/1470","id":241538641,"number":1470,"title":"Can't negate permissions with PlayerHooks.PlayerPermission","user":{"login":"deadsurgeon42","id":5434547,"avatar_url":"https://avatars2.githubusercontent.com/u/5434547?v=3","gravatar_id":"","url":"https://api.github.com/users/deadsurgeon42","html_url":"https://github.com/deadsurgeon42","followers_url":"https://api.github.com/users/deadsurgeon42/followers","following_url":"https://api.github.com/users/deadsurgeon42/following{/other_user}","gists_url":"https://api.github.com/users/deadsurgeon42/gists{/gist_id}","starred_url":"https://api.github.com/users/deadsurgeon42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deadsurgeon42/subscriptions","organizations_url":"https://api.github.com/users/deadsurgeon42/orgs","repos_url":"https://api.github.com/users/deadsurgeon42/repos","events_url":"https://api.github.com/users/deadsurgeon42/events{/privacy}","received_events_url":"https://api.github.com/users/deadsurgeon42/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2017-07-09T17:12:49Z","updated_at":"2017-07-11T08:03:24Z","closed_at":null,"body":"```cs\r\n    public static void PlayerPermission(PlayerPermissionEventArgs e)\r\n    {\r\n      if (e.Handled) return;\r\n\r\n      // result:\r\n      // true = player does have permission, don't let tshock handle it\r\n      // null = idk, let tshock handle it\r\n      // false = player has the permission negated, let tshock know player doesn't have permission (but how)\r\n      bool? result = UserInfo.HasPermission(e.Player, e.Permission);\r\n\r\n      if (result == null)\r\n        return;\r\n\r\n      e.Handled = true;\r\n      // e.Negated = (bool) result; (maybe?)\r\n    }\r\n```\r\n\r\nRight now `PlayerHooks.PlayerPermission` is limited as there's only two ways of telling TShock what to do:\r\n\r\n`e.Handled = true` 🡲 The player has permission, don't check or prevent the player\r\n`e.Handled = false` 🡲 I don't know if the player has permission or not, check\r\n`???` 🡲 *The player doesn't have permission, don't check but prevent the player*\r\n\r\nThis is good enough for adding permissions, but when you want to negate permissions from the player it falls short.\r\n\r\nA simple solution could be changing `PlayerHooks.OnPlayerPermission` return type to `bool?` and adding a `bool Negated` property into `PlayerPermissionEventArgs` (and their cousins `Player(Item/Proj/Tile)banPermissionEventArgs`) which is checked if `Handled` is `false`:\r\n\r\n```cs\r\nvar args = new PlayerPermissionEventArgs(player, permission);\r\nPlayerPermission(args);\r\nif (!args.Handled)\r\n  return !args.Negated;\r\nelse\r\n  return null;\r\n```\r\n\r\nWhich is then checked in `TSPlayer.HasPermission`:\r\n\r\n```cs\r\npublic bool HasPermission(string permission)\r\n{\r\n  bool? hookResult = PlayerHooks.OnPlayerPermission(this, permission);\r\n  if (hookResult != null)\r\n   return (bool) hookResult;\r\n\r\n   if (tempGroup != null)\r\n     return tempGroup.HasPermission(permission);\r\n   else\r\n     return Group.HasPermission(permission);\r\n}\r\n```\r\n\r\nTho this requires some refactoring (and an api tick?)."},"comment":{"url":"https://api.github.com/repos/Pryaxis/TShock/issues/comments/314366498","html_url":"https://github.com/Pryaxis/TShock/issues/1470#issuecomment-314366498","issue_url":"https://api.github.com/repos/Pryaxis/TShock/issues/1470","id":314366498,"user":{"login":"deadsurgeon42","id":5434547,"avatar_url":"https://avatars2.githubusercontent.com/u/5434547?v=3","gravatar_id":"","url":"https://api.github.com/users/deadsurgeon42","html_url":"https://github.com/deadsurgeon42","followers_url":"https://api.github.com/users/deadsurgeon42/followers","following_url":"https://api.github.com/users/deadsurgeon42/following{/other_user}","gists_url":"https://api.github.com/users/deadsurgeon42/gists{/gist_id}","starred_url":"https://api.github.com/users/deadsurgeon42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deadsurgeon42/subscriptions","organizations_url":"https://api.github.com/users/deadsurgeon42/orgs","repos_url":"https://api.github.com/users/deadsurgeon42/repos","events_url":"https://api.github.com/users/deadsurgeon42/events{/privacy}","received_events_url":"https://api.github.com/users/deadsurgeon42/received_events","type":"User","site_admin":false},"created_at":"2017-07-11T08:03:24Z","updated_at":"2017-07-11T08:03:24Z","body":"https://github.com/Pryaxis/TShock/pull/1476\r\n"}}
{"actor":{"display_login":"deadsurgeon42"}}