diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 1bcd5f5a3f4..5d63e777087 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -37,7 +37,8 @@ #define R_SPAWN 4096 #define R_MOD 8192 #define R_MENTOR 16384 +#define R_PROCCALL 32768 -#define R_MAXPERMISSION 16384 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. +#define R_MAXPERMISSION 32768 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. #define R_HOST 65535 \ No newline at end of file diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 251206bbdbf..7fedc81d617 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -346,6 +346,7 @@ proc/tg_text2list(text, glue=",", assocglue=";") if(rights & R_VAREDIT) . += "[seperator]+VAREDIT" if(rights & R_SOUNDS) . += "[seperator]+SOUND" if(rights & R_SPAWN) . += "[seperator]+SPAWN" + if(rights & R_PROCCALL) . += "[seperator]+PROCCALL" if(rights & R_MOD) . += "[seperator]+MODERATOR" if(rights & R_MENTOR) . += "[seperator]+MENTOR" return . diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index af4f203ebf8..40799c58197 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -439,7 +439,7 @@ client //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). else if(href_list["rename"]) - if(!check_rights(R_VAREDIT)) return + if(!check_rights(R_ADMIN)) return var/mob/M = locate(href_list["rename"]) if(!istype(M)) @@ -498,7 +498,7 @@ client cmd_mass_modify_object_variables(A, href_list["varnamemass"]) else if(href_list["mob_player_panel"]) - if(!check_rights(0)) return + if(!check_rights(R_ADMIN|R_MOD)) return var/mob/M = locate(href_list["mob_player_panel"]) if(!istype(M)) @@ -543,7 +543,7 @@ client href_list["datumrefresh"] = href_list["godmode"] else if(href_list["gib"]) - if(!check_rights(0)) return + if(!check_rights(R_ADMIN|R_EVENT)) return var/mob/M = locate(href_list["gib"]) if(!istype(M)) @@ -575,7 +575,7 @@ client usr.client.cmd_admin_drop_everything(M) else if(href_list["direct_control"]) - if(!check_rights(0)) return + if(!check_rights(R_DEBUG|R_ADMIN)) return var/mob/M = locate(href_list["direct_control"]) if(!istype(M)) @@ -668,7 +668,7 @@ client message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") else if(href_list["addreagent"]) /* Made on /TG/, credit to them. */ - if(!check_rights(0)) return + if(!check_rights(R_DEBUG|R_ADMIN)) return var/atom/A = locate(href_list["addreagent"]) @@ -731,7 +731,7 @@ client href_list["datumrefresh"] = href_list["mark_object"] else if(href_list["proc_call"]) - if(!check_rights(0)) + if(!check_rights(R_PROCCALL)) return var/T = locate(href_list["proc_call"]) @@ -740,7 +740,7 @@ client callproc_datum(T) else if(href_list["rotatedatum"]) - if(!check_rights(0)) return + if(!check_rights(R_DEBUG|R_ADMIN)) return var/atom/A = locate(href_list["rotatedatum"]) if(!istype(A)) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm deleted file mode 100644 index 512e9f02dce..00000000000 --- a/code/datums/helper_datums/getrev.dm +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This datum gets revision info from local svn 'entries' file - * Path to the directory containing it should be in 'config/svndir.txt' file - * - */ - -var/global/datum/getrev/revdata = new("config/svndir.txt") - -//Oh yeah, I'm an OOP fag, lalala -/datum/getrev - var/revision - var/commiter - var/svndirpath - var/revhref - - proc/abort() - spawn() - del src - - New(filename) - ..() - var/list/Lines = file2list(filename) - if(!Lines.len) return abort() - for(var/t in Lines) - if(!t) continue - t = trim(t) - if (length(t) == 0) - continue - else if (copytext(t, 1, 2) == "#") - continue - var/pos = findtext(t, " ") - var/name = null - var/value = null - if (pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - if(!name) - continue - switch(name) - if("svndir") - svndirpath = value - if("revhref") - revhref = value - - if(svndirpath && fexists(svndirpath) && fexists("[svndirpath]/entries") && isfile(file("[svndirpath]/entries"))) - var/list/filelist = file2list("[svndirpath]/entries") - var/s_archive = "" //Stores the previous line so the revision owner can be assigned. - - //This thing doesn't count blank lines, so doing filelist[4] isn't working. - for(var/s in filelist) - if(!commiter) - if(s == "has-props")//The line before this is the committer. - commiter = s_archive - if(!revision) - var/n = text2num(s) - if(isnum(n)) - if(n > 5000 && n < 99999) //Do you think we'll still be up and running at r100000? :) ~Errorage - revision = s - if(revision && commiter) - break - s_archive = s - if(!revision) - abort() - diary << "Revision info loaded succesfully" - return - return abort() - - proc/getRevisionText() - var/output - if(revhref) - output = {"[revision]"} - else - output = revision - return output - - proc/showInfo() - return {" - - - -

Server Revision: [getRevisionText()]
- Author: [commiter]

