[MIRROR] PDA general maintenance (NTNet downloader rework) [MDB IGNORE] (#25133)

* PDA general maintenance (NTNet downloader rework)

* Update modular_computer.dm

* e

* weh

* Update archive_viewer.dm

* Update three_layer_hats.json

---------

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-12-24 22:28:40 +00:00
committed by GitHub
co-authored by John Willard Gandalf
parent a26f32aef5
commit d34aab9be3
52 changed files with 222 additions and 187 deletions
@@ -0,0 +1,127 @@
#define MAX_CHANNELS 1000
/datum/ntnet_conversation
///The title of the conversation, seen in the UI.
var/title = "Untitled Conversation"
//If a channel is strong, it cannot be renamed or deleted.
var/strong = FALSE
///The password to join a channel, set by an Administrator.
var/password
///A static UID to ensure no conversations are the same.
var/static/ntnrc_uid = 0
///ID using the UID.
var/id
///List of all messages sent in the conversation.
var/list/messages = list()
///The "Administrator" of the channel, the creator starts as channel's operator by default.
var/datum/computer_file/program/chatclient/channel_operator
///Chat clients who are active or minimized.
var/list/datum/computer_file/program/chatclient/active_clients = list()
///Chat clients who have exited out of the program.
var/list/datum/computer_file/program/chatclient/offline_clients = list()
///Chat clients currently muted by the operator, rendering them unable to ping other people.
var/list/datum/computer_file/program/chatclient/muted_clients = list()
/datum/ntnet_conversation/New(title, strong = FALSE)
src.title = title
src.strong = strong
id = ntnrc_uid
ntnrc_uid++
if(id > MAX_CHANNELS)
qdel(src)
return
SSmodular_computers.chat_channels.Add(src)
return ..()
/datum/ntnet_conversation/Destroy()
SSmodular_computers.chat_channels.Remove(src)
for(var/datum/computer_file/program/chatclient/chatterbox as anything in (active_clients | offline_clients))
purge_client(chatterbox)
return ..()
/datum/ntnet_conversation/proc/add_message(message, username)
message = "[station_time_timestamp(format = "hh:mm")] [username]: [message]"
messages.Add(message)
trim_message_list()
/datum/ntnet_conversation/proc/add_status_message(message)
messages.Add("[station_time_timestamp(format = "hh:mm")] -!- [message]")
trim_message_list()
/datum/ntnet_conversation/proc/trim_message_list()
if(messages.len <= 50)
return
messages = messages.Copy(messages.len-50 ,0)
/datum/ntnet_conversation/proc/add_client(datum/computer_file/program/chatclient/new_user, silent = FALSE)
if(!istype(new_user))
return
new_user.conversations |= src
active_clients.Add(new_user)
if(!silent)
add_status_message("[new_user.username] has joined the channel.")
// No operator, so we assume the channel was empty. Assign this user as operator, without the message, since you're the creator.
if(!channel_operator)
changeop(new_user, silent = TRUE)
//Clear all of our references to a client, used for client deletion
/datum/ntnet_conversation/proc/purge_client(datum/computer_file/program/chatclient/forget)
remove_client(forget)
forget.conversations -= src
/datum/ntnet_conversation/proc/remove_client(datum/computer_file/program/chatclient/leaving)
if(!istype(leaving))
return
if(leaving in active_clients)
active_clients.Remove(leaving)
add_status_message("[leaving.username] has left the channel.")
muted_clients -= leaving
offline_clients -= leaving
// Channel operator left, pick new operator
if(leaving == channel_operator)
channel_operator = null
if(active_clients.len)
var/datum/computer_file/program/chatclient/newop = pick(active_clients)
changeop(newop)
/datum/ntnet_conversation/proc/go_offline(datum/computer_file/program/chatclient/offline)
if(!istype(offline) || !(offline in active_clients))
return
active_clients.Remove(offline)
offline_clients.Add(offline)
/datum/ntnet_conversation/proc/mute_user(datum/computer_file/program/chatclient/op, datum/computer_file/program/chatclient/muted)
if(!op.netadmin_mode && (channel_operator != op)) //sanity even if the person shouldn't be able to see the mute button
return
if(muted in muted_clients)
muted_clients.Remove(muted)
muted.computer.alert_call(muted, "You have been unmuted from [title]!", 'sound/machines/ping.ogg')
else
muted_clients.Add(muted)
muted.computer.alert_call(muted, "You have been muted from [title]!")
/datum/ntnet_conversation/proc/ping_user(datum/computer_file/program/chatclient/pinger, datum/computer_file/program/chatclient/pinged)
if(pinger in muted_clients) //oh my god fuck off
return
add_status_message("[pinger.username] pinged [pinged.username].")
pinged.computer.alert_call(pinged, "You have been pinged in [title] by [pinger.username]!", 'sound/machines/ping.ogg')
/datum/ntnet_conversation/proc/changeop(datum/computer_file/program/chatclient/newop, silent = FALSE)
if(!istype(newop))
CRASH("[src] is attempting to add [newop] as the operator, but it isn't a chat client.")
channel_operator = newop
if(!silent)
add_status_message("Channel operator status transferred to [newop.username].")
/datum/ntnet_conversation/proc/change_title(newtitle, datum/computer_file/program/chatclient/renamer)
if((channel_operator != renamer) || strong) // Not Authorised or channel cannot be editted
return FALSE
add_status_message("[renamer.username] has changed channel title from [title] to [newtitle]")
title = newtitle
#undef MAX_CHANNELS
@@ -0,0 +1,269 @@
#define USERNAME_SIZE 32
#define CHANNELNAME_SIZE 18
#define MESSAGE_SIZE 2048
#define PING_COOLDOWN_TIME (3 SECONDS)
/datum/computer_file/program/chatclient
filename = "ntnrc_client"
filedesc = "Chat Client"
downloader_category = PROGRAM_CATEGORY_DEVICE
program_open_overlay = "command"
extended_desc = "This program allows communication over NTNRC network"
size = 8
requires_ntnet = TRUE
ui_header = "ntnrc_idle.gif"
available_on_ntnet = TRUE
tgui_id = "NtosNetChat"
program_icon = "comment-alt"
alert_able = TRUE
///The user's screen name.
var/username
///The last message you sent in a channel, used to tell if someone has sent a new message yet.
var/last_message
///The channel currently active in.
var/active_channel
///If the tablet is in Admin mode, you bypass Passwords and aren't announced when entering a channel.
var/netadmin_mode = FALSE
///All NTnet conversations the application is apart of.
var/list/datum/ntnet_conversation/conversations = list()
///Cooldown timer between pings.
COOLDOWN_DECLARE(ping_cooldown)
/datum/computer_file/program/chatclient/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing)
. = ..()
if(!username)
username = "DefaultUser[rand(100, 999)]"
/datum/computer_file/program/chatclient/Destroy()
for(var/datum/ntnet_conversation/discussion as anything in conversations)
discussion.purge_client(src)
conversations.Cut()
return ..()
/datum/computer_file/program/chatclient/proc/create_new_channel(channel_title, strong = FALSE)
var/datum/ntnet_conversation/new_converstaion = new /datum/ntnet_conversation(channel_title, strong)
new_converstaion.add_client(src)
new_converstaion.title = channel_title
active_channel = new_converstaion.id
return new_converstaion
/datum/computer_file/program/chatclient/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
var/datum/ntnet_conversation/channel = SSmodular_computers.get_chat_channel_by_id(active_channel)
var/authed = FALSE
if(channel && ((channel.channel_operator == src) || netadmin_mode))
authed = TRUE
switch(action)
if("PRG_speak")
if(!channel || isnull(active_channel))
return
var/message = reject_bad_chattext(params["message"], MESSAGE_SIZE)
if(!message)
return
if(channel.password && (!(src in channel.active_clients) && !(src in channel.offline_clients)))
if(channel.password == message)
channel.add_client(src)
return TRUE
channel.add_message(message, username)
var/mob/living/user = usr
user.log_talk(message, LOG_CHAT, tag = "as [username] to channel [channel.title]")
return TRUE
if("PRG_joinchannel")
var/new_target = text2num(params["id"])
if(isnull(new_target) || new_target == active_channel)
return
if(netadmin_mode)
active_channel = new_target // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
return TRUE
active_channel = new_target
channel = SSmodular_computers.get_chat_channel_by_id(new_target)
if((!(src in channel.active_clients) && !(src in channel.offline_clients)) && !channel.password)
channel.add_client(src)
return TRUE
if("PRG_leavechannel")
if(channel)
channel.remove_client(src)
active_channel = null
return TRUE
if("PRG_newchannel")
var/channel_title = reject_bad_chattext(params["new_channel_name"], CHANNELNAME_SIZE)
if(!channel_title)
return
create_new_channel(channel_title)
return TRUE
if("PRG_toggleadmin")
if(netadmin_mode)
netadmin_mode = FALSE
channel?.add_client(src)
return TRUE
var/mob/living/user = usr
if(can_run(user, TRUE, list(ACCESS_NETWORK)))
for(var/datum/ntnet_conversation/channels as anything in SSmodular_computers.chat_channels)
channels.remove_client(src)
netadmin_mode = TRUE
return TRUE
if("PRG_changename")
var/newname = reject_bad_chattext(params["new_name"], USERNAME_SIZE)
newname = replacetext(newname, " ", "_")
if(!newname || newname == username)
return
for(var/datum/ntnet_conversation/anychannel as anything in SSmodular_computers.chat_channels)
if(src in anychannel.active_clients)
anychannel.add_status_message("[username] is now known as [newname].")
username = newname
return TRUE
if("PRG_savelog")
if(!channel)
return
var/logname = stripped_input(params["log_name"])
if(!logname)
return
var/datum/computer_file/data/text/logfile = new()
// Now we will generate HTML-compliant file that can actually be viewed/printed.
logfile.filename = logname
logfile.stored_text = "\[b\]Logfile dump from NTNRC channel [channel.title]\[/b\]\[BR\]"
for(var/logstring in channel.messages)
logfile.stored_text = "[logfile.stored_text][logstring]\[BR\]"
logfile.stored_text = "[logfile.stored_text]\[b\]Logfile dump completed.\[/b\]"
logfile.calculate_size()
if(!computer || !computer.store_file(logfile))
if(!computer)
// This program shouldn't even be runnable without computer.
CRASH("Var computer is null!")
computer.visible_message(span_warning("\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."))
return TRUE
if("PRG_renamechannel")
if(!authed)
return
var/newname = reject_bad_chattext(params["new_name"], CHANNELNAME_SIZE)
if(!newname || !channel)
return
channel.add_status_message("Channel renamed from [channel.title] to [newname] by operator.")
channel.title = newname
return TRUE
if("PRG_deletechannel")
if(authed)
qdel(channel)
active_channel = null
return TRUE
if("PRG_setpassword")
if(!authed)
return
var/new_password = sanitize(params["new_password"])
if(!authed)
return
channel.password = new_password
return TRUE
if("PRG_mute_user")
if(!authed)
return
var/datum/computer_file/program/chatclient/muted = locate(params["ref"]) in channel.active_clients + channel.offline_clients
channel.mute_user(src, muted)
return TRUE
if("PRG_ping_user")
if(!COOLDOWN_FINISHED(src, ping_cooldown))
return
if(src in channel.muted_clients)
return
var/datum/computer_file/program/chatclient/pinged = locate(params["ref"]) in channel.active_clients + channel.offline_clients
channel.ping_user(src, pinged)
COOLDOWN_START(src, ping_cooldown, PING_COOLDOWN_TIME)
return TRUE
/datum/computer_file/program/chatclient/process_tick(seconds_per_tick)
. = ..()
var/datum/ntnet_conversation/channel = SSmodular_computers.get_chat_channel_by_id(active_channel)
if(src in computer.idle_threads)
ui_header = "ntnrc_idle.gif"
if(channel)
// Remember the last message. If there is no message in the channel remember null.
last_message = length(channel.messages) ? channel.messages[length(channel.messages)] : null
else
last_message = null
return TRUE
if(channel?.messages?.len)
ui_header = (last_message == channel.messages[length(channel.messages)] ? "ntnrc_idle.gif" : "ntnrc_new.gif")
else
ui_header = "ntnrc_idle.gif"
/datum/computer_file/program/chatclient/on_start(mob/living/user)
. = ..()
if(!.)
return
for(var/datum/ntnet_conversation/channel as anything in SSmodular_computers.chat_channels)
if(src in channel.offline_clients)
channel.offline_clients.Remove(src)
channel.active_clients.Add(src)
/datum/computer_file/program/chatclient/kill_program(mob/user)
for(var/datum/ntnet_conversation/channel as anything in SSmodular_computers.chat_channels)
channel.go_offline(src)
active_channel = null
return ..()
/datum/computer_file/program/chatclient/ui_static_data(mob/user)
var/list/data = list()
data["selfref"] = REF(src) //used to verify who is you, as usernames can be copied.
return data
/datum/computer_file/program/chatclient/ui_data(mob/user)
var/list/data = list()
var/list/all_channels = list()
for(var/datum/ntnet_conversation/conversations as anything in SSmodular_computers.chat_channels)
if(conversations.title)
all_channels.Add(list(list(
"chan" = conversations.title,
"id" = conversations.id,
)))
data["all_channels"] = all_channels
data["active_channel"] = active_channel
var/datum/ntnet_conversation/channel = SSmodular_computers.get_chat_channel_by_id(active_channel)
var/authed = FALSE
data["clients"] = list()
data["messages"] = list()
if(channel)
data["title"] = channel.title
if(!channel.password || netadmin_mode)
authed = TRUE
var/list/clients = list()
for(var/datum/computer_file/program/chatclient/channel_client as anything in channel.active_clients + channel.offline_clients)
if(channel_client == src)
authed = TRUE
clients.Add(list(list(
"name" = channel_client.username,
"online" = (channel_client == channel_client.computer.active_program),
"away" = (channel_client in channel_client.computer.idle_threads),
"muted" = (channel_client in channel.muted_clients),
"operator" = (channel.channel_operator == channel_client),
"ref" = REF(channel_client),
)))
//no fishing for ui data allowed
if(authed)
data["strong"] = channel.strong
data["clients"] = clients
var/list/messages = list()
for(var/i=channel.messages.len to 1 step -1)
messages.Add(list(list(
"msg" = channel.messages[i],
)))
data["messages"] = messages
data["is_operator"] = (channel.channel_operator == src) || netadmin_mode
data["username"] = username
data["adminmode"] = netadmin_mode
data["can_admin"] = can_run(user, FALSE, list(ACCESS_NETWORK))
data["authed"] = authed
return data
#undef USERNAME_SIZE
#undef CHANNELNAME_SIZE
#undef MESSAGE_SIZE
#undef PING_COOLDOWN_TIME