Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

admin stuff update #6855

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@
#include "code\__HELPERS\_global_objects.dm"
#include "code\__HELPERS\_lists_tg.dm"
#include "code\__HELPERS\_logging.dm"
#include "code\__HELPERS\admin.dm"
#include "code\__HELPERS\animations.dm"
#include "code\__HELPERS\areas.dm"
#include "code\__HELPERS\atom_movables.dm"
Expand Down Expand Up @@ -693,6 +694,7 @@
#include "code\datums\EPv2.dm"
#include "code\datums\ghost_query.dm"
#include "code\datums\hierarchy.dm"
#include "code\datums\http.dm"
#include "code\datums\is_abstract.dm"
#include "code\datums\material_container.dm"
#include "code\datums\mind.dm"
Expand Down Expand Up @@ -2182,7 +2184,6 @@
#include "code\modules\admin\secrets\random_events\trigger_xenomorph_infestation.dm"
#include "code\modules\admin\verbs\admin_set_headshot.dm"
#include "code\modules\admin\verbs\adminhelp.dm"
#include "code\modules\admin\verbs\adminhelp_vr.dm"
#include "code\modules\admin\verbs\adminjump.dm"
#include "code\modules\admin\verbs\adminpm.dm"
#include "code\modules\admin\verbs\adminsay.dm"
Expand Down Expand Up @@ -2223,6 +2224,7 @@
#include "code\modules\admin\verbs\server\admin_reboot.dm"
#include "code\modules\admin\view_variables\admin_delete.dm"
#include "code\modules\admin\view_variables\color_matrix_editor.dm"
#include "code\modules\admin\view_variables\debug_variable_appearance.dm"
#include "code\modules\admin\view_variables\debug_variables.dm"
#include "code\modules\admin\view_variables\filteriffic.dm"
#include "code\modules\admin\view_variables\get_variables.dm"
Expand Down Expand Up @@ -2668,6 +2670,7 @@
#include "code\modules\detectivework\tools\storage.dm"
#include "code\modules\detectivework\tools\swabs.dm"
#include "code\modules\detectivework\tools\uvlight.dm"
#include "code\modules\discord\discord_embed.dm"
#include "code\modules\donatorreskins\donatoraccessory.dm"
#include "code\modules\donatorreskins\donatorarmor.dm"
#include "code\modules\donatorreskins\donatorclothing.dm"
Expand Down
8 changes: 8 additions & 0 deletions code/__DEFINES/_cooldowns.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@

#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_##cd_index - world.time))

// kevin...
// the cd indexes arent supposed to start with cd_
#define COOLDOWN_START_A(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + (cd_time))

//Returns true if the cooldown has run its course, false otherwise
#define COOLDOWN_FINISHED_A(cd_source, cd_index) (cd_source.cd_index <= world.time)


// INDEXES FOR VAR COOLDOWNS - DO NOT USE UPPERCASE, DO NOT USE cooldown_, APPENDS ADDED AUTOMATICALLY

// INDEXES FOR TIMER COOLDOWNS - Must be unique!
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,7 @@
#define VARSET_FROM_LIST_IF(L, V, C...) if(L && L[#V] && (C)) V = L[#V]
#define VARSET_TO_LIST(L, V) if(L) L[#V] = V
#define VARSET_TO_LIST_IF(L, V, C...) if(L && (C)) L[#V] = V

// Generic listoflist safe add and removal macros:
///If value is a list, wrap it in a list so it can be used with list add/remove operations
#define LIST_VALUE_WRAP_LISTS(value) (islist(value) ? list(value) : value)
15 changes: 12 additions & 3 deletions code/__DEFINES/_protect.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* Completely occludes a path from view variable interactions.
*/
///Protects a datum from being VV'd or spawned through admin manipulation
#ifndef TESTING
#define VV_PROTECT(Path)\
##Path/can_vv_get(var_name){\
return FALSE;\
Expand All @@ -11,9 +10,19 @@
##Path/CanProcCall(procname){\
return FALSE;\
}\
##Path/Read(savefile/savefile){\
del(src);\
}\
##Path/Write(savefile/savefile){\
return;\
}\
##Path/can_vv_mark(){\
return FALSE;\
}
#else
#define VV_PROTECT(Path)
#endif
// we del instead of qdel because for security reasons we must ensure the datum does not exist if Read is called. qdel will not enforce this.

