New chat client / messenger (#10654)

This commit is contained in:
Karolis
2021-01-11 11:04:16 +02:00
committed by GitHub
parent f99e4a29c0
commit 339c531ad7
31 changed files with 858 additions and 846 deletions

View File

@@ -2,9 +2,9 @@ var/global/ntnrc_uid = 0
/datum/ntnet_conversation
var/id
var/title = "Untitled Conversation"
var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator,
var/datum/ntnet_user/operator // "Administrator" of this channel. Creator starts as channel's operator,
var/list/messages = list()
var/list/clients = list()
var/list/users = list()
var/direct = FALSE
var/password
@@ -19,25 +19,32 @@ var/global/ntnrc_uid = 0
operator = "NanoTrasen Information Technology Division" // assign a fake operator
..()
/datum/ntnet_conversation/proc/add_message(var/message, var/username, var/mob/user, var/reply_ref)
log_ntirc("[user.client.ckey]/([username]) : [message]", ckey=key_name(user), conversation=title)
/datum/ntnet_conversation/proc/process_message(var/datum/ntnet_message/message, var/update_ui = TRUE)
var/admin_log = message.format_admin_log()
if (admin_log)
log_ntirc("[message.user.client.ckey]/([message.nuser.username]): [admin_log]", ckey=key_name(message.user), conversation=title)
for(var/datum/computer_file/program/chatclient/C in clients)
if(C.program_state > PROGRAM_STATE_KILLED)
C.computer.output_message("<b>([get_title(C)]) <i>[username]</i>:</b> [message] (<a href='byond://?src=\ref[C];Reply=\ref[src]'>Reply</a>)", 0)
if(!C.silent && C.username != username && C.program_state == PROGRAM_STATE_BACKGROUND)
playsound(C.computer, 'sound/machines/twobeep.ogg', 50, 1)
C.computer.output_message("*[C.ringtone]*")
else if(C.username == username)
ntnet_global.add_log(message, C.computer.network_card, TRUE)
for(var/datum/ntnet_user/U in users)
for(var/datum/computer_file/program/chat_client/Cl in U.clients)
var/notification_text = message.format_chat_notification(src, Cl)
if(notification_text && Cl.can_receive_notification(message.client))
Cl.computer.output_message(notification_text, 0)
if(message.play_sound)
Cl.play_notification_sound(message.client)
message = "[worldtime2text()] [username]: [message]"
messages.Add(message)
trim_message_list()
var/ntnet_log = message.format_ntnet_log(src)
if(ntnet_log)
ntnet_global.add_log(ntnet_log, message.client.computer.network_card, TRUE)
/datum/ntnet_conversation/proc/add_status_message(var/message)
messages.Add("[worldtime2text()] -!- [message]")
trim_message_list()
var/chat_log = message.format_chat_log(src)
if(chat_log)
messages.Add(chat_log)
trim_message_list()
if(update_ui)
for(var/datum/ntnet_user/U in users)
for(var/datum/computer_file/program/chat_client/Cl)
SSvueui.check_uis_for_change(Cl)
/datum/ntnet_conversation/proc/trim_message_list()
if(messages.len <= 50)
@@ -47,89 +54,119 @@ var/global/ntnrc_uid = 0
if(messages.len <= 50)
return
/datum/ntnet_conversation/proc/add_client(var/datum/computer_file/program/chatclient/C)
if(!istype(C))
return
if (C in clients)
return
clients.Add(C)
// No operator, so we assume the channel was empty. Assign this user as operator.
if(!operator)
changeop(C)
for(var/datum/computer_file/program/chatclient/CC in clients)
if(CC.program_state > PROGRAM_STATE_KILLED && CC != C)
if(!direct)
CC.computer.output_message(FONT_SMALL("<b>([get_title(CC)]) <i>[C.username]</i> has entered the chat.</b>"), 0)
/// EXTERNAL PROCs
/datum/ntnet_conversation/proc/begin_direct(var/datum/computer_file/program/chatclient/CA, var/datum/computer_file/program/chatclient/CB)
if(!istype(CA) || !istype(CB))
return
direct = TRUE
clients.Add(CA)
clients.Add(CB)
add_status_message("[CA.username] has opened direct conversation.")
if(CB.program_state > PROGRAM_STATE_KILLED)
CB.computer.output_message(FONT_SMALL("<b>([get_title(CB)]) <i>[CA.username]</i> has opened direct conversation with you.</b>"), 0)
/datum/ntnet_conversation/proc/remove_client(var/datum/computer_file/program/chatclient/C)
if(!istype(C) || !(C in clients))
return
clients.Remove(C)
// Channel operator left, pick new operator
if(C == operator)
operator = null
if(clients.len)
var/datum/computer_file/program/chatclient/newop = pick(clients)
changeop(newop)
for(var/datum/computer_file/program/chatclient/CC in clients)
if(CC.program_state > PROGRAM_STATE_KILLED && CC != C)
CC.computer.output_message(FONT_SMALL("<b>([get_title(CC)]) <i>[C.username]</i> has left the chat.</b>"), 0)
/datum/ntnet_conversation/proc/changeop(var/datum/computer_file/program/chatclient/newop)
if(istype(newop))
operator = newop
add_status_message("Channel operator status transferred to [newop.username].")
/datum/ntnet_conversation/proc/change_title(var/newtitle, var/datum/computer_file/program/chatclient/client)
if(operator != client)
return 0 // Not Authorised
add_status_message("[client.username] has changed channel title from [get_title(client)] to [newtitle]")
for(var/datum/computer_file/program/chatclient/C in clients)
if(C.program_state > PROGRAM_STATE_KILLED && C != client)
C.computer.output_message(FONT_SMALL("([get_title(C)]) <i>[client.username]</i> has changed the channel title to <b>[newtitle]</b>."), 0)
title = newtitle
/datum/ntnet_conversation/proc/get_title(var/datum/computer_file/program/chatclient/cl = null)
/datum/ntnet_conversation/proc/get_title(var/datum/computer_file/program/chat_client/cl = null)
if(direct)
var/names = list()
for(var/datum/computer_file/program/chatclient/C in clients)
names += C.username
if(cl)
names -= cl.username
for(var/datum/ntnet_user/U in users)
names += U.username
if(istype(cl) && istype(cl.my_user))
names -= cl.my_user.username
return "\[DM] [english_list(names)]"
else
return title
/datum/ntnet_conversation/proc/get_dead_title()
if(direct)
var/names = list()
for(var/datum/computer_file/program/chatclient/C in clients)
names += C.username
return "\[DM] [english_list(names)]"
else
return title
/datum/ntnet_conversation/proc/can_see(var/datum/computer_file/program/chatclient/cl)
if(cl in clients)
return TRUE
/datum/ntnet_conversation/proc/can_see(var/datum/computer_file/program/chat_client/cl)
if(cl.netadmin_mode)
return TRUE
if(istype(cl.my_user))
if(cl.my_user in users)
return TRUE
else
for(var/datum/ntnet_user/user in users)
if(cl in user.clients)
return TRUE
if(!direct)
return TRUE
return FALSE
/datum/ntnet_conversation/proc/can_interact(var/datum/computer_file/program/chat_client/cl)
if(cl.netadmin_mode)
return TRUE
if(istype(cl.my_user))
if(cl.my_user in users)
return TRUE
else
for(var/datum/ntnet_user/user in users)
if(cl in user.clients)
return TRUE
return FALSE
/datum/ntnet_conversation/proc/can_manage(var/datum/computer_file/program/chat_client/cl)
if(cl.netadmin_mode)
return TRUE
if(cl.my_user == operator)
return TRUE
return FALSE
/datum/ntnet_conversation/proc/cl_send(var/datum/computer_file/program/chat_client/Cl, var/message, var/mob/user)
if(!istype(Cl) || !can_interact(Cl))
return
var/datum/ntnet_message/message/msg = new(Cl)
msg.message = message
msg.user = user
process_message(msg)
/datum/ntnet_conversation/proc/cl_join(var/datum/computer_file/program/chat_client/Cl)
if(!istype(Cl) || !can_see(Cl) || direct)
return
var/datum/ntnet_message/join/msg = new(Cl)
Cl.my_user.channels.Add(src)
users.Add(Cl.my_user)
if(!operator)
operator = Cl.my_user
var/datum/ntnet_message/new_op/msg2 = new(Cl)
process_message(msg, FALSE)
process_message(msg2)
return
process_message(msg)
/datum/ntnet_conversation/proc/cl_leave(var/datum/computer_file/program/chat_client/Cl)
if(!istype(Cl) || !istype(Cl.my_user) || !(Cl.my_user in users) || !can_interact(Cl) || direct)
return
var/datum/ntnet_message/leave/msg = new(Cl)
Cl.my_user.channels.Remove(src)
users.Remove(Cl.my_user)
if(operator == Cl.my_user)
if(users.len)
operator = pick(users)
var/datum/ntnet_message/new_op/msg2 = new()
msg2.nuser = operator
process_message(msg, FALSE)
process_message(msg2)
return
process_message(msg)
/datum/ntnet_conversation/proc/cl_change_title(var/datum/computer_file/program/chat_client/Cl, var/newTitle)
if(!istype(Cl) || !istype(Cl.my_user) || !can_manage(Cl) || direct)
return
var/datum/ntnet_message/new_title/msg = new(Cl)
msg.title = newTitle
process_message(msg)
title = newTitle
/datum/ntnet_conversation/proc/cl_set_password(var/datum/computer_file/program/chat_client/Cl, var/newPassword)
if(!istype(Cl) || !istype(Cl.my_user) || !can_manage(Cl) || direct)
return
if(newPassword)
password = newPassword
else
password = FALSE
/datum/ntnet_conversation/proc/cl_kick(var/datum/computer_file/program/chat_client/Cl, var/datum/ntnet_user/target)
if(!istype(Cl) || !istype(Cl.my_user) || !can_manage(Cl) || !(target in users) || direct)
return
var/datum/ntnet_message/kick/msg = new(Cl)
msg.target = target
target.channels.Remove(src)
users.Remove(target)
if(operator == target)
if(users.len)
operator = pick(users)
var/datum/ntnet_message/new_op/msg2 = new()
msg2.nuser = operator
process_message(msg, FALSE)
process_message(msg2)
return
process_message(msg)

View File

@@ -0,0 +1,96 @@
// Container for all essesal state for NTRC message while it's proccessed
/datum/ntnet_message
var/mob/user
var/datum/computer_file/program/chat_client/client
var/datum/ntnet_user/nuser
var/play_sound = FALSE
/datum/ntnet_message/New(var/datum/computer_file/program/chat_client/Pr = null, var/mob/user = null)
if(user)
src.user = user
if(Pr)
client = Pr
nuser = Pr.my_user
// Should be sanitized
/datum/ntnet_message/proc/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
return FALSE
/datum/ntnet_message/proc/format_admin_log(var/datum/ntnet_conversation/Conv)
return FALSE
// Should be sanitized
/datum/ntnet_message/proc/format_ntnet_log(var/datum/ntnet_conversation/Conv)
return FALSE
/datum/ntnet_message/proc/format_chat_log(var/datum/ntnet_conversation/Conv)
return FALSE
/datum/ntnet_message/message
play_sound = TRUE
var/message = ""
/datum/ntnet_message/message/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
. = "<b>([sanitize(Conv.get_title(Cl))]) <i>[nuser.username]</i>:</b> [sanitize(message)] (<a href='byond://?src=\ref[Cl]&Reply=\ref[Conv]'>Reply</a>)"
/datum/ntnet_message/message/format_chat_log(var/datum/ntnet_conversation/Conv)
. = "[worldtime2text()] [nuser.username]: [message]"
/datum/ntnet_message/message/format_admin_log(var/datum/ntnet_conversation/Conv)
. = message
/datum/ntnet_message/message/format_ntnet_log(var/datum/ntnet_conversation/Conv)
. = "[sanitize(Conv.get_title())] [nuser.username]: [sanitize(message)]"
/datum/ntnet_message/join/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
. = FONT_SMALL("<b>([sanitize(Conv.get_title(Cl))]) <i>[nuser.username]</i> has entered the chat.</b>")
/datum/ntnet_message/join/format_chat_log(var/datum/ntnet_conversation/Conv)
. = "[worldtime2text()] -!- [nuser.username] has entered the chat."
/datum/ntnet_message/leave/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
. = FONT_SMALL("<b>([sanitize(Conv.get_title(Cl))]) <i>[nuser.username]</i> has left the chat.</b>")
/datum/ntnet_message/leave/format_chat_log(var/datum/ntnet_conversation/Conv)
. = "[worldtime2text()] -!- [nuser.username] has left the chat."
/datum/ntnet_message/new_op/format_chat_log(var/datum/ntnet_conversation/Conv)
. = "[worldtime2text()] -!- [nuser.username] has become operator."
/datum/ntnet_message/new_title
var/title = ""
/datum/ntnet_message/new_title/format_chat_log(var/datum/ntnet_conversation/Conv)
. = "[worldtime2text()] -!- [nuser.username] has changed channel title from [Conv.get_title()] to [title]"
/datum/ntnet_message/new_title/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
. = FONT_SMALL("<b>([sanitize(Conv.get_title(Cl))]) <i>[nuser.username]</i> has changed the channel title to <i>[sanitize(title)].</i></b>")
/datum/ntnet_message/kick
var/datum/ntnet_user/target
/datum/ntnet_message/kick/format_chat_log(var/datum/ntnet_conversation/Conv)
. = "[worldtime2text()] -!- [nuser.username] has kicked [target.username] from conversation."
/datum/ntnet_message/kick/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
. = FONT_SMALL("<b>([sanitize(Conv.get_title(Cl))]) <i>[nuser.username]</i> has kicked <i>[target.username]</i> from conversation.</b>")
/datum/ntnet_message/direct/format_chat_log(var/datum/ntnet_conversation/Conv)
. = "[worldtime2text()] -!- [nuser.username] has opened direct conversation."
/datum/ntnet_message/direct/format_chat_notification(var/datum/ntnet_conversation/Conv, var/datum/computer_file/program/chat_client/Cl)
. = FONT_SMALL("<b>([sanitize(Conv.get_title(Cl))]) <i>[nuser.username]</i> has opened direct conversation with you.</b>")

View File

@@ -0,0 +1,28 @@
/datum/ntnet
var/list/chat_channels = list()
var/list/chat_clients = list()
var/list/chat_users = list()
/datum/ntnet/proc/begin_conversation(var/datum/computer_file/program/chat_client/Cl, var/title)
if(!istype(Cl) || !istype(Cl.my_user))
return
var/datum/ntnet_conversation/Conv = new(title)
Conv.cl_join(Cl)
return Conv
/datum/ntnet/proc/begin_direct(var/datum/computer_file/program/chat_client/Cl, var/datum/ntnet_user/target)
if(!istype(Cl) || !istype(Cl.my_user) || !istype(target) || istype(Cl.my_user.dm_channels[target], /datum/ntnet_conversation))
return
var/datum/ntnet_conversation/Conv = new()
Conv.direct = TRUE
Conv.users.Add(Cl.my_user)
Conv.users.Add(target)
target.dm_channels[Cl.my_user] = Conv
Cl.my_user.dm_channels[target] = Conv
var/datum/ntnet_message/direct/msg = new(Cl)
Conv.process_message(msg)

View File

@@ -0,0 +1,21 @@
/datum/ntnet_user
var/username
var/list/channels = list()
var/list/dm_channels = list()
var/list/clients = list()
/datum/ntnet_user/New()
. = ..()
ntnet_global.chat_users.Add(src)
/datum/ntnet_user/Destroy(force)
. = ..()
ntnet_global.chat_users.Remove(src)
/datum/ntnet_user/proc/generateUsernameIdCard(var/obj/item/card/id/card)
if(!card)
return "Unknown"
return "[card.registered_name] ([card.assignment])"
/datum/ntnet_user/proc/generateUsernameSilicon(var/mob/living/silicon/silicon)
return silicon.name

View File

@@ -11,8 +11,6 @@ var/global/datum/ntnet/ntnet_global = new()
var/list/available_software = list()
var/list/available_software_presets = list()
var/list/available_news = list()
var/list/chat_channels = list()
var/list/chat_clients = list()
var/list/fileservers = list()
var/list/datum/ntnet_account/users = list()
// Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly.