Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package org.bukkit.permissions;
2
3import org.bukkit.Bukkit;
4import org.bukkit.plugin.Plugin;
5
6import java.util.*;
7import java.util.logging.Level;
8
9/**
10 * Base Permissible for use in any Permissible object via proxy or extension
11 */
12public class PermissibleBase implements Permissible {
13 private ServerOperator opable = null;
14 private Permissible parent = this;
15 private final List<PermissionAttachment> attachments = new LinkedList<PermissionAttachment>();
16 private final Map<String, PermissionAttachmentInfo> permissions = new HashMap<String, PermissionAttachmentInfo>();
17
18 public PermissibleBase(ServerOperator opable) {
19 this.opable = opable;
20
21 if (opable instanceof Permissible) {
22 this.parent = (Permissible) opable;
23 }
24
25 recalculatePermissions();
26 }
27
28 public boolean isOp() {
29 if (opable == null) {
30 return false;
31 } else {
32 return opable.isOp();
33 }
34 }
35
36 public void setOp(boolean value) {
37 if (opable == null) {
38 throw new UnsupportedOperationException("Cannot change op value as no ServerOperator is set");
39 } else {
40 opable.setOp(value);
41 }
42 }
43
44 public boolean isPermissionSet(String name) {
45 if (name == null) {
46 throw new IllegalArgumentException("Permission name cannot be null");
47 }
48
49 return permissions.containsKey(name.toLowerCase());
50 }
51
52 public boolean isPermissionSet(Permission perm) {
53 if (perm == null) {
54 throw new IllegalArgumentException("Permission cannot be null");
55 }
56
57 return isPermissionSet(perm.getName());
58 }
59
60 public boolean hasPermission(String inName) {
61 if (inName == null) {
62 throw new IllegalArgumentException("Permission name cannot be null");
63 }
64
65 String name = inName.toLowerCase();
66
67 if (isPermissionSet(name)) {
68 return permissions.get(name).getValue();
69 } else {
70 Permission perm = Bukkit.getServer().getPluginManager().getPermission(name);
71
72 if (perm != null) {
73 return perm.getDefault().getValue(isOp());
74 } else {
75 return false;
76 }
77 }
78 }
79
80 public boolean hasPermission(Permission perm) {
81 if (perm == null) {
82 throw new IllegalArgumentException("Permission cannot be null");
83 }
84
85 String name = perm.getName().toLowerCase();
86
87 if (isPermissionSet(name)) {
88 return permissions.get(name).getValue();
89 } else if (perm != null) {
90 return perm.getDefault().getValue(isOp());
91 } else {
92 return false;
93 }
94 }
95
96 public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) {
97 if (name == null) {
98 throw new IllegalArgumentException("Permission name cannot be null");
99 } else if (plugin == null) {
100 throw new IllegalArgumentException("Plugin cannot be null");
101 } else if (!plugin.isEnabled()) {
102 throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
103 }
104
105 PermissionAttachment result = addAttachment(plugin);
106 result.setPermission(name, value);
107
108 recalculatePermissions();
109
110 return result;
111 }
112
113 public PermissionAttachment addAttachment(Plugin plugin) {
114 if (plugin == null) {
115 throw new IllegalArgumentException("Plugin cannot be null");
116 } else if (!plugin.isEnabled()) {
117 throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
118 }
119
120 PermissionAttachment result = new PermissionAttachment(plugin, parent);
121
122 attachments.add(result);
123 recalculatePermissions();
124
125 return result;
126 }
127
128 public void removeAttachment(PermissionAttachment attachment) {
129 if (attachment == null) {
130 throw new IllegalArgumentException("Attachment cannot be null");
131 }
132
133 if (attachments.contains(attachment)) {
134 attachments.remove(attachment);
135 PermissionRemovedExecutor ex = attachment.getRemovalCallback();
136
137 if (ex != null) {
138 ex.attachmentRemoved(attachment);
139 }
140
141 recalculatePermissions();
142 } else {
143 throw new IllegalArgumentException("Given attachment is not part of Permissible object " + parent);
144 }
145 }
146
147 public void recalculatePermissions() {
148 clearPermissions();
149 Set<Permission> defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp());
150 Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), parent);
151
152 for (Permission perm : defaults) {
153 String name = perm.getName().toLowerCase();
154 permissions.put(name, new PermissionAttachmentInfo(parent, name, null, true));
155 Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
156 calculateChildPermissions(perm.getChildren(), false, null);
157 }
158
159 for (PermissionAttachment attachment : attachments) {
160 calculateChildPermissions(attachment.getPermissions(), false, attachment);
161 }
162 }
163
164 private synchronized void clearPermissions() {
165 Set<String> perms = permissions.keySet();
166
167 for (String name : perms) {
168 Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, parent);
169 }
170
171 Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, parent);
172 Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, parent);
173
174 permissions.clear();
175 }
176
177 private void calculateChildPermissions(Map<String, Boolean> children, boolean invert, PermissionAttachment attachment) {
178 Set<String> keys = children.keySet();
179
180 for (String name : keys) {
181 Permission perm = Bukkit.getServer().getPluginManager().getPermission(name);
182 boolean value = children.get(name) ^ invert;
183 String lname = name.toLowerCase();
184
185 permissions.put(lname, new PermissionAttachmentInfo(parent, lname, attachment, value));
186 Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
187
188 if (perm != null) {
189 calculateChildPermissions(perm.getChildren(), !value, attachment);
190 }
191 }
192 }
193
194 public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) {
195 if (name == null) {
196 throw new IllegalArgumentException("Permission name cannot be null");
197 } else if (plugin == null) {
198 throw new IllegalArgumentException("Plugin cannot be null");
199 } else if (!plugin.isEnabled()) {
200 throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
201 }
202
203 PermissionAttachment result = addAttachment(plugin, ticks);
204
205 if (result != null) {
206 result.setPermission(name, value);
207 }
208
209 return result;
210 }
211
212 public PermissionAttachment addAttachment(Plugin plugin, int ticks) {
213 if (plugin == null) {
214 throw new IllegalArgumentException("Plugin cannot be null");
215 } else if (!plugin.isEnabled()) {
216 throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
217 }
218
219 PermissionAttachment result = addAttachment(plugin);
220
221 if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveAttachmentRunnable(result), ticks) == -1) {
222 Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add PermissionAttachment to " + parent + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1");
223 result.remove();
224 return null;
225 } else {
226 return result;
227 }
228 }
229
230 public Set<PermissionAttachmentInfo> getEffectivePermissions() {
231 return new HashSet<PermissionAttachmentInfo>(permissions.values());
232 }
233
234 private class RemoveAttachmentRunnable implements Runnable {
235 private PermissionAttachment attachment;
236
237 public RemoveAttachmentRunnable(PermissionAttachment attachment) {
238 this.attachment = attachment;
239 }
240
241 public void run() {
242 attachment.remove();
243 }
244 }
245}