/**
* Makes a path read-only to view variables.
Expand Down
35 changes: 20 additions & 15 deletions code/__DEFINES/admin/admin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,31 +84,31 @@
#define ADMIN_FULLMONTY(user) ("[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]")

/atom/proc/Admin_Coordinates_Readable(area_name, admin_jump_ref)
var/turf/T = Safe_COORD_Location()
return T ? "[area_name ? "[get_area_name(T, TRUE)] " : " "]([T.x],[T.y],[T.z])[admin_jump_ref ? " [ADMIN_JMP(T)]" : ""]" : "nonexistent location"
var/turf/turf_at_coords = Safe_COORD_Location()
return turf_at_coords ? "[area_name ? "[get_area_name(turf_at_coords, TRUE)] " : " "]([turf_at_coords.x],[turf_at_coords.y],[turf_at_coords.z])[admin_jump_ref ? " [ADMIN_JMP(turf_at_coords)]" : ""]" : "nonexistent location"

/atom/proc/Safe_COORD_Location()
var/atom/A = drop_location()
if(!A)
return // Not a valid atom.
var/turf/T = get_step(A, 0) // Resolve where the thing is.
if(!T) // Incase it's inside a valid drop container, inside another container. ie if a mech picked up a closet and has it inside it's internal storage.
var/atom/last_try = A.loc?.drop_location() // One last try, otherwise fuck it.
var/atom/drop_atom = drop_location()
if(!drop_atom)
return //not a valid atom.
var/turf/drop_turf = get_step(drop_atom, 0) //resolve where the thing is.
if(!drop_turf) //incase it's inside a valid drop container, inside another container. ie if a mech picked up a closet and has it inside its internal storage.
var/atom/last_try = drop_atom.loc?.drop_location() //one last try, otherwise fuck it.
if(last_try)
T = get_step(last_try, 0)
return T
drop_turf = get_step(last_try, 0)
return drop_turf

/turf/Safe_COORD_Location()
return src

/**
*! AHELP Commands.
*/
#define ADMIN_AHELP_REJECT(user) ("(<a href='?_src_=holder;ahelp=[user];ahelp_action=reject'>[SPAN_TOOLTIP("Reject and close this ticket.","REJT")]</a>)")
#define ADMIN_AHELP_IC(user) ("(<a href='?_src_=holder;ahelp=[user];ahelp_action=icissue'>[SPAN_TOOLTIP("Close this ticket and mark it IC.","IC")]</a>)")
#define ADMIN_AHELP_CLOSE(user) ("(<a href='?_src_=holder;ahelp=[user];ahelp_action=close'>[SPAN_TOOLTIP("Close this ticket.","CLOSE")]</a>)")
#define ADMIN_AHELP_RESOLVE(user) ("(<a href='?_src_=holder;ahelp=[user];ahelp_action=resolve'>[SPAN_TOOLTIP("Close this ticket and mark it as Resolved.","RSLVE")]</a>)")
#define ADMIN_AHELP_HANDLE(user) ("(<a href='?_src_=holder;ahelp=[user];ahelp_action=handleissue'>[SPAN_TOOLTIP("Alert other Administrators that you're handling this ticket.","HANDLE")]</a>)")
#define ADMIN_AHELP_REJECT(user) ("(<a href='?_src_=holder;[HrefToken(forceGlobal = TRUE)];ahelp=[user];ahelp_action=reject'>[SPAN_TOOLTIP("Reject and close this ticket.","REJT")]</a>)")
#define ADMIN_AHELP_IC(user) ("(<a href='?_src_=holder;[HrefToken(forceGlobal = TRUE)];ahelp=[user];ahelp_action=icissue'>[SPAN_TOOLTIP("Close this ticket and mark it IC.","IC")]</a>)")
#define ADMIN_AHELP_CLOSE(user) ("(<a href='?_src_=holder;[HrefToken(forceGlobal = TRUE)];ahelp=[user];ahelp_action=close'>[SPAN_TOOLTIP("Close this ticket.","CLOSE")]</a>)")
#define ADMIN_AHELP_RESOLVE(user) ("(<a href='?_src_=holder;[HrefToken(forceGlobal = TRUE)];ahelp=[user];ahelp_action=resolve'>[SPAN_TOOLTIP("Close this ticket and mark it as Resolved.","RSLVE")]</a>)")
#define ADMIN_AHELP_HANDLE(user) ("(<a href='?_src_=holder;[HrefToken(forceGlobal = TRUE)];ahelp=[user];ahelp_action=handleissue'>[SPAN_TOOLTIP("Alert other Administrators that you're handling this ticket.","HANDLE")]</a>)")
#define ADMIN_AHELP_FULLMONTY(user) ("[ADMIN_AHELP_REJECT(user)] [ADMIN_AHELP_IC(user)] [ADMIN_AHELP_CLOSE(user)] [ADMIN_AHELP_RESOLVE(user)] [ADMIN_AHELP_HANDLE(user)]")

