mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-27 18:41:59 +00:00
Adds NTNRC (NTNet Relay Chat)
- Adds NTNet relay chat, communication method that works as alternative to PDA messaging. - NTNRC client is available to everyone for download. Once started, you can set your username (much as you can with IRC in real) and join channels created by other users (or create your own channel) - Each channel has an operator. This is typically the channel's creator. If the operator leaves, operator status is transferred to randomly picked other user. If all users leave operator status is set as null until someone arrives again. - Operator can delete or rename the channel, as well as save copy of chat logs to the hard drive (in future it will be editable/printable) and set channel password. Password-locked channels are private only for those who know the password. - Added new access type (ID 42): access_network. RD is now, by default, given this access. - People with network access can enter administrative mode, which allows them to make operator actions even without operator status on all channels. Furthermore, this hides them from other users (unless they decide to talk). They also bypass password locks, if they are set. - Minor tweaks to NTNet monitoring tool. Fixed one minor graphical glitch in the UI and added access requirement to run the program (network access) - Screenshot of NTNRC in action: http://i.imgur.com/c7hrWY5.png
This commit is contained in:
@@ -7,4 +7,12 @@
|
||||
/datum/computer_file/data/clone()
|
||||
var/datum/computer_file/data/temp = ..()
|
||||
temp.stored_data = stored_data
|
||||
return temp
|
||||
return temp
|
||||
|
||||
// Calculates file size from amount of characters in saved string
|
||||
/datum/computer_file/data/proc/calculate_size(var/block_size = 250)
|
||||
size = max(1, round(length(stored_data) / block_size))
|
||||
|
||||
/datum/computer_file/data/logfile
|
||||
filetype = "LOG"
|
||||
|
||||
|
||||
@@ -54,8 +54,12 @@
|
||||
|
||||
// Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
|
||||
// User has to wear their ID or have it inhand for ID Scan to work.
|
||||
/datum/computer_file/program/proc/can_run(var/mob/living/user, var/loud = 0)
|
||||
if(!required_access) // No required_access, allow it.
|
||||
// Can also be called manually, with optional parameter being access_to_check to scan the user's ID
|
||||
/datum/computer_file/program/proc/can_run(var/mob/living/user, var/loud = 0, var/access_to_check)
|
||||
// Defaults to required_access
|
||||
if(!access_to_check)
|
||||
access_to_check = required_access
|
||||
if(!access_to_check) // No required_access, allow it.
|
||||
return 1
|
||||
if(istype(user, /mob/living/silicon)) // AI or robot. Allow it.
|
||||
return 1
|
||||
@@ -75,7 +79,7 @@
|
||||
user << "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>"
|
||||
return 0
|
||||
|
||||
if(required_access in I.access)
|
||||
if(access_to_check in I.access)
|
||||
return 1
|
||||
if(loud && computer)
|
||||
user << "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>"
|
||||
|
||||
@@ -44,14 +44,4 @@
|
||||
network_destination = "RCON remote control system"
|
||||
requires_ntnet_feature = NTNET_SYSTEMCONTROL
|
||||
usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE
|
||||
size = 25
|
||||
|
||||
/datum/computer_file/program/suit_sensors
|
||||
filename = "sensormonitor"
|
||||
filedesc = "Suit Sensors Monitoring"
|
||||
nanomodule_path = /datum/nano_module/crew_monitor
|
||||
program_icon_state = "crew"
|
||||
keyboard_icon_state = "keyboard7"
|
||||
requires_ntnet = 1
|
||||
network_destination = "crew lifesigns monitoring system"
|
||||
size = 20
|
||||
size = 25
|
||||
@@ -0,0 +1,9 @@
|
||||
/datum/computer_file/program/suit_sensors
|
||||
filename = "sensormonitor"
|
||||
filedesc = "Suit Sensors Monitoring"
|
||||
nanomodule_path = /datum/nano_module/crew_monitor
|
||||
program_icon_state = "crew"
|
||||
keyboard_icon_state = "keyboard7"
|
||||
requires_ntnet = 1
|
||||
network_destination = "crew lifesigns monitoring system"
|
||||
size = 20
|
||||
@@ -4,6 +4,7 @@
|
||||
program_icon_state = "generic"
|
||||
size = 7
|
||||
requires_ntnet = 1
|
||||
required_access = access_network
|
||||
available_on_ntnet = 1
|
||||
nanomodule_path = /datum/nano_module/computer_ntnetmonitor/
|
||||
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/datum/computer_file/program/chatclient
|
||||
filename = "ntnrc_client"
|
||||
filedesc = "NTNet Relay Chat Client"
|
||||
program_icon_state = "generic"
|
||||
size = 10
|
||||
requires_ntnet = 1
|
||||
requires_ntnet_feature = NTNET_COMMUNICATION
|
||||
network_destination = "NTNRC server"
|
||||
available_on_ntnet = 1
|
||||
nanomodule_path = /datum/nano_module/computer_chatclient/
|
||||
var/username
|
||||
var/datum/ntnet_conversation/channel = null
|
||||
var/operator_mode = 0 // Channel operator mode
|
||||
var/netadmin_mode = 0 // Administrator mode (invisible to other users + bypasses passwords)
|
||||
|
||||
/datum/computer_file/program/chatclient/New()
|
||||
username = "DefaultUser[rand(100, 999)]"
|
||||
|
||||
/datum/computer_file/program/chatclient/Topic(href, href_list)
|
||||
if(href_list["PRG_speak"])
|
||||
if(!channel)
|
||||
return
|
||||
var/mob/living/user = usr
|
||||
var/message = sanitize(input(user, "Enter message or leave blank to cancel: "))
|
||||
if(!message || !channel)
|
||||
return
|
||||
channel.add_message(message, username)
|
||||
|
||||
if(href_list["PRG_joinchannel"])
|
||||
var/datum/ntnet_conversation/C
|
||||
for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels)
|
||||
if(chan.title == href_list["PRG_joinchannel"])
|
||||
C = chan
|
||||
break
|
||||
|
||||
if(!C)
|
||||
return
|
||||
|
||||
if(netadmin_mode)
|
||||
channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
|
||||
return
|
||||
|
||||
if(C.password)
|
||||
var/mob/living/user = usr
|
||||
var/password = sanitize(input(user,"Access Denied. Enter password:"))
|
||||
if(C && (password == C.password))
|
||||
C.add_client(src)
|
||||
channel = C
|
||||
return
|
||||
C.add_client(src)
|
||||
channel = C
|
||||
if(href_list["PRG_leavechannel"])
|
||||
if(channel)
|
||||
channel.remove_client(src)
|
||||
channel = null
|
||||
if(href_list["PRG_newchannel"])
|
||||
var/mob/living/user = usr
|
||||
var/channel_title = sanitize(input(user,"Enter channel name or leave blank to cancel:"))
|
||||
if(!channel_title)
|
||||
return
|
||||
var/datum/ntnet_conversation/C = new/datum/ntnet_conversation()
|
||||
C.add_client(src)
|
||||
C.operator = src
|
||||
channel = C
|
||||
C.title = channel_title
|
||||
if(href_list["PRG_toggleadmin"])
|
||||
if(netadmin_mode)
|
||||
netadmin_mode = 0
|
||||
if(channel)
|
||||
channel.remove_client(src) // We shouldn't be in channel's user list, but just in case...
|
||||
channel = null
|
||||
return
|
||||
var/mob/living/user = usr
|
||||
if(can_run(usr, 1, access_network))
|
||||
if(channel)
|
||||
var/response = alert(user, "Really engage admin-mode? You will be disconnected from your current channel!", "NTNRC Admin mode", "Yes", "No")
|
||||
if(response == "Yes")
|
||||
if(channel)
|
||||
channel.remove_client(src)
|
||||
channel = null
|
||||
else
|
||||
return
|
||||
netadmin_mode = 1
|
||||
if(href_list["PRG_changename"])
|
||||
var/mob/living/user = usr
|
||||
var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:"))
|
||||
if(!newname)
|
||||
return
|
||||
if(channel)
|
||||
channel.add_status_message("[username] is now known as [newname].")
|
||||
username = newname
|
||||
|
||||
if(href_list["PRG_savelog"])
|
||||
if(!channel)
|
||||
return
|
||||
var/mob/living/user = usr
|
||||
var/logname = input(user,"Enter desired logfile name (.log) or leave blank to cancel:")
|
||||
if(!logname || !channel)
|
||||
return
|
||||
var/datum/computer_file/data/logfile = new/datum/computer_file/data/logfile()
|
||||
// Now we will generate HTML-compliant file that can actually be viewed/printed.
|
||||
logfile.stored_data = "<b>Logfile dump from NTNRC channel [channel.title]</b><BR>"
|
||||
for(var/logstring in channel.messages)
|
||||
logfile.stored_data += "[logstring]<BR>"
|
||||
logfile.stored_data = "<b>Logfile dump completed.</b>"
|
||||
logfile.calculate_size()
|
||||
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(logfile))
|
||||
if(!computer)
|
||||
// This program shouldn't even be runnable without computer.
|
||||
CRASH("Var computer is null!")
|
||||
return
|
||||
if(!computer.hard_drive)
|
||||
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive connection error\" warning.")
|
||||
else // In 99.9% cases this will mean our HDD is full
|
||||
computer.visible_message("\The [computer] shows an \"I/O Error - Hard drive may be full. Please free some space and try again. Required space: [logfile.size]GQ\" warning.")
|
||||
if(href_list["PRG_renamechannel"])
|
||||
if(!operator_mode || !channel)
|
||||
return
|
||||
var/mob/living/user = usr
|
||||
var/newname = sanitize(input(user, "Enter new channel name or leave blank to cancel:"))
|
||||
if(!newname || !channel)
|
||||
return
|
||||
channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.")
|
||||
channel.title = newname
|
||||
if(href_list["PRG_deletechannel"])
|
||||
if(channel && ((channel.operator == src) || netadmin_mode))
|
||||
del(channel)
|
||||
if(href_list["PRG_setpassword"])
|
||||
if(!channel || ((channel.operator != src) && !netadmin_mode))
|
||||
return
|
||||
|
||||
var/mob/living/user = usr
|
||||
var/newpassword = sanitize(input(user, "Enter new password for this channel. Leave blank to cancel, enter 'nopassword' to remove password completely:"))
|
||||
if(!channel || !newpassword || ((channel.operator != src) && !netadmin_mode))
|
||||
return
|
||||
|
||||
if(newpassword == "nopassword")
|
||||
channel.password = ""
|
||||
else
|
||||
channel.password = newpassword
|
||||
|
||||
..(href, href_list)
|
||||
|
||||
|
||||
/datum/computer_file/program/chatclient/kill_program(var/forced = 0)
|
||||
if(channel)
|
||||
channel.remove_client(src)
|
||||
channel = null
|
||||
..(forced)
|
||||
|
||||
/datum/nano_module/computer_chatclient
|
||||
name = "NTNet Relay Chat Client"
|
||||
|
||||
/datum/nano_module/computer_chatclient/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
if(!ntnet_global || !ntnet_global.chat_channels)
|
||||
return
|
||||
|
||||
var/list/data = list()
|
||||
if(program)
|
||||
data = program.get_header_data()
|
||||
|
||||
var/datum/computer_file/program/chatclient/C = program
|
||||
if(!istype(C))
|
||||
return
|
||||
|
||||
data["adminmode"] = C.netadmin_mode
|
||||
if(C.channel)
|
||||
data["title"] = C.channel.title
|
||||
var/list/messages[0]
|
||||
for(var/M in C.channel.messages)
|
||||
messages.Add(list(list(
|
||||
"msg" = M
|
||||
)))
|
||||
data["messages"] = messages
|
||||
var/list/clients[0]
|
||||
for(var/datum/computer_file/program/chatclient/cl in C.channel.clients)
|
||||
clients.Add(list(list(
|
||||
"name" = cl.username
|
||||
)))
|
||||
data["clients"] = clients
|
||||
C.operator_mode = (C.channel.operator == C) ? 1 : 0
|
||||
data["is_operator"] = C.operator_mode || C.netadmin_mode
|
||||
|
||||
else // Channel selection screen
|
||||
var/list/all_channels[0]
|
||||
for(var/datum/ntnet_conversation/conv in ntnet_global.chat_channels)
|
||||
if(conv && conv.title)
|
||||
all_channels.Add(list(list(
|
||||
"chan" = conv.title
|
||||
)))
|
||||
data["all_channels"] = all_channels
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "ntnet_chat.tmpl", "NTNet Relay Chat Client", 575, 700, state = state)
|
||||
ui.auto_update_layout = 1
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
Reference in New Issue
Block a user