Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

Resolves #34, support for permissions

I'm not looking into other permission plugins yet though. Just implemented something really simple for now.
  • Loading branch information...
commit 21b6ca55ed5a1cde066727c9f4fac9d08a123fc8 1 parent c338851
@CmdrDats authored
@@ -23,6 +23,12 @@ understand what changes are made and adjust your plugins accordingly.
+30 December 2012:
+ - Implement a simple permissions extension for checking and setting specific permissions on players
+ o This does not yet persist given player permissions across sessions
+ - Added clj.permission as a command to give a player a specific permission
+ o Autocompletion may need work as command lists within commands are untested.
29 December 2012:
- Now sends a message to the player triggering an event when the event function returns {:msg "..."}
- Fix up line function
6 src/cljminecraft/commands.clj
@@ -54,6 +54,9 @@
(defmethod convert-type :entity [sender type arg]
(str arg))
+(defmethod convert-type :permission [sender type arg]
+ (str arg))
(defmulti param-type-tabcomplete (fn [_ x _] x))
(defmethod param-type-tabcomplete :player [sender type arg]
@@ -72,6 +75,9 @@
(defmethod param-type-tabcomplete :entity [sender type arg]
(ent/find-entity arg))
+(defmethod param-type-tabcomplete :permission [sender type arg]
+ (plr/find-permission arg))
(defn arity-split [args]
(split-with #(not= '& %) args))
35 src/cljminecraft/core.clj
@@ -1,7 +1,7 @@
(ns cljminecraft.core
(:require [cljminecraft.bukkit :as bk]
[cljminecraft.blocks :as blocks]
- [ :as events]
+ [ :as ev]
[cljminecraft.entity :as ent]
[cljminecraft.player :as plr]
[cljminecraft.util :as util]
@@ -65,13 +65,37 @@
[(apply str (reverse (first args)))])
(defn addevent-command [sender eventname message]
- (events/register-event @clj-plugin eventname (fn [ev] (.sendMessage sender (str message ": " ev))))
+ (ev/register-event @clj-plugin eventname (fn [ev] (.sendMessage sender (str message ": " ev))))
{:msg (format "Adding event %s with message %s" eventname message)})
(defn spawn-command [sender entity]
(ent/spawn-entity (.getLocation sender) entity)
(log/info "Spawning %s in front of %s" entity (.getName sender)))
+;; cljminecraft basic permission system
+(defn permission-command [sender player permission allow-type]
+ (plr/set-permission player permission allow-type))
+(defn player-permission-attach [ev]
+ (plr/permission-attach-player! @clj-plugin ev))
+(defn player-permission-detach [ev]
+ (plr/permission-detach-player! ev))
+(defn setup-permission-system
+ [plugin]
+ (ev/register-eventlist
+ plugin
+ [(ev/event "player.player-join" #'player-permission-attach)
+ (ev/event "player.player-quit" #'player-permission-detach)
+ (ev/event "player.player-kick" #'player-permission-detach)])
+ (plr/permission-attach-all! plugin))
+(defn disable-permission-system
+ [plugin]
+ (plr/permission-detach-all!))
+;; cljminecraft specific setup
(defn start
"onEnable cljminecraft"
@@ -80,19 +104,20 @@
(cmd/register-command @clj-plugin "clj.tabtest" #'tabtest-command :player :material [:keyword [:start :stop]] [:string #'tabcomplete-reverse-first])
(cmd/register-command @clj-plugin "clj.addevent" #'addevent-command :event :string)
(cmd/register-command @clj-plugin "clj.spawnentity" #'spawn-command :entity)
+ (cmd/register-command @clj-plugin "clj.permission" #'permission-command :player :permission [:keyword [:allow :disallow :release]])
+ (setup-permission-system plugin)
(start-repl-if-needed plugin))
(defn stop
"onDisable cljminecraft"
- (stop-repl))
+ (stop-repl)
+ (disable-permission-system))
(defn on-enable
"to enable self or any child plugins"
(cfg/config-defaults plugin)
(let [plugin-name (.getName plugin)
resolved (resolve (symbol (str (.getName plugin) ".core/start")))]
(if (not resolved)
67 src/cljminecraft/player.clj
@@ -10,7 +10,7 @@
(apply bk/broadcast format args))
(defn broadcast-permission
- "Broadcast a message to all players"
+ "Broadcast a message to all players with a given permission"
[permission format & args]
(apply bk/broadcast permission format args))
@@ -43,10 +43,6 @@
(get-player [this] (.getPlayer (bk/server) this)))
-(extend-type org.bukkit.Bukkit
- HasPlayer
- (get-player [this] (.getPlayer this)))
(extend-type org.bukkit.entity.Player
(get-player [this] this))
@@ -58,3 +54,64 @@
(let [stack (items/item-stack material-key qty)
player (get-player player)]
(.addItem (.getInventory (get-player player)) (into-array org.bukkit.inventory.ItemStack [stack]))))
+(defonce permission-attachments (atom {}))
+(defn permission-attach-player!
+ "Attach a player to a plugin for permission handling - clj-minecraft handles this automatically, so you shouldn't need to."
+ [plugin player]
+ (let [plr (get-player player)]
+ (if-not (contains? @permission-attachments (.getName plr))
+ (swap! permission-attachments assoc (.getName plr) (.addAttachment plr plugin)))))
+(defn permission-detach-player!
+ "Detach a player from permission handling - clj-minecraft handles this automatically, so you shouldn't need to."
+ [player]
+ (let [plr (get-player player)
+ attach (get @permission-attachments (.getName plr))]
+ (try
+ (.removeAttachment plr attach)
+ (catch Exception e nil))
+ (swap! permission-attachments dissoc (.getName plr))))
+(defn permission-attach-all!
+ [plugin]
+ (doseq [plr (.getOnlinePlayers (.getServer plugin))]
+ (permission-attach-player! plugin plr)))
+(defn permission-detach-all!
+ []
+ (doseq [plr (keys @permission-attachments)]
+ (permission-detach-player! plr)))
+(defn defined-permissions []
+ (for [plugin (.getPlugins (bk/plugin-manager))
+ permission (.getPermissions (.getDescription plugin))]
+ (.getName permission)))
+(defn command-permissions []
+ (for [plugin (.getPlugins (bk/plugin-manager))
+ i (.values (.getCommands (.getDescription plugin)))]
+ (.get i "permission")))
+(defn find-permission
+ "Finds permissions starting with a given name"
+ [name]
+ (let [permissionlist (concat (defined-permissions) (command-permissions))]
+ (filter #(.startsWith % name) permissionlist)))
+(defn has-permission
+ "Check if a player has a permission - this does an implicit (get-player player), so you can pass in a String, Player, Event (that has .getPlayer), InventoryView, etc. (see get-player protocol)"
+ [player permission]
+ (let [plr (get-player player)]
+ (.hasPermission plr permission)))
+(defn set-permission
+ "This uses the clj-minecraft permission handling to set a permission. This is very simplistic and really for basic permission setting so that you don't need another plugin for the basic permission management - allow-type can be :allow, :disallow or :release - :disallow actively disallows a permission, where :release just unsets it and lets possibly another plugin set it again."
+ [player permission allow-type]
+ (let [plr (get-player player)
+ attach (get @permission-attachments (.getName plr))]
+ (case allow-type
+ :allow (.setPermission attach permission true)
+ :disallow (.setPermission attach permission false)
+ :release (.unsetPermission attach permission))))
6 src/plugin.yml
@@ -24,4 +24,8 @@ commands:
description: Spawn a given entity in front of you
permission: clojure.spawn
- usage: /<command> entityname
+ usage: /<command> entityname
+ clj.permission:
+ description: Set a permission for a given player
+ permission: clojure.permission
+ usage: /<command> player permissionname (allow|disallow|release)
Please sign in to comment.
Something went wrong with that request. Please try again.