#define AHELP_ACTIVE 1
Expand All @@ -118,3 +118,8 @@
// LOG BROWSE TYPES
#define BROWSE_ROOT_ALL_LOGS 1
#define BROWSE_ROOT_CURRENT_LOGS 2

/// for [/proc/check_asay_links], if there are any actionable refs in the asay message, this index in the return list contains the new message text to be printed
#define ASAY_LINK_NEW_MESSAGE_INDEX "!asay_new_message"
/// for [/proc/check_asay_links], if there are any admin pings in the asay message, this index in the return list contains a list of admins to ping
#define ASAY_LINK_PINGED_ADMINS_INDEX "!pinged_admins"
2 changes: 1 addition & 1 deletion code/__DEFINES/chat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
#define MESSAGE_TYPE_RADIO "radio"
#define MESSAGE_TYPE_INFO "info"
#define MESSAGE_TYPE_WARNING "warning"
#define MESSAGE_TYPE_HELPFUL "helpful"
#define MESSAGE_TYPE_DEADCHAT "deadchat"
#define MESSAGE_TYPE_OOC "ooc"
#define MESSAGE_TYPE_ADMINPM "adminpm"
#define MESSAGE_TYPE_COMBAT "combat"
#define MESSAGE_TYPE_ADMINCHAT "adminchat"
#define MESSAGE_TYPE_PRAYER "prayer"
#define MESSAGE_TYPE_MODCHAT "modchat"
#define MESSAGE_TYPE_EVENTCHAT "eventchat"
#define MESSAGE_TYPE_ADMINLOG "adminlog"
Expand Down
5 changes: 4 additions & 1 deletion code/__DEFINES/is_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@

#define ismutableappearance(D) (istype(D, /mutable_appearance))

#define isweakref(D) (istype(D, /datum/weakref))

#define isimage(D) (istype(D, /image))

#define isweakref(D) (istype(D, /datum/weakref))
GLOBAL_VAR_INIT(magic_appearance_detecting_image, new /image) // appearances are awful to detect safely, but this seems to be the best way ~ninjanomnom
#define isappearance(thing) (!isimage(thing) && !ispath(thing) && istype(GLOB.magic_appearance_detecting_image, thing))

//Datums

Expand Down
9 changes: 6 additions & 3 deletions code/__DEFINES/vv.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#define VV_NUM "Number"
#define VV_TEXT "Text"
#define VV_MESSAGE "Mutiline Text"
#define VV_MESSAGE "Multiline Text"
#define VV_COLOR "Color"
#define VV_COLOR_MATRIX "Color Matrix"
#define VV_ICON "Icon"
#define VV_ATOM_REFERENCE "Atom Reference"
#define VV_DATUM_REFERENCE "Datum Reference"
Expand All @@ -16,11 +18,13 @@
#define VV_NEW_TYPE "New Custom Typepath"
#define VV_NEW_LIST "New List"
#define VV_NULL "NULL"
#define VV_INFINITY "Infinity"
#define VV_RESTORE_DEFAULT "Restore to Default"
#define VV_MARKED_DATUM "Marked Datum"
#define VV_BITFIELD "Bitfield"
#define VV_TEXT_LOCATE "Custom Reference Locate"
#define VV_PROCCALL_RETVAL "Return Value of Proccall"
#define VV_WEAKREF "Weak Reference Datum"

