mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-16 10:35:41 +01:00
Special radio channels now use bitflags instead of individual vars (#85150)
## About The Pull Request Radios/encryption keys now use a `RADIO_SPECIAL_XXXXX` bitflag for behaviors related to "special" radio channels (Binary, Centcom, Syndie). I decided to do this because I wanted to add a radio channel for pirates and hunters (hence the branch name), but it felt weird adding two more variables. The more I look at the changes I've made here the more I realize that the effort was probably not worth the utility but whatever. This also subtypes some varedited intercoms and makes them their own objects. ## Why It's Good For The Game Compresses a whopping three (3!) variables into a single one. Easier to scale (I guess?). I felt like adding a fourth/fifth variable and just moving on with the original project, but decided "lets do this the unnecessarily hard way instead". ## Changelog 🆑 Rhials code: Radios/encryption keys now use a single variable for "special" frequencies. Please report if you experience any strangeness with accessing/being unable to access the Centcom, Syndicate, or Cyborg radio. /🆑 --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -451,12 +451,8 @@
|
||||
/area/ruin/comms_agent)
|
||||
"xq" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/item/radio/intercom{
|
||||
pixel_x = 31;
|
||||
syndie = 1;
|
||||
freerange = 1;
|
||||
name = "syndicate radio intercom";
|
||||
desc = "A custom-made Syndicate-issue intercom used to transmit on all Nanotrasen frequencies. Particularly expensive."
|
||||
/obj/item/radio/intercom/syndicate/freerange{
|
||||
pixel_x = 31
|
||||
},
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/machinery/fax{
|
||||
|
||||
@@ -2446,10 +2446,7 @@
|
||||
"lb" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/machinery/door/window/left/directional/south,
|
||||
/obj/item/radio/intercom{
|
||||
desc = "Talk smack through this.";
|
||||
syndie = 1
|
||||
},
|
||||
/obj/item/radio/intercom/syndicate,
|
||||
/turf/open/floor/iron/grimy,
|
||||
/area/centcom/central_command_areas/courtroom)
|
||||
"lc" = (
|
||||
@@ -2462,10 +2459,7 @@
|
||||
/area/centcom/central_command_areas/courtroom)
|
||||
"ld" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/radio/intercom{
|
||||
desc = "Talk smack through this.";
|
||||
syndie = 1
|
||||
},
|
||||
/obj/item/radio/intercom/syndicate,
|
||||
/obj/machinery/door/window/brigdoor/right/directional/south{
|
||||
name = "CentCom Stand";
|
||||
req_access = list("cent_captain")
|
||||
@@ -2634,10 +2628,8 @@
|
||||
/obj/structure/chair{
|
||||
dir = 8
|
||||
},
|
||||
/obj/item/radio/intercom{
|
||||
desc = "Talk smack through this.";
|
||||
/obj/item/radio/intercom/syndicate{
|
||||
pixel_x = -32;
|
||||
syndie = 1
|
||||
},
|
||||
/turf/open/floor/iron/grimy,
|
||||
/area/centcom/central_command_areas/courtroom)
|
||||
@@ -2703,10 +2695,7 @@
|
||||
/area/centcom/central_command_areas/courtroom)
|
||||
"mn" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/radio/intercom{
|
||||
desc = "Talk smack through this.";
|
||||
syndie = 1
|
||||
},
|
||||
/obj/item/radio/intercom/syndicate,
|
||||
/turf/open/floor/iron/grimy,
|
||||
/area/centcom/central_command_areas/courtroom)
|
||||
"mo" = (
|
||||
@@ -10313,10 +10302,8 @@
|
||||
/obj/machinery/computer/station_alert{
|
||||
dir = 8
|
||||
},
|
||||
/obj/item/radio/intercom{
|
||||
desc = "Talk smack through this.";
|
||||
pixel_x = 28;
|
||||
syndie = 1
|
||||
/obj/item/radio/intercom/syndicate{
|
||||
pixel_x = 28
|
||||
},
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/centcom/central_command_areas/control)
|
||||
|
||||
@@ -130,3 +130,10 @@
|
||||
#define RADIO_FREQENCY_LOCKED 1
|
||||
/// Radio frequency is locked and unchangeable, but can be unlocked by an emag
|
||||
#define RADIO_FREQENCY_EMAGGABLE_LOCK 2
|
||||
|
||||
///Bitflag for if a headset can use the syndicate radio channel
|
||||
#define RADIO_SPECIAL_SYNDIE (1<<0)
|
||||
///Bitflag for if a headset can use the centcom radio channel
|
||||
#define RADIO_SPECIAL_CENTCOM (1<<1)
|
||||
///Bitflag for if a headset can use the binary radio channel
|
||||
#define RADIO_SPECIAL_BINARY (1<<2)
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
if (TRANSMISSION_SUPERSPACE)
|
||||
// Only radios which are independent
|
||||
for(var/obj/item/radio/independent_radio in GLOB.all_radios["[frequency]"])
|
||||
if(independent_radio.independent && independent_radio.can_receive(frequency, signal_reaches_every_z_level))
|
||||
if((independent_radio.special_channels & RADIO_SPECIAL_CENTCOM) && independent_radio.can_receive(frequency, signal_reaches_every_z_level))
|
||||
radios += independent_radio
|
||||
|
||||
for(var/obj/item/radio/called_radio as anything in radios)
|
||||
|
||||
@@ -4,26 +4,22 @@
|
||||
icon = 'icons/obj/devices/circuitry_n_data.dmi'
|
||||
icon_state = "cypherkey_basic"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
/// Can this radio key access the binary radio channel?
|
||||
var/translate_binary = FALSE
|
||||
/// Decrypts Syndicate radio transmissions.
|
||||
var/syndie = FALSE
|
||||
/// If true, the radio can say/hear on the special CentCom channel.
|
||||
var/independent = FALSE
|
||||
/// What channels does this encryption key grant to the parent headset.
|
||||
var/list/channels = list()
|
||||
/// Flags for which "special" radio networks should be accessible
|
||||
var/special_channels = NONE
|
||||
var/datum/language/translated_language
|
||||
greyscale_config = /datum/greyscale_config/encryptionkey_basic
|
||||
greyscale_colors = "#820a16#3758c4"
|
||||
|
||||
/obj/item/encryptionkey/examine(mob/user)
|
||||
. = ..()
|
||||
if(LAZYLEN(channels) || translate_binary)
|
||||
if(LAZYLEN(channels) || special_channels & RADIO_SPECIAL_BINARY)
|
||||
var/list/examine_text_list = list()
|
||||
for(var/i in channels)
|
||||
examine_text_list += "[GLOB.channel_tokens[i]] - [LOWER_TEXT(i)]"
|
||||
|
||||
if(translate_binary)
|
||||
if(special_channels & RADIO_SPECIAL_BINARY)
|
||||
examine_text_list += "[GLOB.channel_tokens[MODE_BINARY]] - [MODE_BINARY]"
|
||||
|
||||
. += span_notice("It can access the following channels; [jointext(examine_text_list, ", ")].")
|
||||
@@ -34,14 +30,14 @@
|
||||
name = "syndicate encryption key"
|
||||
icon_state = "cypherkey_syndicate"
|
||||
channels = list(RADIO_CHANNEL_SYNDICATE = 1)
|
||||
syndie = TRUE
|
||||
special_channels = RADIO_SPECIAL_SYNDIE
|
||||
greyscale_config = /datum/greyscale_config/encryptionkey_syndicate
|
||||
greyscale_colors = "#171717#990000"
|
||||
|
||||
/obj/item/encryptionkey/binary
|
||||
name = "binary translator key"
|
||||
icon_state = "cypherkey_basic"
|
||||
translate_binary = TRUE
|
||||
special_channels = RADIO_SPECIAL_BINARY
|
||||
translated_language = /datum/language/machine
|
||||
greyscale_config = /datum/greyscale_config/encryptionkey_basic
|
||||
greyscale_colors = "#24a157#3758c4"
|
||||
@@ -182,7 +178,7 @@
|
||||
/obj/item/encryptionkey/headset_cent
|
||||
name = "\improper CentCom radio encryption key"
|
||||
icon_state = "cypherkey_centcom"
|
||||
independent = TRUE
|
||||
special_channels = RADIO_SPECIAL_CENTCOM
|
||||
channels = list(RADIO_CHANNEL_CENTCOM = 1)
|
||||
greyscale_config = /datum/greyscale_config/encryptionkey_centcom
|
||||
greyscale_colors = "#24a157#dca01b"
|
||||
@@ -211,14 +207,14 @@
|
||||
RADIO_CHANNEL_SERVICE = 1,
|
||||
RADIO_CHANNEL_AI_PRIVATE = 1,
|
||||
)
|
||||
translate_binary = TRUE
|
||||
special_channels = RADIO_SPECIAL_BINARY
|
||||
translated_language = /datum/language/machine
|
||||
|
||||
/obj/item/encryptionkey/ai/evil //ported from NT, this goes 'inside' the AI.
|
||||
name = "syndicate binary encryption key"
|
||||
icon_state = "cypherkey_syndicate"
|
||||
channels = list(RADIO_CHANNEL_SYNDICATE = 1)
|
||||
syndie = TRUE
|
||||
special_channels = RADIO_SPECIAL_SYNDIE
|
||||
greyscale_config = /datum/greyscale_config/encryptionkey_syndicate
|
||||
greyscale_colors = "#171717#990000"
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
if(item_flags & IN_INVENTORY && loc == user)
|
||||
// construction of frequency description
|
||||
var/list/avail_chans = list("Use [RADIO_KEY_COMMON] for the currently tuned frequency")
|
||||
if(translate_binary)
|
||||
if(special_channels & RADIO_SPECIAL_BINARY)
|
||||
avail_chans += "use [MODE_TOKEN_BINARY] for [MODE_BINARY]"
|
||||
if(length(channels))
|
||||
for(var/i in 1 to length(channels))
|
||||
@@ -430,12 +430,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
|
||||
if(!(ch_name in src.channels))
|
||||
LAZYSET(channels, ch_name, keyslot2.channels[ch_name])
|
||||
|
||||
if(keyslot2.translate_binary)
|
||||
translate_binary = TRUE
|
||||
if(keyslot2.syndie)
|
||||
syndie = TRUE
|
||||
if(keyslot2.independent)
|
||||
independent = TRUE
|
||||
special_channels |= keyslot2.special_channels
|
||||
|
||||
for(var/ch_name in channels)
|
||||
secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name])
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
return FALSE
|
||||
|
||||
if(freq == FREQ_SYNDICATE)
|
||||
if(!(syndie))
|
||||
if(!(special_channels &= RADIO_SPECIAL_SYNDIE))
|
||||
return FALSE//Prevents broadcast of messages over devices lacking the encryption
|
||||
|
||||
return TRUE
|
||||
@@ -219,6 +219,19 @@ WALL_MOUNT_DIRECTIONAL_HELPERS(/obj/item/radio/intercom)
|
||||
command = TRUE
|
||||
icon_off = "intercom_command-p"
|
||||
|
||||
/obj/item/radio/intercom/syndicate
|
||||
name = "syndicate intercom"
|
||||
desc = "Talk smack through this."
|
||||
command = TRUE
|
||||
special_channels = RADIO_SPECIAL_SYNDIE
|
||||
|
||||
/obj/item/radio/intercom/syndicate/freerange
|
||||
name = "syndicate wide-band intercom"
|
||||
desc = "A custom-made Syndicate-issue intercom used to transmit on all Nanotrasen frequencies. Particularly expensive."
|
||||
freerange = TRUE
|
||||
|
||||
WALL_MOUNT_DIRECTIONAL_HELPERS(/obj/item/radio/intercom/prison)
|
||||
WALL_MOUNT_DIRECTIONAL_HELPERS(/obj/item/radio/intercom/chapel)
|
||||
WALL_MOUNT_DIRECTIONAL_HELPERS(/obj/item/radio/intercom/command)
|
||||
WALL_MOUNT_DIRECTIONAL_HELPERS(/obj/item/radio/intercom/syndicate)
|
||||
WALL_MOUNT_DIRECTIONAL_HELPERS(/obj/item/radio/intercom/syndicate/freerange)
|
||||
|
||||
@@ -63,12 +63,8 @@
|
||||
|
||||
/// Encryption key handling
|
||||
var/obj/item/encryptionkey/keyslot
|
||||
/// If true, can hear the special binary channel.
|
||||
var/translate_binary = FALSE
|
||||
/// If true, can say/hear on the special CentCom channel.
|
||||
var/independent = FALSE
|
||||
/// If true, hears all well-known channels automatically, and can say/hear on the Syndicate channel. Also protects from radio jammers.
|
||||
var/syndie = FALSE
|
||||
/// Flags for which "special" radio networks should be accessible
|
||||
var/special_channels = NONE
|
||||
/// associative list of the encrypted radio channels this radio is currently set to listen/broadcast to, of the form: list(channel name = TRUE or FALSE)
|
||||
var/list/channels
|
||||
/// associative list of the encrypted radio channels this radio can listen/broadcast to, of the form: list(channel name = channel frequency)
|
||||
@@ -104,7 +100,7 @@
|
||||
perform_update_icon = FALSE
|
||||
set_listening(listening)
|
||||
set_broadcasting(broadcasting)
|
||||
set_frequency(sanitize_frequency(frequency, freerange, syndie))
|
||||
set_frequency(sanitize_frequency(frequency, freerange, (special_channels & RADIO_SPECIAL_SYNDIE)))
|
||||
set_on(on)
|
||||
perform_update_icon = TRUE
|
||||
|
||||
@@ -149,12 +145,7 @@
|
||||
if(!(channel_name in channels))
|
||||
channels[channel_name] = keyslot.channels[channel_name]
|
||||
|
||||
if(keyslot.translate_binary)
|
||||
translate_binary = TRUE
|
||||
if(keyslot.syndie)
|
||||
syndie = TRUE
|
||||
if(keyslot.independent)
|
||||
independent = TRUE
|
||||
special_channels = keyslot.special_channels
|
||||
|
||||
for(var/channel_name in channels)
|
||||
secure_radio_connections[channel_name] = add_radio(src, GLOB.radiochannels[channel_name])
|
||||
@@ -166,9 +157,7 @@
|
||||
/obj/item/radio/proc/resetChannels()
|
||||
channels = list()
|
||||
secure_radio_connections = list()
|
||||
translate_binary = FALSE
|
||||
syndie = FALSE
|
||||
independent = FALSE
|
||||
special_channels = NONE
|
||||
|
||||
///goes through all radio channels we should be listening for and readds them to the global list
|
||||
/obj/item/radio/proc/readd_listening_radio_channels()
|
||||
@@ -180,7 +169,7 @@
|
||||
/obj/item/radio/proc/make_syndie() // Turns normal radios into Syndicate radios!
|
||||
qdel(keyslot)
|
||||
keyslot = new /obj/item/encryptionkey/syndicate()
|
||||
syndie = TRUE
|
||||
special_channels |= RADIO_SPECIAL_SYNDIE
|
||||
recalculateChannels()
|
||||
|
||||
/obj/item/radio/interact(mob/user)
|
||||
@@ -337,7 +326,7 @@
|
||||
channel = null
|
||||
|
||||
// Nearby active jammers prevent the message from transmitting
|
||||
if(is_within_radio_jammer_range(src) && !syndie)
|
||||
if(is_within_radio_jammer_range(src) && !(special_channels & RADIO_SPECIAL_SYNDIE))
|
||||
return
|
||||
|
||||
// Determine the identity information which will be attached to the signal.
|
||||
@@ -347,7 +336,7 @@
|
||||
var/datum/signal/subspace/vocal/signal = new(src, freq, speaker, language, radio_message, spans, message_mods)
|
||||
|
||||
// Independent radios, on the CentCom frequency, reach all independent radios
|
||||
if (independent && (freq == FREQ_CENTCOM || freq == FREQ_CTF_RED || freq == FREQ_CTF_BLUE || freq == FREQ_CTF_GREEN || freq == FREQ_CTF_YELLOW))
|
||||
if (special_channels & RADIO_SPECIAL_CENTCOM && (freq == FREQ_CENTCOM || freq == FREQ_CTF_RED || freq == FREQ_CTF_BLUE || freq == FREQ_CTF_GREEN || freq == FREQ_CTF_YELLOW))
|
||||
signal.data["compression"] = 0
|
||||
signal.transmission_method = TRANSMISSION_SUPERSPACE
|
||||
signal.levels = list(0)
|
||||
@@ -415,7 +404,7 @@
|
||||
if(!position || !(position.z in levels))
|
||||
return FALSE
|
||||
|
||||
if (input_frequency == FREQ_SYNDICATE && !syndie)
|
||||
if (input_frequency == FREQ_SYNDICATE && !(special_channels & RADIO_SPECIAL_SYNDIE))
|
||||
return FALSE
|
||||
|
||||
// allow checks: are we listening on that frequency?
|
||||
@@ -423,7 +412,7 @@
|
||||
return TRUE
|
||||
for(var/ch_name in channels)
|
||||
if(channels[ch_name] & FREQ_LISTENING)
|
||||
if(GLOB.radiochannels[ch_name] == text2num(input_frequency) || syndie)
|
||||
if(GLOB.radiochannels[ch_name] == text2num(input_frequency) || special_channels & RADIO_SPECIAL_SYNDIE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -491,7 +480,7 @@
|
||||
tune = tune * 10
|
||||
. = TRUE
|
||||
if(.)
|
||||
set_frequency(sanitize_frequency(tune, freerange, syndie))
|
||||
set_frequency(sanitize_frequency(tune, freerange, (special_channels & RADIO_SPECIAL_SYNDIE)))
|
||||
if("listen")
|
||||
set_listening(!listening)
|
||||
. = TRUE
|
||||
@@ -590,7 +579,7 @@
|
||||
channels[ch_name] = TRUE
|
||||
|
||||
/obj/item/radio/borg/syndicate
|
||||
syndie = TRUE
|
||||
special_channels = RADIO_SPECIAL_SYNDIE
|
||||
keyslot = /obj/item/encryptionkey/syndicate
|
||||
|
||||
/obj/item/radio/borg/syndicate/Initialize(mapload)
|
||||
|
||||
@@ -153,15 +153,15 @@ ADMIN_VERB(borg_panel, R_ADMIN, "Show Borg Panel", ADMIN_VERB_NO_DESCRIPTION, AD
|
||||
if (!borg.radio.keyslot) // There's no encryption key. This shouldn't happen but we can cope
|
||||
borg.radio.channels -= channel
|
||||
if (channel == RADIO_CHANNEL_SYNDICATE)
|
||||
borg.radio.syndie = FALSE
|
||||
borg.radio.special_channels &= ~RADIO_SPECIAL_SYNDIE
|
||||
else if (channel == "CentCom")
|
||||
borg.radio.independent = FALSE
|
||||
borg.radio.special_channels &= ~RADIO_SPECIAL_CENTCOM
|
||||
else
|
||||
borg.radio.keyslot.channels -= channel
|
||||
if (channel == RADIO_CHANNEL_SYNDICATE)
|
||||
borg.radio.keyslot.syndie = FALSE
|
||||
borg.radio.keyslot.special_channels &= ~RADIO_SPECIAL_SYNDIE
|
||||
else if (channel == "CentCom")
|
||||
borg.radio.keyslot.independent = FALSE
|
||||
borg.radio.keyslot.special_channels &= ~RADIO_SPECIAL_CENTCOM
|
||||
message_admins("[key_name_admin(user)] removed the [channel] radio channel from [ADMIN_LOOKUPFLW(borg)].")
|
||||
log_silicon("[key_name(user)] removed the [channel] radio channel from [key_name(borg)].")
|
||||
else // We're adding a channel
|
||||
@@ -169,9 +169,9 @@ ADMIN_VERB(borg_panel, R_ADMIN, "Show Borg Panel", ADMIN_VERB_NO_DESCRIPTION, AD
|
||||
borg.radio.keyslot = new()
|
||||
borg.radio.keyslot.channels[channel] = 1
|
||||
if (channel == RADIO_CHANNEL_SYNDICATE)
|
||||
borg.radio.keyslot.syndie = TRUE
|
||||
borg.radio.keyslot.special_channels |= RADIO_SPECIAL_SYNDIE
|
||||
else if (channel == "CentCom")
|
||||
borg.radio.keyslot.independent = TRUE
|
||||
borg.radio.keyslot.special_channels |= RADIO_SPECIAL_CENTCOM
|
||||
message_admins("[key_name_admin(user)] added the [channel] radio channel to [ADMIN_LOOKUPFLW(borg)].")
|
||||
log_silicon("[key_name(user)] added the [channel] radio channel to [key_name(borg)].")
|
||||
borg.radio.recalculateChannels()
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
var/obj/item/radio/headset = human_to_equip.ears
|
||||
headset.set_frequency(team_radio_freq)
|
||||
headset.freqlock = RADIO_FREQENCY_LOCKED
|
||||
headset.independent = TRUE
|
||||
headset.special_channels |= RADIO_SPECIAL_CENTCOM
|
||||
human_to_equip.dna.species.stunmod = 0
|
||||
|
||||
/datum/outfit/ctf/instagib
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
var/area/our_area = get_area(src)
|
||||
if(our_area.area_flags & BINARY_JAMMING)
|
||||
return FALSE
|
||||
return dongle.translate_binary
|
||||
return (dongle.special_channels & RADIO_SPECIAL_BINARY)
|
||||
|
||||
/mob/living/carbon/human/radio(message, list/message_mods = list(), list/spans, language) //Poly has a copy of this, lazy bastard
|
||||
. = ..()
|
||||
|
||||
@@ -874,7 +874,7 @@
|
||||
lawupdate = TRUE
|
||||
lawsync()
|
||||
if(radio && AI.radio) //AI keeps all channels, including Syndie if it is a Traitor
|
||||
if(AI.radio.syndie)
|
||||
if((AI.radio.special_channels & RADIO_SPECIAL_SYNDIE))
|
||||
radio.make_syndie()
|
||||
radio.subspace_transmission = TRUE
|
||||
radio.channels = AI.radio.channels
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/mob/living/silicon/pai/binarycheck()
|
||||
return radio?.translate_binary
|
||||
return (radio?.special_channels & RADIO_SPECIAL_BINARY)
|
||||
|
||||
@@ -237,9 +237,9 @@
|
||||
// Normally speaking, if there isn't a functional telecomms array on the same z-level, then handheld radios
|
||||
// have a short delay before sending the message. We use the centcom frequency to get around this.
|
||||
speaker_radio.set_frequency(FREQ_CENTCOM)
|
||||
speaker_radio.independent = TRUE
|
||||
speaker_radio.special_channels = RADIO_SPECIAL_CENTCOM
|
||||
listener_radio.set_frequency(FREQ_CENTCOM)
|
||||
listener_radio.independent = TRUE
|
||||
listener_radio.special_channels = RADIO_SPECIAL_CENTCOM
|
||||
|
||||
var/pangram_quote = "The quick brown fox jumps over the lazy dog"
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
return TRUE
|
||||
if("set_frequency")
|
||||
var/new_frequency = text2num(params["new_frequency"])
|
||||
radio.set_frequency(sanitize_frequency(new_frequency, radio.freerange, radio.syndie))
|
||||
radio.set_frequency(sanitize_frequency(new_frequency, radio.freerange, (radio.special_channels & RADIO_SPECIAL_SYNDIE)))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user