- - "} - -client/verb/showrevinfo() - set category = "OOC" - set name = "Show Server Revision" - var/output = "Sorry, the revision info is unavailable." - output = file2text("/home/bay12/live/data/gitcommit") - output += "Current Infomational Settings:
" - output += "Protect Authority Roles From Tratior: [config.protect_roles_from_antagonist]
" - usr << browse(output,"window=revdata"); - return diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b7a5fa46935..4ec840223aa 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -800,7 +800,7 @@ var/global/nologevent = 0 set desc = "Edit mobs's memory and role" set name = "Show Traitor Panel" - if(!check_rights(R_ADMIN)) + if(!check_rights(R_ADMIN|R_MOD)) return if(!istype(M)) diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 236fbe42779..ae6ea3c4aae 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -42,6 +42,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights if("spawn","create") rights |= R_SPAWN if("mod") rights |= R_MOD if("mentor") rights |= R_MENTOR + if("proccall") rights |= R_PROCCALL admin_ranks[rank] = rights previous_rights = rights diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 839634b2887..5184f4e7dd2 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -69,7 +69,8 @@ var/list/admin_verbs_admin = list( /client/proc/alt_check, /client/proc/secrets, /client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */ - /client/proc/change_human_appearance_self /* Allows the human-based mob itself change its basic appearance */ + /client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */ + /client/proc/debug_variables ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -139,8 +140,6 @@ var/list/admin_verbs_debug = list( /client/proc/reload_admins, /client/proc/restart_controller, /client/proc/enable_debug_verbs, - /client/proc/callproc, - /client/proc/callproc_datum, /client/proc/toggledebuglogs, /client/proc/qdel_toggle, /client/proc/gc_dump_hdl, @@ -179,12 +178,16 @@ var/list/admin_verbs_mod = list( /client/proc/jobbans, /client/proc/debug_variables /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ ) - var/list/admin_verbs_mentor = list( /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ /client/proc/cmd_admin_pm_by_key_panel /*admin-pm list by key*/ ) +var/list/admin_verbs_proccall = list ( + /client/proc/callproc, + /client/proc/callproc_datum, + /client/proc/SDQL2_query +) /client/proc/add_admin_verbs() if(holder) @@ -203,6 +206,7 @@ var/list/admin_verbs_mentor = list( if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn if(holder.rights & R_MOD) verbs += admin_verbs_mod if(holder.rights & R_MENTOR) verbs += admin_verbs_mentor + if(holder.rights & R_PROCCALL) verbs += admin_verbs_proccall /client/proc/remove_admin_verbs() verbs.Remove( diff --git a/code/modules/admin/machine_upgrade.dm b/code/modules/admin/machine_upgrade.dm index 9f2039fdd0f..a0e97c4ae7b 100644 --- a/code/modules/admin/machine_upgrade.dm +++ b/code/modules/admin/machine_upgrade.dm @@ -1,10 +1,21 @@ /proc/machine_upgrade(obj/machinery/M in world) set name = "Tweak Component Ratings" set category = "Debug" + + if(!check_rights(R_DEBUG)) + return + + if(!istype(M)) + usr << "This can only be used on subtypes of /obj/machinery." + return + var/new_rating = input("Enter new rating:","Num") as num - if(new_rating && M.component_parts) + if(!isnull(new_rating) && M.component_parts) for(var/obj/item/weapon/stock_parts/P in M.component_parts) P.rating = new_rating M.RefreshParts() + + message_admins("[key_name_admin(usr)] has set the component rating of [M] to [new_rating]") + log_admin("[key_name(usr)] has set the component rating of [M] to [new_rating]") feedback_add_details("admin_verb","MU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index e53d4644c33..19ca9ef9b4f 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -2,11 +2,13 @@ set category = "Admin" set name = "Permissions Panel" set desc = "Edit admin permissions" - if(!check_rights(R_PERMISSIONS)) return + if(!check_rights(R_PERMISSIONS)) + return usr.client.holder.edit_admin_permissions() /datum/admins/proc/edit_admin_permissions() - if(!check_rights(R_PERMISSIONS)) return + if(!check_rights(R_PERMISSIONS)) + return var/output = {" @@ -55,8 +57,7 @@ if(!usr.client) return - if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS)) - usr << "\red You do not have permission to do this!" + if(!check_rights(R_PERMISSIONS)) return establish_db_connection() @@ -100,13 +101,13 @@ usr << "\blue Admin rank changed." /datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission) - if(config.admin_legacy_system) return + if(config.admin_legacy_system) + return if(!usr.client) return - if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS)) - usr << "\red You do not have permission to do this!" + if(!check_rights(R_PERMISSIONS)) return establish_db_connection() diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm new file mode 100644 index 00000000000..5fcfa3a12c3 --- /dev/null +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -0,0 +1,477 @@ +// Examples +/* + -- Will call the proc for all computers in the world, thats dir is 2. + CALL ex_act(1) ON /obj/machinery/computer IN world WHERE dir == 2 + -- Will open a window with a list of all the closets in the world, with a link to VV them. + SELECT /obj/structure/closet/secure_closet/security/cargo IN world WHERE icon_off == "secoff" + -- Will change all the tube lights to green + UPDATE /obj/machinery/light IN world SET color = "#0F0" WHERE icon_state == "tube1" + -- Will delete all pickaxes. "IN world" is not required. + DELETE /obj/item/weapon/pickaxe + -- Will flicker the lights once, then turn all mobs green. The semicolon is important to separate the consecutive querys, but is not required for standard one-query use + CALL flicker(1) ON /obj/machinery/light; UPDATE /mob SET color = "#00cc00" + + --You can use operators other than ==, such as >, <=, != and etc.. + +*/ + +/client/proc/SDQL2_query(query_text as message) + set category = "Debug" + + if(!check_rights(R_PROCCALL)) //Shouldn't happen... but just to be safe. + message_admins("ERROR: Non-admin [key_name_admin(usr)] attempted to execute a SDQL query!") + log_admin("Non-admin [key_name(usr)] attempted to execute a SDQL query!") + + if(!query_text || length(query_text) < 1) + return + + //world << query_text + + var/list/query_list = SDQL2_tokenize(query_text) + + if(!query_list || query_list.len < 1) + return + + var/list/querys = SDQL_parse(query_list) + + if(!querys || querys.len < 1) + return + + var/query_log = "executed SDQL query: \"[query_text]\"." + message_admins("[key_name_admin(usr)] [query_log]") + query_log = "[key_name(usr)] [query_log]" + log_admin(query_log) + + for(var/list/query_tree in querys) + var/list/from_objs = list() + var/list/select_types = list() + + switch(query_tree[1]) + if("explain") + SDQL_testout(query_tree["explain"]) + return + + if("call") + if("on" in query_tree) + select_types = query_tree["on"] + else + return + + if("select", "delete", "update") + select_types = query_tree[query_tree[1]] + + from_objs = SDQL_from_objs(query_tree["from"]) + + var/list/objs = list() + + for(var/type in select_types) + var/char = copytext(type, 1, 2) + + if(char == "/" || char == "*") + for(var/from in from_objs) + objs += SDQL_get_all(type, from) + + else if(char == "'" || char == "\"") + objs += locate(copytext(type, 2, length(type))) + + if("where" in query_tree) + var/objs_temp = objs + objs = list() + for(var/datum/d in objs_temp) + if(SDQL_expression(d, query_tree["where"])) + objs += d + + switch(query_tree[1]) + if("call") + var/list/call_list = query_tree["call"] + var/list/args_list = query_tree["args"] + + for(var/datum/d in objs) + for(var/v in call_list) + // To stop any procs which sleep from executing slowly. + if(d) + if(hascall(d, v)) + spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps. + + if("delete") + for(var/datum/d in objs) + del d + + if("select") + var/text = "" + for(var/datum/t in objs) + text += "\ref[t]" + if(istype(t, /atom)) + var/atom/a = t + + if(a.x) + text += ": [t] at ([a.x], [a.y], [a.z])
" + + else if(a.loc && a.loc.x) + text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])
" + + else + text += ": [t]
" + + else + text += ": [t]
" + + usr << browse(text, "window=SDQL-result") + + if("update") + if("set" in query_tree) + var/list/set_list = query_tree["set"] + for(var/datum/d in objs) + var/list/vals = list() + for(var/v in set_list) + if(v in d.vars) + vals += v + vals[v] = SDQL_expression(d, set_list[v]) + + if(istype(d, /turf)) + for(var/v in vals) + if(v == "x" || v == "y" || v == "z") + continue + + d.vars[v] = vals[v] + + else + for(var/v in vals) + d.vars[v] = vals[v] + +/proc/SDQL_parse(list/query_list) + var/datum/SDQL_parser/parser = new() + var/list/querys = list() + var/list/query_tree = list() + var/pos = 1 + var/querys_pos = 1 + var/do_parse = 0 + + for(var/val in query_list) + if(val == ";") + do_parse = 1 + else if(pos >= query_list.len) + query_tree += val + do_parse = 1 + + if(do_parse) + parser.query = query_tree + var/list/parsed_tree + parsed_tree = parser.parse() + if(parsed_tree.len > 0) + querys.len = querys_pos + querys[querys_pos] = parsed_tree + querys_pos++ + else //There was an error so don't run anything, and tell the user which query has errored. + usr << "Parsing error on [querys_pos]\th query. Nothing was executed." + return list() + query_tree = list() + do_parse = 0 + else + query_tree += val + pos++ + + qdel(parser) + + return querys + + + +/proc/SDQL_testout(list/query_tree, indent = 0) + var/spaces = "" + for(var/s = 0, s < indent, s++) + spaces += " " + + for(var/item in query_tree) + if(istype(item, /list)) + usr << "[spaces](" + SDQL_testout(item, indent + 1) + usr << "[spaces])" + + else + usr << "[spaces][item]" + + if(!isnum(item) && query_tree[item]) + + if(istype(query_tree[item], /list)) + usr << "[spaces] (" + SDQL_testout(query_tree[item], indent + 2) + usr << "[spaces] )" + + else + usr << "[spaces] [query_tree[item]]" + +/proc/SDQL_from_objs(list/tree) + if("world" in tree) + return list(world) + + var/list/out = list() + + for(var/type in tree) + var/char = copytext(type, 1, 2) + + if(char == "/") + out += SDQL_get_all(type, world) + + else if(char == "'" || char == "\"") + out += locate(copytext(type, 2, length(type))) + + return out + +/proc/SDQL_get_all(type, location) + var/list/out = list() + + if(type == "*") + for(var/datum/d in location) + out += d + + return out + + type = text2path(type) + + if(ispath(type, /mob)) + for(var/mob/d in location) + if(istype(d, type)) + out += d + + else if(ispath(type, /turf)) + for(var/turf/d in location) + if(istype(d, type)) + out += d + + else if(ispath(type, /obj)) + for(var/obj/d in location) + if(istype(d, type)) + out += d + + else if(ispath(type, /area)) + for(var/area/d in location) + if(istype(d, type)) + out += d + + else if(ispath(type, /atom)) + for(var/atom/d in location) + if(istype(d, type)) + out += d + + else + for(var/datum/d in location) + if(istype(d, type)) + out += d + + return out + +/proc/SDQL_expression(datum/object, list/expression, start = 1) + var/result = 0 + var/val + + for(var/i = start, i <= expression.len, i++) + var/op = "" + + if(i > start) + op = expression[i] + i++ + + var/list/ret = SDQL_value(object, expression, i) + val = ret["val"] + i = ret["i"] + + if(op != "") + switch(op) + if("+") + result += val + if("-") + result -= val + if("*") + result *= val + if("/") + result /= val + if("&") + result &= val + if("|") + result |= val + if("^") + result ^= val + if("=", "==") + result = (result == val) + if("!=", "<>") + result = (result != val) + if("<") + result = (result < val) + if("<=") + result = (result <= val) + if(">") + result = (result > val) + if(">=") + result = (result >= val) + if("and", "&&") + result = (result && val) + if("or", "||") + result = (result || val) + else + usr << "SDQL2: Unknown op [op]" + result = null + else + result = val + + return result + +/proc/SDQL_value(datum/object, list/expression, start = 1) + var/i = start + var/val = null + + if(i > expression.len) + return list("val" = null, "i" = i) + + if(istype(expression[i], /list)) + val = SDQL_expression(object, expression[i]) + + else if(expression[i] == "!") + var/list/ret = SDQL_value(object, expression, i + 1) + val = !ret["val"] + i = ret["i"] + + else if(expression[i] == "~") + var/list/ret = SDQL_value(object, expression, i + 1) + val = ~ret["val"] + i = ret["i"] + + else if(expression[i] == "-") + var/list/ret = SDQL_value(object, expression, i + 1) + val = -ret["val"] + i = ret["i"] + + else if(expression[i] == "null") + val = null + + else if(isnum(expression[i])) + val = expression[i] + + else if(copytext(expression[i], 1, 2) in list("'", "\"")) + val = copytext(expression[i], 2, length(expression[i])) + + else + val = SDQL_var(object, expression, i) + i = expression.len + + return list("val" = val, "i" = i) + +/proc/SDQL_var(datum/object, list/expression, start = 1) + + if(expression[start] in object.vars) + + if(start < expression.len && expression[start + 1] == ".") + return SDQL_var(object.vars[expression[start]], expression[start + 2]) + + else + return object.vars[expression[start]] + + else + return null + +/proc/SDQL2_tokenize(query_text) + + var/list/whitespace = list(" ", "\n", "\t") + var/list/single = list("(", ")", ",", "+", "-", ".", ";") + var/list/multi = list( + "=" = list("", "="), + "<" = list("", "=", ">"), + ">" = list("", "="), + "!" = list("", "=")) + + var/word = "" + var/list/query_list = list() + var/len = length(query_text) + + for(var/i = 1, i <= len, i++) + var/char = copytext(query_text, i, i + 1) + + if(char in whitespace) + if(word != "") + query_list += word + word = "" + + else if(char in single) + if(word != "") + query_list += word + word = "" + + query_list += char + + else if(char in multi) + if(word != "") + query_list += word + word = "" + + var/char2 = copytext(query_text, i + 1, i + 2) + + if(char2 in multi[char]) + query_list += "[char][char2]" + i++ + + else + query_list += char + + else if(char == "'") + if(word != "") + usr << "SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again." + return null + + word = "'" + + for(i++, i <= len, i++) + char = copytext(query_text, i, i + 1) + + if(char == "'") + if(copytext(query_text, i + 1, i + 2) == "'") + word += "'" + i++ + + else + break + + else + word += char + + if(i > len) + usr << "SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"[query_text]\". Please check your syntax, and try again." + return null + + query_list += "[word]'" + word = "" + + else if(char == "\"") + if(word != "") + usr << "SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"[query_text]\" following \"[word]\". Please check your syntax, and try again." + return null + + word = "\"" + + for(i++, i <= len, i++) + char = copytext(query_text, i, i + 1) + + if(char == "\"") + if(copytext(query_text, i + 1, i + 2) == "'") + word += "\"" + i++ + + else + break + + else + word += char + + if(i > len) + usr << "SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"[query_text]\". Please check your syntax, and try again." + return null + + query_list += "[word]\"" + word = "" + + else + word += char + + if(word != "") + query_list += word + return query_list + \ No newline at end of file diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm new file mode 100644 index 00000000000..007453a980d --- /dev/null +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_parser.dm @@ -0,0 +1,530 @@ +//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser. +//Spec +////////// +// +// query : select_query | delete_query | update_query | call_query | explain +// explain : 'EXPLAIN' query +// +// select_query : 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] +// delete_query : 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] +// update_query : 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression] +// call_query : 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]] +// +// select_list : select_item [',' select_list] +// select_item : '*' | select_function | object_type +// select_function : count_function +// count_function : 'COUNT' '(' '*' ')' | 'COUNT' '(' object_types ')' +// +// from_list : from_item [',' from_list] +// from_item : 'world' | object_type +// +// call_function : ['(' [arguments] ')'] +// arguments : expression [',' arguments] +// +// object_type : | string +// +// assignments : assignment, [',' assignments] +// assignment : '=' expression +// variable : | '.' variable +// +// bool_expression : expression comparitor expression [bool_operator bool_expression] +// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression] +// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' ) +// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' +// value : variable | string | number | 'null' +// unary_operator : '!' | '-' | '~' +// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' +// bool_operator : 'AND' | '&&' | 'OR' | '||' +// +// string : ''' ''' | '"' '"' +// number : +// +////////// + +/datum/SDQL_parser + var/query_type + var/error = 0 + + var/list/query + var/list/tree + + var/list/select_functions = list("count") + var/list/boolean_operators = list("and", "or", "&&", "||") + var/list/unary_operators = list("!", "-", "~") + var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^") + var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=") + +/datum/SDQL_parser/New(query_list) + query = query_list + +/datum/SDQL_parser/proc/parse_error(error_message) + error = 1 + usr << "SQDL2 Parsing Error: [error_message]" + return query.len + 1 + +/datum/SDQL_parser/proc/parse() + tree = list() + query(1, tree) + + if(error) + return list() + else + return tree + +/datum/SDQL_parser/proc/token(i) + if(i <= query.len) + return query[i] + + else + return null + +/datum/SDQL_parser/proc/tokens(i, num) + if(i + num <= query.len) + return query.Copy(i, i + num) + + else + return null + +/datum/SDQL_parser/proc/tokenl(i) + return lowertext(token(i)) + +/datum/SDQL_parser/proc + +//query: select_query | delete_query | update_query + query(i, list/node) + query_type = tokenl(i) + + switch(query_type) + if("select") + select_query(i, node) + + if("delete") + delete_query(i, node) + + if("update") + update_query(i, node) + + if("call") + call_query(i, node) + + if("explain") + node += "explain" + node["explain"] = list() + query(i + 1, node["explain"]) + + +// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] + select_query(i, list/node) + var/list/select = list() + i = select_list(i + 1, select) + + node += "select" + node["select"] = select + + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" + + node += "from" + node["from"] = from + + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) + + node += "where" + node["where"] = where + + return i + + +//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression] + delete_query(i, list/node) + var/list/select = list() + i = select_list(i + 1, select) + + node += "delete" + node["delete"] = select + + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" + + node += "from" + node["from"] = from + + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) + + node += "where" + node["where"] = where + + return i + + +//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression] + update_query(i, list/node) + var/list/select = list() + i = select_list(i + 1, select) + + node += "update" + node["update"] = select + + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" + + node += "from" + node["from"] = from + + if(tokenl(i) != "set") + i = parse_error("UPDATE has misplaced SET") + + var/list/set_assignments = list() + i = assignments(i + 1, set_assignments) + + node += "set" + node["set"] = set_assignments + + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) + + node += "where" + node["where"] = where + + return i + + +//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]] + call_query(i, list/node) + var/list/func = list() + var/list/arguments = list() + i = call_function(i + 1, func, arguments) + + node += "call" + node["call"] = func + node["args"] = arguments + + if(tokenl(i) != "on") + return i + + var/list/select = list() + i = select_list(i + 1, select) + + node += "on" + node["on"] = select + + var/list/from = list() + if(tokenl(i) in list("from", "in")) + i = from_list(i + 1, from) + else + from += "world" + + node += "from" + node["from"] = from + + if(tokenl(i) == "where") + var/list/where = list() + i = bool_expression(i + 1, where) + + node += "where" + node["where"] = where + + return i + + +//select_list: select_item [',' select_list] + select_list(i, list/node) + i = select_item(i, node) + + if(token(i) == ",") + i = select_list(i + 1, node) + + return i + + +//from_list: from_item [',' from_list] + from_list(i, list/node) + i = from_item(i, node) + + if(token(i) == ",") + i = from_list(i + 1, node) + + return i + + +//assignments: assignment, [',' assignments] + assignments(i, list/node) + i = assignment(i, node) + + if(token(i) == ",") + i = assignments(i + 1, node) + + return i + + +//select_item: '*' | select_function | object_type + select_item(i, list/node) + + if(token(i) == "*") + node += "*" + i++ + + else if(tokenl(i) in select_functions) + i = select_function(i, node) + + else + i = object_type(i, node) + + return i + + +//from_item: 'world' | object_type + from_item(i, list/node) + + if(token(i) == "world") + node += "world" + i++ + + else + i = object_type(i, node) + + return i + + +//bool_expression: expression [bool_operator bool_expression] + bool_expression(i, list/node) + + var/list/bool = list() + i = expression(i, bool) + + node[++node.len] = bool + + if(tokenl(i) in boolean_operators) + i = bool_operator(i, node) + i = bool_expression(i, node) + + return i + + +//assignment: '=' expression + assignment(i, list/node) + + node += token(i) + + if(token(i + 1) == "=") + var/varname = token(i) + node[varname] = list() + + i = expression(i + 2, node[varname]) + + else + parse_error("Assignment expected, but no = found") + + return i + + +//variable: | '.' variable + variable(i, list/node) + var/list/L = list(token(i)) + node[++node.len] = L + + if(token(i + 1) == ".") + L += "." + i = variable(i + 2, L) + + else + i++ + + return i + + +//object_type: | string + object_type(i, list/node) + + if(copytext(token(i), 1, 2) == "/") + node += token(i) + + else + i = string(i, node) + + return i + 1 + + +//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>=' + comparitor(i, list/node) + + if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">=")) + node += token(i) + + else + parse_error("Unknown comparitor [token(i)]") + + return i + 1 + + +//bool_operator: 'AND' | '&&' | 'OR' | '||' + bool_operator(i, list/node) + + if(tokenl(i) in list("and", "or", "&&", "||")) + node += token(i) + + else + parse_error("Unknown comparitor [token(i)]") + + return i + 1 + + +//string: ''' ''' | '"' '"' + string(i, list/node) + + if(copytext(token(i), 1, 2) in list("'", "\"")) + node += token(i) + + else + parse_error("Expected string but found '[token(i)]'") + + return i + 1 + + +//call_function: ['(' [arguments] ')'] + call_function(i, list/node, list/arguments) + if(length(tokenl(i))) + node += token(i++) + if(token(i) != "(") + parse_error("Expected ( but found '[token(i)]'") + else if(token(i + 1) != ")") + do + i = expression(i + 1, arguments) + if(token(i) == ",") + continue + while(token(i) && token(i) != ")") + else + i++ + else + parse_error("Expected a function but found nothing") + return i + 1 + + +//select_function: count_function + select_function(i, list/node) + + parse_error("Sorry, function calls aren't available yet") + + return i + + +//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression] + expression(i, list/node) + + if(token(i) in unary_operators) + i = unary_expression(i, node) + + else if(token(i) == "(") + var/list/expr = list() + + i = expression(i + 1, expr) + + if(token(i) != ")") + parse_error("Missing ) at end of expression.") + + else + i++ + + node[++node.len] = expr + + else + i = value(i, node) + + if(token(i) in binary_operators) + i = binary_operator(i, node) + i = expression(i, node) + + else if(token(i) in comparitors) + i = binary_operator(i, node) + + var/list/rhs = list() + i = expression(i, rhs) + + node[++node.len] = rhs + + + return i + + +//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' ) + unary_expression(i, list/node) + + if(token(i) in unary_operators) + var/list/unary_exp = list() + + unary_exp += token(i) + i++ + + if(token(i) in unary_operators) + i = unary_expression(i, unary_exp) + + else if(token(i) == "(") + var/list/expr = list() + + i = expression(i + 1, expr) + + if(token(i) != ")") + parse_error("Missing ) at end of expression.") + + else + i++ + + unary_exp[++unary_exp.len] = expr + + else + i = value(i, unary_exp) + + node[++node.len] = unary_exp + + + else + parse_error("Expected unary operator but found '[token(i)]'") + + return i + + +//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^' + binary_operator(i, list/node) + + if(token(i) in (binary_operators + comparitors)) + node += token(i) + + else + parse_error("Unknown binary operator [token(i)]") + + return i + 1 + + +//value: variable | string | number | 'null' + value(i, list/node) + + if(token(i) == "null") + node += "null" + i++ + + else if(isnum(text2num(token(i)))) + node += text2num(token(i)) + i++ + + else if(copytext(token(i), 1, 2) in list("'", "\"")) + i = string(i, node) + + else + i = variable(i, node) + + return i +/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/ diff --git a/code/modules/admin/verbs/check_customitem_activity.dm b/code/modules/admin/verbs/check_customitem_activity.dm deleted file mode 100644 index 18a796a0b08..00000000000 --- a/code/modules/admin/verbs/check_customitem_activity.dm +++ /dev/null @@ -1,85 +0,0 @@ -var/checked_for_inactives = 0 -var/inactive_keys = "None
" - -/client/proc/check_customitem_activity() - set category = "Admin" - set name = "Check activity of players with custom items" - - var/dat = "Inactive players with custom items
" - dat += "
" - dat += "The list below contains players with custom items that have not logged\ - in for the past two months, or have not logged in since this system was implemented.\ - This system requires the feedback SQL database to be properly setup and linked.
" - dat += "
" - dat += "Populating this list is done automatically, but must be manually triggered on a per\ - round basis. Populating the list may cause a lag spike, so use it sparingly.
" - dat += "
" - if(checked_for_inactives) - dat += inactive_keys - dat += "
" - dat += "This system was implemented on March 1 2013, and the database a few days before that. Root server access is required to add or disable access to specific custom items.
" - else - dat += "Populate list (requires an active database connection)
" - - usr << browse(dat, "window=inactive_customitems;size=600x480") - -/proc/populate_inactive_customitems_list(var/client/C) - //set background = 1 - - if(checked_for_inactives) - return - - establish_db_connection() - if(!dbcon.IsConnected()) - return - - //grab all ckeys associated with custom items - var/list/ckeys_with_customitems = list() - - var/file = file2text("config/custom_items.txt") - var/lines = text2list(file, "\n") - - for(var/line in lines) - // split & clean up - var/list/Entry = text2list(line, ":") - for(var/i = 1 to Entry.len) - Entry[i] = trim(Entry[i]) - - if(Entry.len < 1) - continue - - var/cur_key = Entry[1] - if(!ckeys_with_customitems.Find(cur_key)) - ckeys_with_customitems.Add(cur_key) - - //run a query to get all ckeys inactive for over 2 months - var/list/inactive_ckeys = list() - if(ckeys_with_customitems.len) - var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey, lastseen FROM [format_table_name("player")] WHERE datediff(Now(), lastseen) > 60") - query_inactive.Execute() - while(query_inactive.NextRow()) - var/cur_ckey = query_inactive.item[1] - //if the ckey has a custom item attached, output it - if(ckeys_with_customitems.Find(cur_ckey)) - ckeys_with_customitems.Remove(cur_ckey) - inactive_ckeys[cur_ckey] = "last seen on [query_inactive.item[2]]" - - //if there are ckeys left over, check whether they have a database entry at all - if(ckeys_with_customitems.len) - for(var/cur_ckey in ckeys_with_customitems) - var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[cur_ckey]'") - query_inactive.Execute() - if(!query_inactive.RowCount()) - inactive_ckeys += cur_ckey - - if(inactive_ckeys.len) - inactive_keys = "" - for(var/cur_key in inactive_ckeys) - if(inactive_ckeys[cur_key]) - inactive_keys += "[cur_key] - [inactive_ckeys[cur_key]]
" - else - inactive_keys += "[cur_key] - no database entry
" - - checked_for_inactives = 1 - if(C) - C.check_customitem_activity() diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index 453e6d81f69..22d6d4b2a7a 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -20,13 +20,13 @@ var/stafftype = null - if (src.holder.rights & R_MENTOR) + if (check_rights(R_MENTOR, 0)) stafftype = "MENTOR" - if (src.holder.rights & R_MOD) + if (check_rights(R_MOD, 0)) stafftype = "MOD" - if (src.holder.rights & R_ADMIN) + if (check_rights(R_ADMIN, 0)) stafftype = "ADMIN" msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 2dd0e2adb71..542a02ee231 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1,7 +1,9 @@ /client/proc/Debug2() set category = "Debug" set name = "Debug-Game" - if(!check_rights(R_DEBUG)) return + + if(!check_rights(R_DEBUG)) + return if(Debug2) Debug2 = 0 @@ -28,7 +30,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that set category = "Debug" set name = "Advanced ProcCall" - if(!check_rights(R_DEBUG)) return + if(!check_rights(R_PROCCALL)) + return spawn(0) var/target = null @@ -94,7 +97,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that set category = "Debug" set name = "Atom ProcCall" - if(!check_rights(R_DEBUG)) + if(!check_rights(R_PROCCALL)) return var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null @@ -180,6 +183,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/Cell() set category = "Debug" set name = "Air Status in Location" + + if(!check_rights(R_DEBUG)) + return + if(!mob) return var/turf/T = mob.loc @@ -201,6 +208,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_robotize(var/mob/M in mob_list) set category = "Event" set name = "Make Robot" + + if(!check_rights(R_SPAWN)) + return if(!ticker) alert("Wait until the game starts") @@ -216,6 +226,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_animalize(var/mob/M in mob_list) set category = "Event" set name = "Make Simple Animal" + + if(!check_rights(R_SPAWN)) + return if(!ticker) alert("Wait until the game starts") @@ -238,6 +251,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that set category = "Event" set name = "Make pAI" set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI" + + if(!check_rights(R_SPAWN)) + return var/list/available = list() for(var/mob/C in mob_list) @@ -264,6 +280,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_alienize(var/mob/M in mob_list) set category = "Event" set name = "Make Alien" + + if(!check_rights(R_SPAWN)) + return if(!ticker) alert("Wait until the game starts") @@ -281,6 +300,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_slimeize(var/mob/M in mob_list) set category = "Event" set name = "Make slime" + + if(!check_rights(R_SPAWN)) + return if(!ticker) alert("Wait until the game starts") @@ -298,6 +320,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_super(var/mob/M in mob_list) set category = "Event" set name = "Make Superhero" + + if(!check_rights(R_SPAWN)) + return if(!ticker) alert("Wait until the game starts") @@ -312,102 +337,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that else alert("Invalid mob") -/* -/client/proc/cmd_admin_monkeyize(var/mob/M in world) - set category = "Event" - set name = "Make Monkey" - - if(!ticker) - alert("Wait until the game starts") - return - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/target = M - log_admin("[key_name(src)] is attempting to monkeyize [M.key].") - spawn(10) - target.monkeyize() - else - alert("Invalid mob") - -/client/proc/cmd_admin_changelinginize(var/mob/M in world) - set category = "Event" - set name = "Make Changeling" - - if(!ticker) - alert("Wait until the game starts") - return - if(istype(M, /mob/living/carbon/human)) - log_admin("[key_name(src)] has made [M.key] a changeling.") - spawn(10) - M.absorbed_dna[M.real_name] = M.dna.Clone() - M.make_changeling() - if(M.mind) - M.mind.special_role = "Changeling" - else - alert("Invalid mob") -*/ -/* -/client/proc/cmd_admin_abominize(var/mob/M in world) - set category = null - set name = "Make Abomination" - - usr << "Ruby Mode disabled. Command aborted." - return - if(!ticker) - alert("Wait until the game starts.") - return - if(istype(M, /mob/living/carbon/human)) - log_admin("[key_name(src)] has made [M.key] an abomination.") - - // spawn(10) - // M.make_abomination() - -*/ -/* -/client/proc/make_cultist(var/mob/M in world) // -- TLE, modified by Urist - set category = "Event" - set name = "Make Cultist" - set desc = "Makes target a cultist" - if(!cultwords["travel"]) - runerandom() - if(M) - if(M.mind in ticker.mode.cult) - return - else - if(alert("Spawn that person a tome?",,"Yes","No")=="Yes") - M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie. A tome, a message from your new master, appears on the ground." - new /obj/item/weapon/tome(M.loc) - else - M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." - var/glimpse=pick("1","2","3","4","5","6","7","8") - switch(glimpse) - if("1") - M << "\red You remembered one thing from the glimpse... [cultwords["travel"]] is travel..." - if("2") - M << "\red You remembered one thing from the glimpse... [cultwords["blood"]] is blood..." - if("3") - M << "\red You remembered one thing from the glimpse... [cultwords["join"]] is join..." - if("4") - M << "\red You remembered one thing from the glimpse... [cultwords["hell"]] is Hell..." - if("5") - M << "\red You remembered one thing from the glimpse... [cultwords["destroy"]] is destroy..." - if("6") - M << "\red You remembered one thing from the glimpse... [cultwords["technology"]] is technology..." - if("7") - M << "\red You remembered one thing from the glimpse... [cultwords["self"]] is self..." - if("8") - M << "\red You remembered one thing from the glimpse... [cultwords["see"]] is see..." - - if(M.mind) - M.mind.special_role = "Cultist" - ticker.mode.cult += M.mind - src << "Made [M] a cultist." -*/ - //TODO: merge the vievars version into this or something maybe mayhaps /client/proc/cmd_debug_del_all() set category = "Debug" set name = "Del-All" + if(!check_rights(R_DEBUG)) + return + // to prevent REALLY stupid deletions var/blocked = list(/mob/living, /mob/living/carbon, /mob/living/carbon/human, /mob/dead, /mob/dead/observer, /mob/living/silicon, /mob/living/silicon/robot, /mob/living/silicon/ai) var/hsbitem = input(usr, "Choose an object to delete.", "Delete:") as null|anything in subtypesof(/obj) + subtypesof(/mob) - blocked @@ -422,6 +359,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_debug_make_powernets() set category = "Debug" set name = "Make Powernets" + + if(!check_rights(R_DEBUG)) + return + makepowernets() log_admin("[key_name(src)] has remade the powernet. makepowernets() called.") message_admins("[key_name_admin(src)] has remade the powernets. makepowernets() called.", 0) @@ -430,6 +371,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_grantfullaccess(var/mob/M in mob_list) set category = "Admin" set name = "Grant Full Access" + + if(!check_rights(R_EVENT)) + return if (!ticker) alert("Wait until the game starts") @@ -463,7 +407,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that set name = "Assume direct control" set desc = "Direct intervention" - if(!check_rights(R_DEBUG|R_ADMIN)) return + if(!check_rights(R_DEBUG|R_ADMIN)) + return + if(M.ckey) if(alert("This mob is being controlled by [M.ckey]. Are you sure you wish to assume control of it? [M.ckey] will be made a ghost.",,"Yes","No") != "Yes") return @@ -482,6 +428,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_areatest() set category = "Mapping" set name = "Test areas" + + if(!check_rights(R_DEBUG)) + return var/list/areas_all = list() var/list/areas_with_APC = list() @@ -570,9 +519,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_dress(var/mob/living/carbon/human/M in mob_list) set category = "Event" set name = "Select equipment" + + if(!check_rights(R_EVENT)) + return + if(!ishuman(M)) alert("Invalid mob") return + //log_admin("[key_name(src)] has alienized [M.key].") var/list/dresspacks = list( "strip", @@ -1106,11 +1060,13 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that return /client/proc/startSinglo() - set category = "Debug" set name = "Start Singularity" set desc = "Sets up the singularity and all machines to get power flowing through the station" + if(!check_rights(R_DEBUG)) + return + if(alert("Are you sure? This will start up the engine. Should only be used during debug!",,"Yes","No") != "Yes") return @@ -1160,6 +1116,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that set category = "Debug" set name = "Debug Mob Lists" set desc = "For when you just gotta know" + + if(!check_rights(R_DEBUG)) + return switch(input("Which list?") in list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Silicons","Clients","Respawnable Mobs")) if("Players") @@ -1181,6 +1140,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that /client/proc/cmd_admin_toggle_block(var/mob/M,var/block) + if(!check_rights(R_SPAWN)) + return + if(!ticker) alert("Wait until the game starts") return @@ -1194,4 +1156,3 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that log_admin("[key_name(src)] has toggled [M.key]'s [blockname] block [state]!") else alert("Invalid mob") - diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 5acf6c21b44..cc7f9f1befa 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -40,14 +40,15 @@ var/intercom_range_display_status = 0 /client/proc/camera_view() set category = "Mapping" set name = "Camera Range Display" + + if(!check_rights(R_DEBUG)) + return if(camera_range_display_status) camera_range_display_status = 0 else camera_range_display_status = 1 - - for(var/obj/effect/debugging/camera_range/C in world) del(C) @@ -56,15 +57,12 @@ var/intercom_range_display_status = 0 new/obj/effect/debugging/camera_range(C.loc) feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - /client/proc/sec_camera_report() set category = "Mapping" set name = "Camera Report" - - if(!master_controller) - alert(usr,"Master_controller not found.","Sec Camera Report") - return 0 + + if(!check_rights(R_DEBUG)) + return var/list/obj/machinery/camera/CL = list() @@ -101,6 +99,9 @@ var/intercom_range_display_status = 0 /client/proc/intercom_view() set category = "Mapping" set name = "Intercom Range Display" + + if(!check_rights(R_DEBUG)) + return if(intercom_range_display_status) intercom_range_display_status = 0 @@ -119,26 +120,24 @@ var/intercom_range_display_status = 0 feedback_add_details("admin_verb","mIRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! var/list/admin_verbs_show_debug_verbs = list( - /client/proc/camera_view, //-errorage - /client/proc/sec_camera_report, //-errorage - /client/proc/intercom_view, //-errorage + /client/proc/camera_view, + /client/proc/sec_camera_report, + /client/proc/intercom_view, /client/proc/Cell, //More air things /client/proc/atmosscan, //check plumbing /client/proc/powerdebug, //check power /client/proc/count_objects_on_z_level, /client/proc/count_objects_all, - /client/proc/cmd_assume_direct_control, //-errorage + /client/proc/cmd_assume_direct_control, /client/proc/startSinglo, /client/proc/ticklag, /client/proc/cmd_admin_grantfullaccess, -// /client/proc/splash, /client/proc/cmd_admin_areatest, /client/proc/cmd_admin_rejuvenate, /datum/admins/proc/show_traitor_panel, /client/proc/print_jobban_old, /client/proc/print_jobban_old_filter, /client/proc/forceEvent, - ///client/proc/cmd_admin_rejuvenate, /client/proc/nanomapgen_DumpImage ) @@ -146,7 +145,8 @@ var/list/admin_verbs_show_debug_verbs = list( set category = "Debug" set name = "Debug verbs" - if(!check_rights(R_DEBUG)) return + if(!check_rights(R_DEBUG)) + return verbs += admin_verbs_show_debug_verbs @@ -155,6 +155,10 @@ var/list/admin_verbs_show_debug_verbs = list( /client/proc/count_objects_on_z_level() set category = "Mapping" set name = "Count Objects On Level" + + if(!check_rights(R_DEBUG)) + return + var/level = input("Which z-level?","Level?") as text if(!level) return var/num_level = text2num(level) @@ -182,22 +186,16 @@ var/list/admin_verbs_show_debug_verbs = list( if(B.z == num_level) count++ atom_list += A - /* - var/atom/temp_atom - for(var/i = 0; i <= (atom_list.len/10); i++) - var/line = "" - for(var/j = 1; j <= 10; j++) - if(i*10+j <= atom_list.len) - temp_atom = atom_list[i*10+j] - line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; " - world << line*/ - world << "There are [count] objects of type [type_path] on z-level [num_level]" + world << "There are [count] objects of type [type_path] on z-level [num_level]." feedback_add_details("admin_verb","mOBJZ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/count_objects_all() set category = "Mapping" set name = "Count Objects All" + + if(!check_rights(R_DEBUG)) + return var/type_text = input("Which type path?","") as text if(!type_text) return @@ -209,15 +207,6 @@ var/list/admin_verbs_show_debug_verbs = list( for(var/atom/A in world) if(istype(A,type_path)) count++ - /* - var/atom/temp_atom - for(var/i = 0; i <= (atom_list.len/10); i++) - var/line = "" - for(var/j = 1; j <= 10; j++) - if(i*10+j <= atom_list.len) - temp_atom = atom_list[i*10+j] - line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; " - world << line*/ - world << "There are [count] objects of type [type_path] in the game world" + world << "There are [count] objects of type [type_path] in the game world." feedback_add_details("admin_verb","mOBJ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 37110c3c237..a49cd02c06b 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1,8 +1,8 @@ /client/proc/cmd_admin_drop_everything(mob/M as mob in mob_list) set category = null set name = "Drop Everything" - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_DEBUG|R_ADMIN)) return var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No") @@ -19,9 +19,10 @@ /client/proc/cmd_admin_prison(mob/M as mob in mob_list) set category = "Admin" set name = "Prison" - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_ADMIN)) return + if (ismob(M)) if(istype(M, /mob/living/silicon/ai)) alert("The AI can't be sent to prison you jerk!", null, null, null, null, null) @@ -47,9 +48,11 @@ set category = "Event" set name = "Subtle Message" - if(!ismob(M)) return + if(!ismob(M)) + return - if(!check_rights(R_SERVER|R_EVENT)) return + if(!check_rights(R_SERVER|R_EVENT)) + return var/msg = input("Message:", text("Subtle PM to [M.key]")) as text @@ -67,8 +70,9 @@ /client/proc/cmd_mentor_check_new_players() //Allows mentors / admins to determine who the newer players are. set category = "Admin" set name = "Check new Players" - if(!holder) - src << "Only staff members may use this command." + + if(!check_rights(R_MENTOR|R_MOD|R_ADMIN)) + return var/age = alert(src, "Age check", "Show accounts yonger then _____ days","7", "30" , "All") @@ -99,7 +103,8 @@ set category = "Event" set name = "Global Narrate" - if(!check_rights(R_SERVER|R_EVENT)) return + if(!check_rights(R_SERVER|R_EVENT)) + return var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text @@ -114,7 +119,8 @@ set category = "Event" set name = "Direct Narrate" - if(!check_rights(R_SERVER|R_EVENT)) return + if(!check_rights(R_SERVER|R_EVENT)) + return if(!M) M = input("Direct narrate to who?", "Active Players") as null|anything in get_mob_with_client_list() @@ -135,9 +141,10 @@ /client/proc/cmd_admin_godmode(mob/M as mob in mob_list) set category = "Special Verbs" set name = "Godmode" - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_ADMIN)) return + M.status_flags ^= GODMODE usr << "\blue Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]" @@ -148,7 +155,8 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) if(automute) - if(!config.automute_on) return + if(!config.automute_on) + return else if(!usr || !usr.client) return @@ -157,7 +165,8 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) return if(!M.client) usr << "Error: cmd_admin_mute: This mob doesn't have a client tied to it." - if(!M.client) return + if(!M.client) + return var/muteunmute var/mute_string @@ -195,9 +204,10 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) /client/proc/cmd_admin_add_random_ai_law() set category = "Event" set name = "Add Random AI Law" - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_EVENT)) return + var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") if(confirm != "Yes") return log_admin("[key_name(src)] has added a random AI law.") @@ -209,105 +219,14 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) new /datum/event/ion_storm(0, announce_ion_laws) feedback_add_details("admin_verb","ION") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -//I use this proc for respawn character too. /N -/proc/create_xeno(ckey) - if(!ckey) - var/list/candidates = list() - for(var/mob/M in player_list) - if(M.stat != DEAD) continue //we are not dead! - if(!M.client.prefs.be_special & BE_ALIEN) continue //we don't want to be an alium - if(jobban_isbanned(M, "alien") || jobban_isbanned(M, "Syndicate")) continue //we are jobbanned - if(M.client.is_afk()) continue //we are afk - if(M.mind && M.mind.current && M.mind.current.stat != DEAD) continue //we have a live body we are tied to - candidates += M.ckey - if(candidates.len) - ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates - else - usr << "Error: create_xeno(): no suitable candidates." - if(!istext(ckey)) return 0 - - var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva") - var/obj/effect/landmark/spawn_here = xeno_spawn.len ? pick(xeno_spawn) : pick(latejoin) - var/mob/living/carbon/alien/new_xeno - switch(alien_caste) - if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen/large(spawn_here) - if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here) - if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here) - if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here) - if("Larva") new_xeno = new /mob/living/carbon/alien/larva(spawn_here) - else return 0 - - new_xeno.ckey = ckey - message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1) - return 1 - -/* -Allow admins to set players to be able to respawn/bypass 30 min wait, without the admin having to edit variables directly -Ccomp's first proc. -*/ - -/client/proc/get_ghosts(var/notify = 0,var/what = 2) - // what = 1, return ghosts ass list. - // what = 2, return mob list - - var/list/mobs = list() - var/list/ghosts = list() - var/list/sortmob = sortAtom(mob_list) // get the mob list. - /var/any=0 - for(var/mob/dead/observer/M in sortmob) - mobs.Add(M) //filter it where it's only ghosts - any = 1 //if no ghosts show up, any will just be 0 - if(!any) - if(notify) - src << "There doesn't appear to be any ghosts for you to select." - return - - for(var/mob/M in mobs) - var/name = M.name - ghosts[name] = M //get the name of the mob for the popup list - if(what==1) - return ghosts - else - return mobs -/* - -/client/proc/allow_character_respawn() - set category = "Special Verbs" - set name = "Allow player to respawn" - set desc = "Let's the player bypass the 30 minute wait to respawn or allow them to re-enter their corpse." - if(!holder) - src << "Only administrators may use this command." - var/list/ghosts= get_ghosts(1,1) - - var/target = input("Please, select a ghost!", "COME BACK TO LIFE!", null, null) as null|anything in ghosts - if(!target) - src << "Hrm, appears you didn't select a ghost" // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error. - return - - var/mob/dead/observer/G = ghosts[target] - if(G.has_enabled_antagHUD && config.antag_hud_restricted) - var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No") - if(response == "No") return - G.timeofdeath=-19999 /* time of death is checked in /mob/verb/abandon_mob() which is the Respawn verb. - timeofdeath is used for bodies on autopsy but since we're messing with a ghost I'm pretty sure - there won't be an autopsy. - */ - G.has_enabled_antagHUD = 2 - G.can_reenter_corpse = 1 - - G:show_message(text("\blue You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead."), 1) - log_admin("[key_name(usr)] allowed [key_name(G)] to bypass the 30 minute respawn limit") - message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(G)] to bypass the 30 minute respawn limit", 1) - - /client/proc/toggle_antagHUD_use() set category = "Server" set name = "Toggle antagHUD usage" set desc = "Toggles antagHUD usage for observers" - if(!holder) - src << "Only administrators may use this command." + if(!check_rights(R_SERVER)) + return + var/action="" if(config.antag_hud_allowed) for(var/mob/dead/observer/g in get_ghosts()) @@ -333,14 +252,14 @@ Ccomp's first proc. log_admin("[key_name(usr)] has [action] antagHUD usage for observers") message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1) - - /client/proc/toggle_antagHUD_restrictions() set category = "Server" set name = "Toggle antagHUD Restrictions" set desc = "Restricts players that have used antagHUD from being able to join this round." - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_SERVER)) + return + var/action="" if(config.antag_hud_restricted) for(var/mob/dead/observer/g in get_ghosts()) @@ -360,7 +279,6 @@ Ccomp's first proc. log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD") message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1) -*/ /* If a guy was gibbed and you want to revive him, this is a good way to do so. @@ -371,9 +289,10 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Special Verbs" set name = "Respawn Character" set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into." - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_SPAWN)) return + var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", "")) if(!input) return @@ -519,71 +438,70 @@ Traitors and the like can also be revived with the previous role mostly intact. feedback_add_details("admin_verb","RSPCH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return new_character -/client/proc/toggle_antagHUD_use() - set category = "Server" - set name = "Toggle antagHUD usage" - set desc = "Toggles antagHUD usage for observers" +//I use this proc for respawn character too. /N +/proc/create_xeno(ckey) + if(!ckey) + var/list/candidates = list() + for(var/mob/M in player_list) + if(M.stat != DEAD) continue //we are not dead! + if(!M.client.prefs.be_special & BE_ALIEN) continue //we don't want to be an alium + if(jobban_isbanned(M, "alien") || jobban_isbanned(M, "Syndicate")) continue //we are jobbanned + if(M.client.is_afk()) continue //we are afk + if(M.mind && M.mind.current && M.mind.current.stat != DEAD) continue //we have a live body we are tied to + candidates += M.ckey + if(candidates.len) + ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates + else + usr << "Error: create_xeno(): no suitable candidates." + if(!istext(ckey)) return 0 - if(!holder) - src << "Only administrators may use this command." - var/action="" - if(config.antag_hud_allowed) - for(var/mob/dead/observer/g in get_ghosts()) - if(!g.client.holder) //Remove the verb from non-admin ghosts - g.verbs -= /mob/dead/observer/verb/toggle_antagHUD - if(g.antagHUD) - g.antagHUD = 0 // Disable it on those that have it enabled - g.has_enabled_antagHUD = 2 // We'll allow them to respawn - g << "\red The Administrator has disabled AntagHUD " - config.antag_hud_allowed = 0 - src << "\red AntagHUD usage has been disabled" - action = "disabled" + var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva") + var/obj/effect/landmark/spawn_here = xeno_spawn.len ? pick(xeno_spawn) : pick(latejoin) + var/mob/living/carbon/alien/new_xeno + switch(alien_caste) + if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen/large(spawn_here) + if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here) + if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here) + if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here) + if("Larva") new_xeno = new /mob/living/carbon/alien/larva(spawn_here) + else return 0 + + new_xeno.ckey = ckey + message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1) + return 1 + + +/client/proc/get_ghosts(var/notify = 0,var/what = 2) + // what = 1, return ghosts ass list. + // what = 2, return mob list + + var/list/mobs = list() + var/list/ghosts = list() + var/list/sortmob = sortAtom(mob_list) // get the mob list. + /var/any=0 + for(var/mob/dead/observer/M in sortmob) + mobs.Add(M) //filter it where it's only ghosts + any = 1 //if no ghosts show up, any will just be 0 + if(!any) + if(notify) + src << "There doesn't appear to be any ghosts for you to select." + return + + for(var/mob/M in mobs) + var/name = M.name + ghosts[name] = M //get the name of the mob for the popup list + if(what==1) + return ghosts else - for(var/mob/dead/observer/g in get_ghosts()) - if(!g.client.holder) // Add the verb back for all non-admin ghosts - g.verbs += /mob/dead/observer/verb/toggle_antagHUD - g << "\blue The Administrator has enabled AntagHUD " // Notify all observers they can now use AntagHUD - config.antag_hud_allowed = 1 - action = "enabled" - src << "\blue AntagHUD usage has been enabled" - - - log_admin("[key_name(usr)] has [action] antagHUD usage for observers") - message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1) - - -/client/proc/toggle_antagHUD_restrictions() - set category = "Server" - set name = "Toggle antagHUD Restrictions" - set desc = "Restricts players that have used antagHUD from being able to join this round." - if(!holder) - src << "Only administrators may use this command." - var/action="" - if(config.antag_hud_restricted) - for(var/mob/dead/observer/g in get_ghosts()) - g << "\blue The administrator has lifted restrictions on joining the round if you use AntagHUD" - action = "lifted restrictions" - config.antag_hud_restricted = 0 - src << "\blue AntagHUD restrictions have been lifted" - else - for(var/mob/dead/observer/g in get_ghosts()) - g << "\red The administrator has placed restrictions on joining the round if you use AntagHUD" - g << "\red Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions " - g.antagHUD = 0 - g.has_enabled_antagHUD = 0 - action = "placed restrictions" - config.antag_hud_restricted = 1 - src << "\red AntagHUD restrictions have been enabled" - - log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD") - message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1) - + return mobs + /client/proc/cmd_admin_add_freeform_ai_law() set category = "Event" set name = "Add Custom AI law" - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_EVENT)) return + var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null if(!input) return @@ -601,9 +519,10 @@ Traitors and the like can also be revived with the previous role mostly intact. /client/proc/cmd_admin_rejuvenate(mob/living/M as mob in mob_list) set category = "Special Verbs" set name = "Rejuvenate" - if(!holder) - src << "Only administrators may use this command." + + if(!check_rights(R_REJUVINATE)) return + if(!mob) return if(!istype(M)) @@ -619,7 +538,8 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Event" set name = "Create Command Report" - if(!check_rights(R_SERVER|R_EVENT)) return + if(!check_rights(R_SERVER|R_EVENT)) + return var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null var/customname = input(usr, "Pick a title for the report.", "Title") as text|null @@ -651,8 +571,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Admin" set name = "Delete" - if (!holder) - src << "Only administrators may use this command." + if(!check_rights(R_ADMIN)) return if (alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No") == "Yes") @@ -669,9 +588,9 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Admin" set name = "List free slots" - if (!holder) - src << "Only administrators may use this command." + if(!check_rights(R_ADMIN)) return + if(job_master) for(var/datum/job/job in job_master.occupations) src << "[job.title]: [job.total_positions]" @@ -681,7 +600,8 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Event" set name = "Explosion" - if(!check_rights(R_DEBUG|R_EVENT)) return + if(!check_rights(R_DEBUG|R_EVENT)) + return var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null if(devastation == null) return @@ -711,7 +631,8 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Special Verbs" set name = "EM Pulse" - if(!check_rights(R_DEBUG|R_EVENT)) return + if(!check_rights(R_DEBUG|R_EVENT)) + return var/heavy = input("Range of heavy pulse.", text("Input")) as num|null if(heavy == null) return @@ -733,7 +654,8 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Special Verbs" set name = "Gib" - if(!check_rights(R_ADMIN|R_EVENT)) return + if(!check_rights(R_ADMIN|R_EVENT)) + return var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") if(confirm != "Yes") return @@ -754,6 +676,9 @@ Traitors and the like can also be revived with the previous role mostly intact. set name = "Gibself" set category = "Event" + if(!check_rights(R_ADMIN|R_EVENT)) + return + var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") if(confirm == "Yes") if (istype(mob, /mob/dead/observer)) // so they don't spam gibs everywhere @@ -764,115 +689,29 @@ Traitors and the like can also be revived with the previous role mostly intact. log_admin("[key_name(usr)] used gibself.") message_admins("\blue [key_name_admin(usr)] used gibself.", 1) feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/* -/client/proc/cmd_manual_ban() - set name = "Manual Ban" - set category = "Special Verbs" - if(!authenticated || !holder) - src << "Only administrators may use this command." - return - var/mob/M = null - switch(alert("How would you like to ban someone today?", "Manual Ban", "Key List", "Enter Manually", "Cancel")) - if("Key List") - var/list/keys = list() - for(var/mob/M in world) - keys += M.client - var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in keys - if(!selection) - return - M = selection:mob - if ((M.client && M.client.holder && (M.client.holder.level >= holder.level))) - alert("You cannot perform this action. You must be of a higher administrative rank!") - return - - switch(alert("Temporary Ban?",,"Yes","No")) - if("Yes") - var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num - if(!mins) - return - if(mins >= 525600) mins = 525599 - var/reason = input(usr,"Reason?","reason","Griefer") as text - if(!reason) - return - if(M) - AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins) - M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]." - M << "\red This is a temporary ban, it will be removed in [mins] minutes." - M << "\red To try to resolve this matter head to http://ss13.donglabs.com/forum/" - log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.") - message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.") - world.Export("http://216.38.134.132/adminlog.php?type=ban&key=[usr.client.key]&key2=[M.key]&msg=[html_decode(reason)]&time=[mins]&server=[replacetext(config.server_name, "#", "")]") - del(M.client) - del(M) - else - - if("No") - var/reason = input(usr,"Reason?","reason","Griefer") as text - if(!reason) - return - AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0) - M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]." - M << "\red This is a permanent ban." - M << "\red To try to resolve this matter head to http://ss13.donglabs.com/forum/" - log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.") - message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.") - world.Export("http://216.38.134.132/adminlog.php?type=ban&key=[usr.client.key]&key2=[M.key]&msg=[html_decode(reason)]&time=perma&server=[replacetext(config.server_name, "#", "")]") - del(M.client) - del(M) -*/ - -/client/proc/update_world() - // If I see anyone granting powers to specific keys like the code that was here, - // I will both remove their SVN access and permanently ban them from my servers. - return /client/proc/cmd_admin_check_contents(mob/living/M as mob in mob_list) set category = "Special Verbs" set name = "Check Contents" + + if(!check_rights(R_ADMIN)) + return var/list/L = M.get_contents() for(var/t in L) usr << "[t]" feedback_add_details("admin_verb","CC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/* This proc is DEFERRED. Does not do anything. -/client/proc/cmd_admin_remove_plasma() - set category = "Debug" - set name = "Stabilize Atmos." - if(!holder) - src << "Only administrators may use this command." - return - feedback_add_details("admin_verb","STATM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -// DEFERRED - spawn(0) - for(var/turf/T in view()) - T.poison = 0 - T.oldpoison = 0 - T.tmppoison = 0 - T.oxygen = 755985 - T.oldoxy = 755985 - T.tmpoxy = 755985 - T.co2 = 14.8176 - T.oldco2 = 14.8176 - T.tmpco2 = 14.8176 - T.n2 = 2.844e+006 - T.on2 = 2.844e+006 - T.tn2 = 2.844e+006 - T.tsl_gas = 0 - T.osl_gas = 0 - T.sl_gas = 0 - T.temp = 293.15 - T.otemp = 293.15 - T.ttemp = 293.15 -*/ - /client/proc/toggle_view_range() set category = "Special Verbs" set name = "Change View Range" set desc = "switches between 1x and custom views" + + if(!check_rights(R_ADMIN)) + return if(view == world.view) - view = input("Select view range:", "View Range", 9) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128) + view = input("Select view range:", "View Range", world.view) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128) else view = world.view @@ -882,14 +721,14 @@ Traitors and the like can also be revived with the previous role mostly intact. feedback_add_details("admin_verb","CVRA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/admin_call_shuttle() - set category = "Admin" set name = "Call Shuttle" if ((!( ticker ) || !emergency_shuttle.location())) return - if(!check_rights(R_ADMIN)) return + if(!check_rights(R_ADMIN)) + return var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") if(confirm != "Yes") return @@ -924,7 +763,8 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Admin" set name = "Cancel Shuttle" - if(!check_rights(R_ADMIN)) return + if(!check_rights(R_ADMIN)) + return if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return @@ -945,7 +785,8 @@ Traitors and the like can also be revived with the previous role mostly intact. if (!ticker) return - if(!check_rights(R_ADMIN)) return + if(!check_rights(R_ADMIN)) + return emergency_shuttle.deny_shuttle = !emergency_shuttle.deny_shuttle @@ -956,6 +797,9 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Special Verbs" set name = "Attack Log" + if(!check_rights(R_ADMIN)) + return + usr << text("\red Attack Log for []", mob) for(var/t in M.attack_log) usr << t @@ -967,7 +811,8 @@ Traitors and the like can also be revived with the previous role mostly intact. set name = "Make Everyone Random" set desc = "Make everyone have a random appearance. You can only use this before rounds!" - if(!check_rights(R_SERVER|R_EVENT)) return + if(!check_rights(R_SERVER|R_EVENT)) + return if (ticker && ticker.mode) usr << "Nope you can't do this, the game's already started. This only works before rounds!" @@ -995,13 +840,13 @@ Traitors and the like can also be revived with the previous role mostly intact. ticker.random_players = 1 feedback_add_details("admin_verb","MER") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /client/proc/toggle_random_events() set category = "Event" set name = "Toggle random events on/off" set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" - if(!check_rights(R_SERVER|R_EVENT)) return + if(!check_rights(R_SERVER|R_EVENT)) + return if(!config.allow_random_events) config.allow_random_events = 1 @@ -1018,7 +863,8 @@ Traitors and the like can also be revived with the previous role mostly intact. set name = "Toggle ERT" set desc = "Toggle the station's ability to call a response team." - if(!check_rights(R_EVENT)) return + if(!check_rights(R_EVENT)) + return if(ticker.mode.ert_disabled) ticker.mode.ert_disabled = 0 diff --git a/code/modules/reagents/newchem/toxins.dm b/code/modules/reagents/newchem/toxins.dm index 2176171bc11..d5d20843759 100644 --- a/code/modules/reagents/newchem/toxins.dm +++ b/code/modules/reagents/newchem/toxins.dm @@ -15,7 +15,7 @@ datum/reagent/polonium datum/reagent/polonium/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - M.apply_effect(8, IRRADIATE) + M.apply_effect(8, IRRADIATE, negate_armor = 1) ..() return @@ -712,7 +712,7 @@ datum/reagent/glowing_slurry/reaction_mob(var/mob/M, var/method=TOUCH, var/volum datum/reagent/glowing_slurry/on_mob_life(var/mob/living/M as mob) if(!M) M = holder.my_atom - M.apply_effect(2*REM,IRRADIATE,0) + M.apply_effect(2*REM, IRRADIATE, 0, negate_armor = 1) if(prob(15)) randmutb(M) if(prob(5)) diff --git a/code/world.dm b/code/world.dm index 78ba88f840c..14b23b525b5 100644 --- a/code/world.dm +++ b/code/world.dm @@ -334,32 +334,6 @@ var/world_topic_spam_protect_time = world.timeofday config.loadoverflowwhitelist("config/ofwhitelist.txt") // apply some settings from config.. -/hook/startup/proc/loadMods() - world.load_mods() - return 1 - -/world/proc/load_mods() - if(config.admin_legacy_system) - var/text = file2text("config/moderators.txt") - if (!text) - diary << "Failed to load config/mods.txt\n" - else - var/list/lines = text2list(text, "\n") - for(var/line in lines) - if (!line) - continue - - if (copytext(line, 1, 2) == ";") - continue - - var/title = "Moderator" - if(config.mods_are_mentors) title = "Mentor" - var/rights = admin_ranks[title] - - var/ckey = copytext(line, 1, length(line)+1) - var/datum/admins/D = new /datum/admins(title, rights, ckey) - D.associate(directory[ckey]) - /world/proc/update_status() var/s = "" diff --git a/config/example/access levels.txt b/config/example/access levels.txt deleted file mode 100644 index 8068be153fa..00000000000 --- a/config/example/access levels.txt +++ /dev/null @@ -1,79 +0,0 @@ -HOW TO CONVERT A MAP TO THE NEW (june 2008) ACCESS LEVEL SYSTEM -1. Open the .dmp file up in Notepad -2. Find all the "access = blahblah" attributes of doors. -3. Delete them. -4. Open the map up in Dream Maker. If you didn't get them all, it'll tell you so. -5. Assign the existing doors new access permissions using the method below. - -HOW TO MAKE A MAP USING THE NEW (june 2008) ACCESS LEVEL SYSTEM -1. Make a map as normal -2. Select a door that you want to not be accessible to everybody -3. Right click on it and edit its attributes -4. Make the "req_access_txt" attribute be a semicolon-separated list of the permissions required to open the doors -5. Repeat for all doors. - -For example, a brig door would have it be "2" while a door that requires you have toxins and teleporter access (for whatever reason) would have it be "9;20" - -Here is a list of the permissions and their numbers (this may be out of date, see code/game/access.dm for an updated version): - -access_security = 1 -access_brig = 2 -access_armory = 3 -access_forensics_lockers= 4 -access_medical = 5 -access_morgue = 6 -access_tox = 7 -access_tox_storage = 8 -access_genetics = 9 -access_engine = 10 -access_engine_equip= 11 -access_maint_tunnels = 12 -access_external_airlocks = 13 -access_emergency_storage = 14 -access_change_ids = 15 -access_ai_upload = 16 -access_teleporter = 17 -access_eva = 18 -access_heads = 19 -access_captain = 20 -access_all_personal_lockers = 21 -access_chapel_office = 22 -access_tech_storage = 23 -access_atmospherics = 24 -access_bar = 25 -access_janitor = 26 -access_crematorium = 27 -access_kitchen = 28 -access_robotics = 29 -access_rd = 30 -access_cargo = 31 -access_construction = 32 -access_chemistry = 33 -access_cargo_bot = 34 -access_hydroponics = 35 -access_manufacturing = 36 -access_library = 37 -access_lawyer = 38 -access_virology = 39 -access_cmo = 40 -access_qm = 41 -access_court = 42 -access_clown = 43 -access_mime = 44 -access_surgery = 45 -access_theatre = 46 -access_research = 47 -access_mining = 48 -access_mining_office = 49 //not in use -access_mailsorting = 50 -access_mint = 51 -access_mint_vault = 52 -access_heads_vault = 53 -access_mining_station = 54 -access_xenobiology = 55 -access_ce = 56 -access_hop = 57 -access_hos = 58 -access_RC_announce = 59 //Request console announcements -access_keycard_auth = 60 //Used for events which require at least two people to confirm them -access_tcomsat = 61 // has access to the entire telecomms satellite / machinery \ No newline at end of file diff --git a/config/example/admin_ranks.txt b/config/example/admin_ranks.txt index e02a56df044..db2118ee8b7 100644 --- a/config/example/admin_ranks.txt +++ b/config/example/admin_ranks.txt @@ -5,31 +5,30 @@ # Each rank is then followed by keywords with the prefix "+". # # These keywords represent groups of verbs and abilities which are given to that rank. # # +@ (or +prev) is a special shorthand which adds all the rights of the rank above it. # -# Ranks with no keywords will just be given the most basic verbs and abilities ~Carn # +# Ranks with no keywords will just be given the most basic verbs and abilities # ######################################################################################## -# PLEASE NOTE: depending on config options, some abilities will be unavailable regardless if you have permission to use them! -# ALSO NOTE: this is a WorkInProgress at the moment. Most of this is just arbitrarily thrown in whatever group because LoadsaWork2Do+LittleTime. -# I'll be doing more moving around as feedback comes in. So be sure to check the notes after updates. - # KEYWORDS: -# +ADMIN = general admin tools, verbs etc -# +FUN = events, other event-orientated actions. Access to the fun secrets in the secrets panel. -# +BAN = the ability to ban, jobban and fullban -# +STEALTH = the ability to stealthmin (make yourself appear with a fake name to everyone but other admins -# +POSSESS = the ability to possess objects -# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode -# +BUILD (or +BUILDMODE) = the ability to use buildmode -# +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration. -# +DEBUG = debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server. -# +VAREDIT = everyone may view viewvars/debugvars/whatever you call it. This keyword allows you to actually EDIT those variables. -# +RIGHTS (or +PERMISSIONS) = allows you to promote and/or demote people. -# +SOUND (or +SOUNDS) = allows you to upload and play sounds -# +SPAWN (or +CREATE) = mob transformations, spawning of most atoms including mobs (high-risk atoms, e.g. blackholes, will require the +FUN flag too) -# +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag +# +ADMIN = General admin tools and verbs. +# +FUN = Events and other event-orientated actions. +# +BAN = The ability to ban and jobban. +# +STEALTH = The ability to stealthmin (make yourself appear with a fake name to everyone but other admins). +# +POSSESS = The ability to possess objects. +# +REJUV (or +REJUVINATE) = The ability to heal, respawn, modify damage and use godmode. +# +BUILD (or +BUILDMODE) = The ability to use buildmode. +# +SERVER = Higher-risk admin verbs and abilities, such as those which affect the server configuration. +# +DEBUG = Debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server. +# +VAREDIT = Allows you to actually modify variables in the view variables window. +# +RIGHTS (or +PERMISSIONS) = Allows you to promote and demote people. +# +SOUND (or +SOUNDS) = Allows you to upload and play sounds. +# +SPAWN (or +CREATE) = Mob transformations, spawning of most atoms including mobs (high-risk atoms will require the +FUN flag too). +# +PROCCALL = The ability to call any proc on any entity. +# +MOD = Low level admin abilities. +# +MENTOR = The ability to answer questions. +# +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag. Admin Observer +Mentor +MENTOR Moderator +MOD -Mentor +MENTOR Admin Candidate +ADMIN Trial Admin +@ +SPAWN +REJUV +VAREDIT +BAN @@ -41,5 +40,4 @@ Retired Admin +ADMIN +STEALTH Host +EVERYTHING -Developer +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE -Dev Mod +@ +MOD +Developer +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE \ No newline at end of file diff --git a/config/example/admins.txt b/config/example/admins.txt index 3b830cd27ff..0e89ae17e23 100644 --- a/config/example/admins.txt +++ b/config/example/admins.txt @@ -2,7 +2,7 @@ # Basically, ckey goes first. Rank goes after the "-" # # Case is not important for ckey. # # Case IS important for the rank. However punctuation/spaces are not # -# Ranks can be anything defined in admin_ranks.txt ~Carn # +# Ranks can be anything defined in admin_ranks.txt # ###################################################################### -# not_a_user - Admin +# example - Admin diff --git a/config/example/custom_items.txt b/config/example/custom_items.txt deleted file mode 100644 index f4bb1a7028b..00000000000 --- a/config/example/custom_items.txt +++ /dev/null @@ -1 +0,0 @@ -ckey: name: /path/to/obj diff --git a/config/example/moderators.txt b/config/example/moderators.txt deleted file mode 100644 index b14d8e49f43..00000000000 --- a/config/example/moderators.txt +++ /dev/null @@ -1,3 +0,0 @@ -; just add the ckey (lowercase) of every moderator on a separate line -; lines starting with ; are comments and will be ignored - diff --git a/config/example/svndir.txt b/config/example/svndir.txt deleted file mode 100644 index 5c907c92f1f..00000000000 --- a/config/example/svndir.txt +++ /dev/null @@ -1,5 +0,0 @@ -#Path to the .svn directory. Used to get server revision info. -SVNDIR .svn - -#Link to revision details. -REVHREF http://code.google.com/p/tgstation13/source/detail?r= \ No newline at end of file diff --git a/paradise.dme b/paradise.dme index 5fcbab6ee36..76969b151fa 100644 --- a/paradise.dme +++ b/paradise.dme @@ -944,6 +944,8 @@ #include "code\modules\admin\verbs\ticklag.dm" #include "code\modules\admin\verbs\tripAI.dm" #include "code\modules\admin\verbs\vox_raiders.dm" +#include "code\modules\admin\verbs\SDQL2\SDQL_2.dm" +#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm" #include "code\modules\alarm\alarm.dm" #include "code\modules\alarm\alarm_handler.dm" #include "code\modules\alarm\atmosphere_alarm.dm"