#define VV_MSG_MARKED "<br><font size='1' color='red'><b>Marked Object</b></font>"
#define VV_MSG_EDITED "<br><font size='1' color='red'><b>Var Edited</b></font>"
Expand Down Expand Up @@ -62,8 +66,7 @@
#define VV_HK_TARGET "target"
///name or index of var for 1 variable targetting hrefs.
#define VV_HK_VARNAME "targetvar"
/// to view an appearance virtual object
#define VV_HK_VIEW_APPEARANCE "vv_appearance"
// VV_HK_VIEW_APPEARANCE is handled on vv natively now
// vv_do_list() keys
#define VV_HK_LIST_ADD "listadd"
#define VV_HK_LIST_EDIT "listedit"
Expand Down
12 changes: 5 additions & 7 deletions code/__HELPERS/_logging.dm
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,7 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
rustg_log_close_all()
#endif

/**
* Helper procs for building detailed log lines
*/
/* Helper procs for building detailed log lines */
/proc/key_name(whom, include_link = null, include_name = TRUE, highlight_special_characters = TRUE)
var/mob/M
var/client/C
Expand All @@ -332,7 +330,7 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
C = GLOB.directory[ckey]
if(C)
M = C.mob
else if(istype(whom, /datum/mind))
else if(istype(whom,/datum/mind))
var/datum/mind/mind = whom
ckey = mind.ckey
if(mind.current)
Expand All @@ -347,7 +345,7 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
if(istype(whom, /atom))
var/atom/A = whom
swhom = "[A.name]"
else if(istype(whom, /datum))
else if(isdatum(whom))
swhom = "[whom]"

if(!swhom)
Expand All @@ -363,11 +361,11 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
if(key)
if(C?.is_under_stealthmin() && !include_name)
if(include_link)
. += "<a href='?priv_msg=[REF(C)]'>"
. += "<a href='?priv_msg=[C.get_revealed_key()]'>"
. += "Administrator"
else
if(include_link)
. += "<a href='?priv_msg=[REF(ckey)]'>"
. += "<a href='?priv_msg=[ckey]'>"
. += key
if(!C)
. += "\[DC\]"
Expand Down
9 changes: 9 additions & 0 deletions code/__HELPERS/admin.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

/proc/is_admin(mob/user)
return check_rights(R_ADMIN, 0, user) != 0

/// Sends a message in the event that someone attempts to elevate their permissions through invoking a certain proc.
/proc/alert_to_permissions_elevation_attempt(mob/user)
var/message = " has tried to elevate permissions!"
message_admins(key_name_admin(user) + message)
log_admin(key_name(user) + message)
38 changes: 22 additions & 16 deletions code/__HELPERS/chat.dm
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
/**
/*
*
* Here's how to use the TGS chat system with configs
*
* Here's how to use the chat system with configs
* send2adminchat is a simple function that broadcasts to all admin channels that are designated in TGS
*
*? send2adminchat is a simple function that broadcasts to admin channels
* send2chat is a bit verbose but can be very specific
*
*? send2chat is a bit verbose but can be very specific
* In TGS3 it will always be sent to all connected designated game chats.
*
* In TGS4+ they use the new tagging system
*
* The second parameter is a string, this string should be read from a config.
* What this does is dictacte which TGS4 channels can be sent to.
* What this does is dictate which TGS channels can be sent to.
*
* For example if you have the following channels in tgs4 set up
* - Channel 1, Tag: asdf
Expand All @@ -18,7 +22,7 @@
*
* and you make the call:
*
* send2chat("I sniff butts", CONFIG_GET(string/where_to_send_sniff_butts))
* send2chat(new /datum/tgs_message_content("I sniff butts"), CONFIG_GET(string/where_to_send_sniff_butts))
*
* and the config option is set like:
*
Expand All @@ -31,47 +35,49 @@
* WHERE_TO_SEND_SNIFF_BUTTS
*
* it will be sent to all connected chats.
*
* In TGS3 it will always be sent to all connected designated game chats.
*/
*/

