Admin ranks now use bitfields for permissions. Rather than checking the name of the rank, adminverbs will now check holder.rights to see if it has certain bits turned on.

SERVER HOSTS:
This commit replaces the existing admin-rank system. It is now more customizable.
Admin.txt essentially works the same as it always has. Each line should look like:
ckey - admin rank

There is now however, an admin_ranks.txt. This textfile allows you to define ranks like so:
admin rank +ADMIN +FUN +BUILD
the +KEYWORD are flags adding permissions to that rank. There are brief descriptions in the text-file explaining what they do.

You can now name the ranks anything you like, and give them the permissions you want them to have. This allows, for instance, ranks like:
Game Admin on disciplinary +ADMIN +BAN
This would give that game admin only the tools they need to admin. They would not have access to 'fun' verbs which control events and antags.
There's lots of things you can do. For instance, a coder rank whom can debug stuff but cannot do admin tasks:
Codermin +DEBUG +VAREDIT +SERVER

There's lots you can do. As it evolves it will hopefully become more flexible.

admin_ranks.txt defaults to use the old admin rank names.

Apologies in advance as there will be a lot of anomalies, such as ranks losing verbs they once had. Please let me know about any problems. I can fix them quite easily simply by moving verbs between the lists or splitting the lists up into new flags.

CODERS:
There is now a check_rights(flags) proc. 
It check is usr is and admin and has -at least one of- the rights specified.
It checks > usr < not src, so keep that in mind!
If you need to check if something other than usr has specific tights, you can do if(holder.rights & R_ADMIN) etc.

KNOWN ISSUES:
+FUN probably needs to be split up into +MOBS and +EVENTS
In-game promotion/demotion is currently disabled. It will be readded after everything else works ok.
Erro's sql rights changes stuff is currently commented out. It will be re-added.
There are still many many verbs which need updating.

