mirror of
https://github.com/Skyrat-SS13/Skyrat-tg.git
synced 2026-08-27 14:58:01 +01:00
[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:
co-authored by
John Willard
Gandalf
parent
a26f32aef5
commit
d34aab9be3
@@ -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
|
||||
Reference in New Issue
Block a user