/**
* Sends a message to TGS chat channels.
* Asynchronously sends a message to TGS chat channels.
*
* message - The message to send.
* message - The [/datum/tgs_message_content] to send.
* channel_tag - Required. If "", the message with be sent to all connected (Game-type for TGS3) channels. Otherwise, it will be sent to TGS4 channels with that tag (Delimited by ','s).
* admin_only - Determines if this communication can only be sent to admin only channels.
*/
/proc/send2chat(message, channel_tag)
/proc/send2chat(datum/tgs_message_content/message, channel_tag, admin_only = FALSE)
set waitfor = FALSE
if(channel_tag == null || !world.TgsAvailable())
return

var/datum/tgs_version/version = world.TgsVersion()
if(channel_tag == "" || version.suite == 3)
world.TgsTargetedChatBroadcast(message, FALSE)
world.TgsTargetedChatBroadcast(message, admin_only)
return

var/list/channels_to_use = list()
for(var/I in world.TgsChatChannelInfo())
var/datum/tgs_chat_channel/channel = I
var/list/applicable_tags = splittext(channel.custom_tag, ",")
if(channel_tag in applicable_tags)
if((!admin_only || channel.is_admin_channel) && (channel_tag in applicable_tags))
channels_to_use += channel

if(channels_to_use.len)
world.TgsChatBroadcast(message, channels_to_use)

/**
* Sends a message to TGS admin chat channels.
* Asynchronously sends a message to TGS admin chat channels.
*
* category - The category of the mssage.
* message - The message to send.
*/
/proc/send2adminchat(category, message, embed_links = FALSE)
set waitfor = FALSE

category = replacetext(replacetext(category, "\proper", ""), "\improper", "")
message = replacetext(replacetext(message, "\proper", ""), "\improper", "")
if(!embed_links)
message = GLOB.has_discord_embeddable_links.Replace(replacetext(message, "`", ""), " ```$1``` ")
world.TgsTargetedChatBroadcast("[category] | [message]", TRUE)
world.TgsTargetedChatBroadcast(new /datum/tgs_message_content("[category] | [message]"), TRUE)

/// Handles text formatting for item use hints in examine text
#define EXAMINE_HINT(text) ("<b>" + text + "</b>")
11 changes: 8 additions & 3 deletions code/__HELPERS/game.dm
Original file line number Diff line number Diff line change
Expand Up @@ -512,10 +512,15 @@
/proc/SecondsToTicks(seconds)
return seconds * 10

/proc/window_flash(client_or_usr)
if (!client_or_usr)
/// Flash the window of a player
/proc/window_flash(client/flashed_client)
if(ismob(flashed_client))
var/mob/player_mob = flashed_client
if(player_mob.client)
flashed_client = player_mob.client
if(!flashed_client)
return
winset(client_or_usr, "mainwindow", "flash=5")
winset(flashed_client, "mainwindow", "flash=5")

/**
* Used for the multiz camera console stolen from virgo.
Expand Down
6 changes: 6 additions & 0 deletions code/__HELPERS/text.dm
Original file line number Diff line number Diff line change
Expand Up @@ -622,3 +622,9 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
/proc/sanitize_css_class_name(name)
var/static/regex/regex = new(@"[^a-zA-Z0-9]","g")
return replacetext(name, regex, "")

// return input text if it is a text, else returns default
/proc/sanitize_text(text, default="")
if(istext(text))
return text
return default
3 changes: 3 additions & 0 deletions code/__HELPERS/time.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ GLOBAL_VAR_INIT(startup_year, text2num(time2text(world.time, "YYYY")))
GLOBAL_VAR_INIT(startup_month, text2num(time2text(world.time, "MM")))
GLOBAL_VAR_INIT(startup_day, text2num(time2text(world.time, "DD")))

///displays the current time into the round, with a lot of extra code just there for ensuring it looks okay after an entire day passes
#define ROUND_TIME(...) ( "[world.time - SSticker.round_start_time > MIDNIGHT_ROLLOVER ? "[round((world.time - SSticker.round_start_time)/MIDNIGHT_ROLLOVER)]:[WORLDTIME2TEXT("hh:mm:ss")]" : WORLDTIME2TEXT("hh:mm:ss")]" )

#define TimeOfGame (get_game_time())
#define TimeOfTick (TICK_USAGE*0.01*world.tick_lag)

Expand Down
Loading
Loading