Apologies in advance for any inconvenience.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4991 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
elly1989@rocketmail.com
2012-11-02 10:23:04 +00:00
parent d46775ec87
commit 50fe648a91
33 changed files with 3495 additions and 4243 deletions
+7 -7
View File
@@ -40,9 +40,9 @@
src << "<font color='red'>Error: Admin-PM: You are unable to use admin PM-s (muted).</font>"
return
if( !C || !istype(C,/client) )
if(holder) src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
else adminhelp(msg) //admin we are replying to left. adminhelp instead
if(!istype(C,/client))
if(holder) src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
else adminhelp(msg) //admin we are replying to left. adminhelp instead
return
//get message text, limit it's length.and clean/escape html
@@ -58,8 +58,8 @@
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
//clean the message if it's not sent by a GA or GM
if( !holder || !(holder.rank in list("Game Admin", "Game Master")) )
//clean the message if it's not sent by a high-rank admin
if(!check_rights(R_SERVER|R_DEBUG,0))
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
@@ -106,6 +106,6 @@
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
//we don't use message_admins here because the sender/receiver might get it too
for(var/client/X) //there are fewer clients than mobs
if(X.holder && X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient
for(var/client/X in admins)
if(X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]-&gt;[key_name(C, X, 0)]:</B> \blue [msg]</font>" //inform X
+9 -21
View File
@@ -2,30 +2,18 @@
set category = "Special Verbs"
set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite
set hidden = 1
if (!src.holder)
src << "Only administrators may use this command."
return
if (src.muted & MUTE_ADMINHELP)
src << "You cannot send ASAY messages (muted)."
return
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
if(!check_rights(0)) return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
log_admin("[key_name(src)] : [msg]")
if(!msg) return
if (!msg)
return
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(holder.rank == "Admin Observer")
for(var/client/C in admins)
C << "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, C)]:</EM> <span class='message'>[msg]</span></span>"
else
if(check_rights(R_ADMIN,0))
for(var/client/C in admins)
C << "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, C)]</EM> (<A HREF='?src=\ref[C.holder];adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
else
for(var/client/C in admins)
C << "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, C)]:</EM> <span class='message'>[msg]</span></span>"
log_admin("[key_name(src)] : [msg]")
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+9 -14
View File
@@ -1,22 +1,17 @@
/client/proc/Debug2()
set category = "Debug"
set name = "Debug-Game"
if(!holder)
src << "Only administrators may use this command."
return
if(holder.rank == "Game Admin")
Debug2 = !Debug2
if(!check_rights(R_DEBUG)) return
world << "Debugging [Debug2 ? "On" : "Off"]"
log_admin("[key_name(src)] toggled debugging to [Debug2]")
else if(holder.rank == "Game Master")
Debug2 = !Debug2
world << "Debugging [Debug2 ? "On" : "Off"]"
log_admin("[key_name(src)] toggled debugging to [Debug2]")
if(Debug2)
Debug2 = 0
message_admins("[key_name(src)] toggled debugging off.")
log_admin("[key_name(src)] toggled debugging off.")
else
alert("Coders only baby")
return
Debug2 = 1
message_admins("[key_name(src)] toggled debugging on.")
log_admin("[key_name(src)] toggled debugging on.")
feedback_add_details("admin_verb","DG2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+2 -28
View File
@@ -1,27 +1,4 @@
/client/proc
general_report()
set category = "Debug"
set name = "Show General Report"
if(!master_controller)
usr << alert("Master_controller not found.")
var/mobs = 0
for(var/mob/M in mob_list)
mobs++
var/output = {"<B>GENERAL SYSTEMS REPORT</B><HR>
<B>General Processing Data</B><BR>
<B># of Machines:</B> [machines.len]<BR>
<B># of Pipe Networks:</B> [pipe_networks.len]<BR>
<B># of Processing Items:</B> [processing_objects.len]<BR>
<B># of Power Nets:</B> [powernets.len]<BR>
<B># of Mobs:</B> [mobs]<BR>
"}
usr << browse(output,"window=generalreport")
feedback_add_details("admin_verb","SGR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
air_report()
set category = "Debug"
set name = "Show Air Report"
@@ -156,13 +133,10 @@
set name = "Reload Admins"
set category = "Debug"
if(!(usr.client.holder && usr.client.holder.level >= 6)) // protect and prevent
usr << "\red Not a good cop"
return
if(!check_rights(R_SERVER)) return
message_admins("[usr] manually reloaded admins.txt")
usr << "You reload admins.txt"
world.load_admins()
load_admins()
feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+6 -12
View File
@@ -5,7 +5,7 @@
var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL itms)
if(!admin_rank_check(src.holder.level, 3)) return
if(!check_rights(R_VAREDIT)) return
if(A && A.type)
if(typesof(A.type))
@@ -24,11 +24,9 @@
/client/proc/massmodify_variables(var/atom/O, var/var_name = "", var/method = 0)
var/list/locked = list("vars", "key", "ckey", "client")
if(!check_rights(R_VAREDIT)) return
if(!src.holder)
src << "Only administrators may use this command."
return
var/list/locked = list("vars", "key", "ckey", "client")
for(var/p in forbidden_varedit_object_types)
if( istype(O,p) )
@@ -48,17 +46,13 @@
else
variable = var_name
if(!variable)
return
if(!variable) return
var/default
var/var_value = O.vars[variable]
var/dir
if (locked.Find(variable) && !(src.holder.rank in list("Game Master", "Game Admin")))
return
if (variable == "holder" && holder.rank != "Game Master") //Hotfix, a bit ugly but that exploit has been there for ages and now somebody just had to go and tell everyone of it bluh bluh - U
return
if(variable == "holder" || (variable in locked))
if(!check_rights(R_DEBUG)) return
if(isnull(var_value))
usr << "Unable to determine variable type."
+11 -21
View File
@@ -126,6 +126,8 @@ var/list/forbidden_varedit_object_types = list(
L += var_value
/client/proc/mod_list(var/list/L)
if(!check_rights(R_VAREDIT)) return
if(!istype(L,/list)) src << "Not a List."
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine", "poo", "icon", "icon_state")
@@ -144,8 +146,8 @@ var/list/forbidden_varedit_object_types = list(
var/dir
if (locked.Find(variable) && !(src.holder.rank in list("Game Master", "Game Admin")))
return
if(variable in locked)
if(!check_rights(R_DEBUG)) return
if(isnull(variable))
usr << "Unable to determine variable type."
@@ -264,12 +266,9 @@ var/list/forbidden_varedit_object_types = list(
/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state", "mutantrace")
if(!check_rights(R_VAREDIT)) return
if(!src.holder)
src << "Only administrators may use this command."
return
if(!admin_rank_check(src.holder.level, 3)) return
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state", "mutantrace")
for(var/p in forbidden_varedit_object_types)
if( istype(O,p) )
@@ -285,13 +284,8 @@ var/list/forbidden_varedit_object_types = list(
src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])"
return
if (param_var_name == "holder" && holder.rank != "Game Master")
src << "No. Stop being stupid."
return
if (locked.Find(param_var_name) && !(src.holder.rank in list("Game Master", "Game Admin")))
src << "Editing this variable requires you to be a game master or game admin."
return
if(param_var_name == "holder" || (param_var_name in locked))
if(!check_rights(R_DEBUG)) return
variable = param_var_name
@@ -345,15 +339,11 @@ var/list/forbidden_varedit_object_types = list(
names = sortList(names)
variable = input("Which var?","Var") as null|anything in names
if(!variable)
return
if(!variable) return
var_value = O.vars[variable]
if (locked.Find(variable) && !(src.holder.rank in list("Game Master", "Game Admin")))
return
if (variable == "holder" && holder.rank != "Game Master") //Hotfix, a bit ugly but that exploit has been there for ages and now somebody just had to go and tell everyone of it bluh bluh - U
return
if(variable == "holder" || (variable in locked))
if(!check_rights(R_DEBUG)) return
if(!autodetect_class)
+11 -30
View File
@@ -1,47 +1,28 @@
/client/proc/play_sound(S as sound)
set category = "Fun"
set name = "Play Global Sound"
if(!src.holder)
src << "Only administrators may use this command."
return
if(!check_rights(R_SOUNDS)) return
var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = 777)
uploaded_sound.priority = 250
if(src.holder.rank == "Game Master" || src.holder.rank == "Game Admin" || src.holder.rank == "Badmin")
log_admin("[key_name(src)] played sound [S]")
message_admins("[key_name_admin(src)] played sound [S]", 1)
for(var/mob/M in player_list)
if(M.client.midis)
M << uploaded_sound
else
if(usr.client.canplaysound)
usr.client.canplaysound = 0
log_admin("[key_name(src)] played sound [S]")
message_admins("[key_name_admin(src)] played sound [S]", 1)
for(var/mob/M in player_list)
if(M.client.midis)
M << uploaded_sound
else
usr << "You already used up your jukebox monies this round!"
del(uploaded_sound)
log_admin("[key_name(src)] played sound [S]")
message_admins("[key_name_admin(src)] played sound [S]", 1)
for(var/mob/M in player_list)
if(M.client.midis)
M << uploaded_sound
feedback_add_details("admin_verb","PGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_local_sound(S as sound)
set category = "Fun"
set name = "Play Local Sound"
if(!check_rights(R_SOUNDS)) return
if(!src.holder)
src << "Only administrators may use this command."
return
if(src.holder.rank == "Game Master" || src.holder.rank == "Game Admin")
log_admin("[key_name(src)] played a local sound [S]")
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
playsound(get_turf_loc(src.mob), S, 50, 0, 0)
return
log_admin("[key_name(src)] played a local sound [S]")
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
playsound(get_turf_loc(src.mob), S, 50, 0, 0)
feedback_add_details("admin_verb","PLS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+3 -9
View File
@@ -787,20 +787,14 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
/client/proc/admin_cancel_shuttle()
set category = "Admin"
set name = "Cancel Shuttle"
if(!check_rights(0)) return
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
if ((!( ticker ) || emergency_shuttle.location || emergency_shuttle.direction == 0))
if(!ticker || emergency_shuttle.location || emergency_shuttle.direction == 0)
return
if (!holder)
src << "Only administrators may use this command."
return
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
emergency_shuttle.recall()
feedback_add_details("admin_verb","CCSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] admin-recalled the emergency shuttle.")
+13 -21
View File
@@ -5,28 +5,20 @@
set name = "Set Ticklag"
set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9"
if(src.holder)
if(!src.mob) return
if(!check_rights(R_DEBUG)) return
if(src.holder.rank in list("Game Admin", "Game Master"))
var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null
//I've used ticks of 2 before to help with serious singulo lags
if(newtick && newtick <= 2 && newtick > 0)
log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
message_admins("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
world.tick_lag = newtick
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null
//I've used ticks of 2 before to help with serious singulo lags
if(newtick && newtick <= 2 && newtick > 0)
log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
message_admins("[key_name(src)] has modified world.tick_lag to [newtick]", 0)
world.tick_lag = newtick
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
switch(alert("Enable Tick Compensation?","Tick Comp is currently: [config.Tickcomp]","Yes","No"))
if("Yes")
config.Tickcomp = 1
else
config.Tickcomp = 0
switch(alert("Enable Tick Compensation?","Tick Comp is currently: [config.Tickcomp]","Yes","No"))
if("Yes") config.Tickcomp = 1
else config.Tickcomp = 0
else
src << "\red Error: ticklag(): Invalid world.ticklag value. No changes made."
return
src << "\red Error: ticklag(): Invalid world.ticklag value. No changes made."
return
src << "\red Error: ticklag(): You are not authorised to use this. Game Admins and higher only."
return