mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-26 10:02:28 +00:00
New chat client / messenger (#10654)
This commit is contained in:
@@ -2254,6 +2254,9 @@
|
||||
#include "code\modules\modular_computers\NTNet\NTNet.dm"
|
||||
#include "code\modules\modular_computers\NTNet\NTNet_relay.dm"
|
||||
#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm"
|
||||
#include "code\modules\modular_computers\NTNet\NTNRC\message.dm"
|
||||
#include "code\modules\modular_computers\NTNet\NTNRC\ntnrc.dm"
|
||||
#include "code\modules\modular_computers\NTNet\NTNRC\user.dm"
|
||||
#include "code\modules\multiz\_stubs.dm"
|
||||
#include "code\modules\multiz\basic.dm"
|
||||
#include "code\modules\multiz\hoist.dm"
|
||||
|
||||
@@ -201,6 +201,7 @@
|
||||
#define PROGRAM_ALL_REGULAR (PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_TABLET | PROGRAM_WRISTBOUND | PROGRAM_TELESCREEN)
|
||||
#define PROGRAM_ALL_HANDHELD (PROGRAM_TABLET | PROGRAM_WRISTBOUND)
|
||||
|
||||
#define PROGRAM_STATE_DISABLED -1
|
||||
#define PROGRAM_STATE_KILLED 0
|
||||
#define PROGRAM_STATE_BACKGROUND 1
|
||||
#define PROGRAM_STATE_ACTIVE 2
|
||||
|
||||
@@ -126,7 +126,7 @@ var/const/NO_EMAG_ACT = -50
|
||||
var/assignment = null //can be alt title or the actual job
|
||||
var/rank = null //actual job
|
||||
var/dorm = 0 // determines if this ID has claimed a dorm already
|
||||
var/chat_registered = FALSE // registration for NTNET chat
|
||||
var/datum/ntnet_user/chat_user
|
||||
|
||||
/obj/item/card/id/Destroy()
|
||||
mob = null
|
||||
@@ -151,6 +151,8 @@ var/const/NO_EMAG_ACT = -50
|
||||
|
||||
/obj/item/card/id/proc/update_name()
|
||||
name = "ID Card ([src.registered_name] ([src.assignment]))"
|
||||
if(istype(chat_user))
|
||||
chat_user.username = chat_user.generateUsernameIdCard(src)
|
||||
|
||||
/obj/item/card/id/proc/set_id_photo(var/mob/M)
|
||||
front = getFlatIcon(M, SOUTH)
|
||||
@@ -334,6 +336,11 @@ var/const/NO_EMAG_ACT = -50
|
||||
wear_over_suit = !wear_over_suit
|
||||
mob_icon_update()
|
||||
|
||||
/obj/item/card/id/proc/InitializeChatUser()
|
||||
if(!istype(chat_user))
|
||||
chat_user = new()
|
||||
chat_user.username = chat_user.generateUsernameIdCard(src)
|
||||
|
||||
/obj/item/card/id/silver
|
||||
icon_state = "silver"
|
||||
item_state = "silver_id"
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
// get_debug_type displays this
|
||||
else if(istext(value))
|
||||
debug_type = null // it's kinda annoying here; we can tell the type by the quotes
|
||||
vtext = "\"[value]\""
|
||||
vtext = "\"[html_encode(value)]\""
|
||||
else if(isicon(value))
|
||||
vtext = "[value]"
|
||||
else if(isfile(value))
|
||||
|
||||
@@ -95,6 +95,10 @@
|
||||
/mob/living/silicon/proc/SetName(pickedName as text)
|
||||
real_name = pickedName
|
||||
name = real_name
|
||||
if(istype(id_card))
|
||||
if(!istype(id_card.chat_user))
|
||||
id_card.InitializeChatUser()
|
||||
id_card.chat_user.username = real_name
|
||||
|
||||
/mob/living/silicon/proc/show_laws()
|
||||
return
|
||||
|
||||
@@ -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)
|
||||
var/ntnet_log = message.format_ntnet_log(src)
|
||||
if(ntnet_log)
|
||||
ntnet_global.add_log(ntnet_log, message.client.computer.network_card, TRUE)
|
||||
|
||||
var/chat_log = message.format_chat_log(src)
|
||||
if(chat_log)
|
||||
messages.Add(chat_log)
|
||||
trim_message_list()
|
||||
|
||||
/datum/ntnet_conversation/proc/add_status_message(var/message)
|
||||
messages.Add("[worldtime2text()] -!- [message]")
|
||||
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)
|
||||
96
code/modules/modular_computers/NTNet/NTNRC/message.dm
Normal file
96
code/modules/modular_computers/NTNet/NTNRC/message.dm
Normal 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>")
|
||||
28
code/modules/modular_computers/NTNet/NTNRC/ntnrc.dm
Normal file
28
code/modules/modular_computers/NTNet/NTNRC/ntnrc.dm
Normal 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)
|
||||
21
code/modules/modular_computers/NTNet/NTNRC/user.dm
Normal file
21
code/modules/modular_computers/NTNet/NTNRC/user.dm
Normal 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
|
||||
@@ -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.
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
/obj/item/modular_computer/Destroy()
|
||||
kill_program(TRUE)
|
||||
if(registered_id)
|
||||
registered_id.chat_registered = FALSE
|
||||
registered_id = null
|
||||
for(var/obj/item/computer_hardware/CH in src.get_all_components())
|
||||
uninstall_component(null, CH)
|
||||
@@ -197,7 +196,7 @@
|
||||
if(network_card)
|
||||
return network_card.get_signal(specific_action)
|
||||
else
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/obj/item/modular_computer/proc/add_log(var/text)
|
||||
if(!get_ntnet_status())
|
||||
@@ -366,6 +365,7 @@
|
||||
|
||||
|
||||
/obj/item/modular_computer/proc/enable_service(service, mob/user, var/datum/computer_file/program/S = null)
|
||||
. = FALSE
|
||||
if(!S)
|
||||
S = hard_drive?.find_file_by_name(service)
|
||||
|
||||
@@ -382,9 +382,11 @@
|
||||
return
|
||||
|
||||
// Start service
|
||||
if(S.service_activate())
|
||||
if(S.service_enable())
|
||||
enabled_services += S
|
||||
S.service_state = PROGRAM_STATE_ACTIVE
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/obj/item/modular_computer/proc/disable_service(service, mob/user, var/datum/computer_file/program/S = null)
|
||||
@@ -399,8 +401,8 @@
|
||||
enabled_services -= S
|
||||
|
||||
// Stop service
|
||||
S.service_deactivate()
|
||||
S.service_state = PROGRAM_STATE_KILLED
|
||||
S.service_disable()
|
||||
S.service_state = PROGRAM_STATE_DISABLED
|
||||
|
||||
/obj/item/modular_computer/proc/output_message(var/message, var/message_range)
|
||||
message_range += message_output_range
|
||||
@@ -434,12 +436,13 @@
|
||||
if(!istype(id))
|
||||
output_error("No ID card found!")
|
||||
return FALSE
|
||||
if(id.chat_registered)
|
||||
output_error("This card is already registered to another account!")
|
||||
return FALSE
|
||||
|
||||
id.chat_registered = TRUE
|
||||
registered_id = id
|
||||
|
||||
if(hard_drive)
|
||||
for(var/datum/computer_file/program/P in hard_drive.stored_files)
|
||||
P.event_registered()
|
||||
|
||||
output_notice("Registration successful!")
|
||||
playsound(get_turf(src), 'sound/machines/ping.ogg', 10, 0)
|
||||
return registered_id
|
||||
@@ -448,13 +451,12 @@
|
||||
if(!registered_id)
|
||||
return FALSE
|
||||
|
||||
registered_id.chat_registered = FALSE
|
||||
registered_id = null
|
||||
|
||||
if(hard_drive)
|
||||
var/datum/computer_file/program/P = hard_drive.find_file_by_name("ntnrc_client")
|
||||
for(var/datum/computer_file/program/P in hard_drive.stored_files)
|
||||
P.event_unregistered()
|
||||
|
||||
registered_id = null
|
||||
|
||||
output_message(SPAN_NOTICE("\The [src] beeps: \"Successfully unregistered ID!\""))
|
||||
playsound(get_turf(src), 'sound/machines/ping.ogg', 20, 0)
|
||||
return TRUE
|
||||
@@ -476,7 +478,6 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/modular_computer/proc/silence_notifications()
|
||||
for (var/datum/computer_file/program/P in hard_drive.stored_files)
|
||||
if (istype(P))
|
||||
P.event_silentmode()
|
||||
silent = !silent
|
||||
for (var/datum/computer_file/program/P in hard_drive.stored_files)
|
||||
P.event_silentmode()
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
visible_message(SPAN_WARNING("\The [src]'s screen flickers briefly and then goes dark."))
|
||||
if(active_program)
|
||||
active_program.event_powerfailure(FALSE)
|
||||
for(var/datum/computer_file/program/PRG in idle_threads)
|
||||
for(var/datum/computer_file/program/PRG in hard_drive.stored_files)
|
||||
if(PRG != active_program)
|
||||
PRG.event_powerfailure(TRUE)
|
||||
shutdown_computer(FALSE)
|
||||
power_has_failed = TRUE
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
name = "Modular Computer"
|
||||
desc = "A modular computer. You shouldn't see this."
|
||||
|
||||
var/lexical_name = "computer"
|
||||
var/enabled = FALSE // Whether the computer is turned on.
|
||||
var/screen_on = TRUE // Whether the computer is active/opened/it's screen is on.
|
||||
var/working = TRUE // Whether the computer is working.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/obj/item/modular_computer/handheld
|
||||
name = "tablet computer"
|
||||
lexical_name = "tablet"
|
||||
desc = "A portable device for your needs on the go."
|
||||
desc_info = "To deploy the charging cable on this device, either drag and drop it over a nearby APC, or click on the APC with the computer in hand."
|
||||
icon = 'icons/obj/modular_tablet.dmi'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/modular_computer/laptop
|
||||
anchored = TRUE
|
||||
name = "laptop computer"
|
||||
lexical_name = "laptop"
|
||||
desc = "A portable computer."
|
||||
desc_info = "You can alt-click the laptop while it's set down on surface to open it up and work with it. Left clicking while it is open will allow you to operate it."
|
||||
hardware_flag = PROGRAM_LAPTOP
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/obj/item/modular_computer/handheld/pda
|
||||
name = "PDA"
|
||||
lexical_name = "tablet"
|
||||
desc = "The latest in portable microcomputer solutions from Thinktronic Systems, LTD."
|
||||
icon = 'icons/obj/pda.dmi'
|
||||
icon_state = "pda"
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
/obj/item/modular_computer/silicon/install_default_programs()
|
||||
hard_drive.store_file(new /datum/computer_file/program/filemanager(src))
|
||||
hard_drive.store_file(new /datum/computer_file/program/ntnetdownload(src))
|
||||
hard_drive.store_file(new /datum/computer_file/program/chatclient(src))
|
||||
hard_drive.store_file(new /datum/computer_file/program/chat_client(src))
|
||||
hard_drive.remove_file(hard_drive.find_file_by_name("clientmanager"))
|
||||
addtimer(CALLBACK(src, .proc/register_chat), 1 SECOND)
|
||||
|
||||
@@ -62,24 +62,6 @@
|
||||
enable_computer(null, TRUE) // passing null because we don't want the UI to open
|
||||
minimize_program()
|
||||
|
||||
/obj/item/modular_computer/silicon/verb/send_pda_message()
|
||||
set category = "AI IM"
|
||||
set name = "Send Direct Message"
|
||||
set src in usr
|
||||
if (usr.stat == DEAD)
|
||||
to_chat(usr, "You can't send PDA messages because you are dead!")
|
||||
return
|
||||
var/datum/computer_file/program/chatclient/CL = hard_drive.find_file_by_name("ntnrc_client")
|
||||
if(!istype(CL))
|
||||
output_error("Chat client not installed!")
|
||||
return
|
||||
else if(CL.program_state == PROGRAM_STATE_KILLED)
|
||||
run_program("ntnrc_client")
|
||||
|
||||
CL.direct_message()
|
||||
if(CL.channel)
|
||||
CL.add_message(CL.send_message())
|
||||
|
||||
/obj/item/modular_computer/silicon/robot/drone/install_default_programs()
|
||||
hard_drive.store_file(new /datum/computer_file/program/filemanager(src))
|
||||
hard_drive.store_file(new /datum/computer_file/program/ntnetdownload(src))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/obj/item/modular_computer/handheld/wristbound
|
||||
name = "wristbound computer"
|
||||
lexical_name = "wristbound"
|
||||
desc = "A portable wristbound device for your needs on the go. Quite comfortable."
|
||||
desc_fluff = "A NanoTrasen design, this wristbound computer allows the user to quickly and safely access critical info, without taking their hands out of the equation."
|
||||
icon = 'icons/obj/modular_wristbound.dmi'
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
var/computer_emagged = FALSE // Set to TRUE if computer that's running us was emagged. Computer updates this every Process() tick
|
||||
var/ui_header // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images!
|
||||
var/color = "#FFFFFF" // The color of light the computer should emit when this program is open.
|
||||
var/service_state = PROGRAM_STATE_KILLED // PROGRAM_STATE_KILLED or PROGRAM_STATE_ACTIVE - specifies whether this program's service is running.
|
||||
var/service_state = PROGRAM_STATE_DISABLED // PROGRAM_STATE_KILLED or PROGRAM_STATE_ACTIVE - specifies whether this program's service is running.
|
||||
var/silent = FALSE
|
||||
|
||||
/datum/computer_file/program/New(var/obj/item/modular_computer/comp)
|
||||
@@ -196,27 +196,6 @@
|
||||
if(computer)
|
||||
return computer.get_header_data()
|
||||
|
||||
// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
|
||||
// When implementing new program based device, use this to run the program.
|
||||
/datum/computer_file/program/proc/run_program(var/mob/user)
|
||||
if(can_run(user, 1) || !requires_access_to_run)
|
||||
if(nanomodule_path)
|
||||
NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src)
|
||||
if(requires_ntnet && network_destination)
|
||||
generate_network_log("Connection opened to [network_destination].")
|
||||
program_state = PROGRAM_STATE_ACTIVE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
|
||||
/datum/computer_file/program/proc/kill_program(var/forced = 0)
|
||||
program_state = PROGRAM_STATE_KILLED
|
||||
if(network_destination)
|
||||
generate_network_log("Connection to [network_destination] closed.")
|
||||
if(NM)
|
||||
qdel(NM)
|
||||
NM = null
|
||||
return TRUE
|
||||
|
||||
// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
|
||||
// It returns 0 if it can't run or if NanoModule was used instead. I suggest using NanoModules where applicable.
|
||||
@@ -248,15 +227,6 @@
|
||||
else
|
||||
return -1
|
||||
|
||||
// Is called when program service is being activated
|
||||
// Returns 1 if service startup was sucessfull
|
||||
/datum/computer_file/program/proc/service_activate()
|
||||
return FALSE
|
||||
|
||||
// Is called when program service is being deactivated
|
||||
/datum/computer_file/program/proc/service_deactivate()
|
||||
return
|
||||
|
||||
/datum/computer_file/program/proc/message_dead(var/message)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && (M.client && M.client.prefs.toggles & CHAT_GHOSTEARS))
|
||||
|
||||
@@ -1,6 +1,47 @@
|
||||
// Events are sent to the program by the computer.
|
||||
// Always include a parent call when overriding an event.
|
||||
|
||||
// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
|
||||
// When implementing new program based device, use this to run the program.
|
||||
/datum/computer_file/program/proc/run_program(var/mob/user)
|
||||
if(can_run(user, 1) || !requires_access_to_run)
|
||||
if(nanomodule_path)
|
||||
NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src)
|
||||
if(requires_ntnet && network_destination)
|
||||
generate_network_log("Connection opened to [network_destination].")
|
||||
program_state = PROGRAM_STATE_ACTIVE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
|
||||
/datum/computer_file/program/proc/kill_program(var/forced = 0)
|
||||
program_state = PROGRAM_STATE_KILLED
|
||||
if(network_destination)
|
||||
generate_network_log("Connection to [network_destination] closed.")
|
||||
if(NM)
|
||||
qdel(NM)
|
||||
NM = null
|
||||
return TRUE
|
||||
|
||||
// Is called when program service is being activated
|
||||
// Returns 1 if service startup was sucessfull
|
||||
/datum/computer_file/program/proc/service_activate()
|
||||
return FALSE
|
||||
|
||||
// Is called when program service is being deactivated
|
||||
/datum/computer_file/program/proc/service_deactivate()
|
||||
return
|
||||
|
||||
// Is called when program service is being activated for first time.
|
||||
/datum/computer_file/program/proc/service_enable()
|
||||
return service_activate()
|
||||
|
||||
// Is called when program service is being deactivated without
|
||||
/datum/computer_file/program/proc/service_disable()
|
||||
return service_deactivate()
|
||||
|
||||
/// SECOND ORDER EVENTS
|
||||
|
||||
// Called when the ID card is removed from computer. ID is removed AFTER this proc.
|
||||
/datum/computer_file/program/proc/event_idremoved(var/background)
|
||||
return
|
||||
@@ -9,11 +50,16 @@
|
||||
return
|
||||
|
||||
// Called when an ID is unregistered from the device.
|
||||
/datum/computer_file/program/proc/event_unregistered(var/background)
|
||||
/datum/computer_file/program/proc/event_unregistered()
|
||||
return
|
||||
|
||||
// Called when an ID is unregistered from the device.
|
||||
/datum/computer_file/program/proc/event_registered()
|
||||
return
|
||||
|
||||
// Called when the computer fails due to power loss. Override when program wants to specifically react to power loss.
|
||||
/datum/computer_file/program/proc/event_powerfailure(var/background)
|
||||
if(program_state > PROGRAM_STATE_KILLED)
|
||||
kill_program(TRUE)
|
||||
|
||||
// Called when the network connectivity fails. Computer does necessary checks and only calls this when requires_ntnet_feature and similar variables are not met.
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/power_monitor(comp),
|
||||
new /datum/computer_file/program/alarm_monitor(comp),
|
||||
@@ -56,7 +56,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/power_monitor(comp),
|
||||
new /datum/computer_file/program/alarm_monitor(comp),
|
||||
@@ -81,7 +81,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/comm(comp, FALSE),
|
||||
new /datum/computer_file/program/game/sudoku(comp),
|
||||
@@ -108,7 +108,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/suit_sensors(comp),
|
||||
new /datum/computer_file/program/records/medical(comp),
|
||||
@@ -130,7 +130,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/comm(comp, FALSE),
|
||||
new /datum/computer_file/program/suit_sensors(comp),
|
||||
@@ -155,7 +155,7 @@
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/ntnetmonitor(comp),
|
||||
new /datum/computer_file/program/aidiag(comp),
|
||||
@@ -178,7 +178,7 @@
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/ntnetmonitor(comp),
|
||||
new /datum/computer_file/program/aidiag(comp),
|
||||
@@ -201,7 +201,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/comm(comp, FALSE),
|
||||
new /datum/computer_file/program/ntnetmonitor(comp),
|
||||
@@ -225,7 +225,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/card_mod(comp),
|
||||
new /datum/computer_file/program/comm(comp, FALSE),
|
||||
@@ -246,7 +246,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/civilian/cargocontrol(comp),
|
||||
new /datum/computer_file/program/card_mod(comp),
|
||||
@@ -269,7 +269,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/card_mod(comp),
|
||||
new /datum/computer_file/program/comm(comp, FALSE),
|
||||
new /datum/computer_file/program/camera_monitor(comp),
|
||||
@@ -317,7 +317,7 @@
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/camera_monitor(comp),
|
||||
new /datum/computer_file/program/comm(comp),
|
||||
@@ -341,7 +341,7 @@
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/camera_monitor(comp),
|
||||
new /datum/computer_file/program/comm(comp),
|
||||
@@ -367,7 +367,7 @@
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/camera_monitor(comp),
|
||||
new /datum/computer_file/program/digitalwarrant(comp),
|
||||
new /datum/computer_file/program/penal_mechs(comp),
|
||||
@@ -391,7 +391,7 @@
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/comm(comp, FALSE),
|
||||
new /datum/computer_file/program/camera_monitor(comp),
|
||||
@@ -415,7 +415,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/game/arcade(comp),
|
||||
new /datum/computer_file/program/game/sudoku(comp),
|
||||
@@ -435,7 +435,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/civilian/janitor(comp),
|
||||
new /datum/computer_file/program/game/arcade(comp),
|
||||
@@ -468,7 +468,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargocontrol(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/civilian/cargodelivery(comp),
|
||||
@@ -488,7 +488,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargodelivery(comp),
|
||||
new /datum/computer_file/program/ntsl2_interpreter(comp)
|
||||
)
|
||||
@@ -506,7 +506,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/game/sudoku(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/records/employment(comp),
|
||||
@@ -525,7 +525,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/civilian/cargoorder(comp),
|
||||
new /datum/computer_file/program/camera_monitor(comp),
|
||||
new /datum/computer_file/program/alarm_monitor(comp),
|
||||
@@ -594,7 +594,7 @@
|
||||
new /datum/computer_file/program/filemanager(comp),
|
||||
new /datum/computer_file/program/manifest(comp),
|
||||
new /datum/computer_file/program/newsbrowser(comp),
|
||||
new /datum/computer_file/program/chatclient(comp),
|
||||
new /datum/computer_file/program/chat_client(comp),
|
||||
new /datum/computer_file/program/merchant(comp)
|
||||
)
|
||||
return _prg_list
|
||||
|
||||
@@ -1,381 +1,253 @@
|
||||
/datum/computer_file/program/chatclient
|
||||
/datum/computer_file/program/chat_client
|
||||
filename = "ntnrc_client"
|
||||
filedesc = "Chat Client"
|
||||
program_icon_state = "command"
|
||||
extended_desc = "This program allows communication over the NTNRC network."
|
||||
extended_desc = "This program allows communication over the NTRC network."
|
||||
size = 2
|
||||
requires_ntnet = TRUE
|
||||
requires_ntnet_feature = NTNET_COMMUNICATION
|
||||
network_destination = "NTNRC server"
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
program_type = PROGRAM_TYPE_ALL
|
||||
network_destination = "NTRC server"
|
||||
available_on_ntnet = TRUE
|
||||
nanomodule_path = /datum/nano_module/program/computer_chatclient
|
||||
color = LIGHT_COLOR_GREEN
|
||||
silent = FALSE
|
||||
|
||||
var/last_message // Used to generate the toolbar icon
|
||||
var/username
|
||||
var/datum/ntnet_conversation/channel
|
||||
var/operator_mode = FALSE // Channel operator mode
|
||||
var/datum/ntnet_user/my_user
|
||||
var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords)
|
||||
var/set_offline = FALSE // appear "invisible"
|
||||
var/list/directmessagechannels = list()
|
||||
|
||||
var/ringtone = "beep"
|
||||
var/syndi_auth = FALSE
|
||||
|
||||
/datum/computer_file/program/chatclient/New(var/obj/item/modular_computer/comp)
|
||||
..(comp)
|
||||
if(!comp)
|
||||
return
|
||||
|
||||
/datum/computer_file/program/chatclient/Destroy()
|
||||
ntnet_global.chat_clients -= src
|
||||
/datum/computer_file/program/chat_client/Destroy()
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/chatclient/Topic(href, href_list)
|
||||
/datum/computer_file/program/chat_client/proc/can_receive_notification(var/datum/computer_file/program/chat_client/from)
|
||||
return ((program_state > PROGRAM_STATE_KILLED || service_state > PROGRAM_STATE_KILLED) && from != src && get_signal(NTNET_COMMUNICATION))
|
||||
|
||||
/datum/computer_file/program/chat_client/proc/play_notification_sound(var/datum/computer_file/program/chat_client/from)
|
||||
if(!silent && src != from && program_state == PROGRAM_STATE_BACKGROUND)
|
||||
playsound(computer, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
computer.output_message("[icon2html(computer, world)] *[ringtone]*", 2)
|
||||
|
||||
/datum/computer_file/program/chat_client/Topic(href, href_list)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(href_list["PRG_toggleringer"])
|
||||
. = TRUE
|
||||
silent = !silent
|
||||
|
||||
if(href_list["PRG_setringtone"])
|
||||
. = TRUE
|
||||
var/t = input(usr, "Please enter new ringtone", filedesc, ringtone) as text|null
|
||||
if(!usr.Adjacent(computer) || !t)
|
||||
return
|
||||
if(href_list["ringtone"])
|
||||
var/newRingtone = href_list["ringtone"]
|
||||
var/obj/item/device/uplink/hidden/H = computer.hidden_uplink
|
||||
if(istype(H) && H.check_trigger(usr, lowertext(t), lowertext(H.pda_code)))
|
||||
if(istype(H) && H.check_trigger(usr, lowertext(newRingtone), lowertext(H.pda_code)))
|
||||
to_chat(usr, SPAN_NOTICE("\The [computer] softly beeps."))
|
||||
syndi_auth = TRUE
|
||||
SSnanoui.close_uis(NM)
|
||||
SSvueui.close_uis(src)
|
||||
else
|
||||
t = sanitize(t, 20)
|
||||
ringtone = t
|
||||
newRingtone = sanitize(newRingtone, 20)
|
||||
ringtone = newRingtone
|
||||
SSvueui.check_uis_for_change(src)
|
||||
|
||||
if(href_list["PRG_speak"])
|
||||
. = TRUE
|
||||
add_message(send_message())
|
||||
|
||||
if(href_list["Reply"])
|
||||
. = TRUE
|
||||
var/datum/ntnet_conversation/C = locate(href_list["Reply"]) in ntnet_global.chat_channels
|
||||
if(!istype(C))
|
||||
to_chat(usr, SPAN_WARNING("The target channel couldn't be found and has likely been deleted!"))
|
||||
// User only commands
|
||||
if(!istype(my_user))
|
||||
return
|
||||
var/message = send_message()
|
||||
if(!(C in ntnet_global.chat_channels))
|
||||
to_chat(usr, SPAN_WARNING("The target channel couldn't be found and has likely been deleted!"))
|
||||
// Following actions require signal
|
||||
if(!get_signal(NTNET_COMMUNICATION))
|
||||
return
|
||||
add_message(message, C)
|
||||
|
||||
if(href_list["PRG_joinchannel"])
|
||||
. = TRUE
|
||||
var/datum/ntnet_conversation/C
|
||||
for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels)
|
||||
if(chan.id == text2num(href_list["PRG_joinchannel"]))
|
||||
C = chan
|
||||
break
|
||||
|
||||
if(!C)
|
||||
return TRUE
|
||||
|
||||
if(netadmin_mode)
|
||||
channel = C // Bypasses normal leave/join and passwords. Technically makes the user invisible to others.
|
||||
return TRUE
|
||||
|
||||
if(C.password)
|
||||
if(href_list["send"])
|
||||
var/mob/living/user = usr
|
||||
var/password = sanitize(input(user, "Access Denied. Enter password:"))
|
||||
if(C?.password == password)
|
||||
C.add_client(src)
|
||||
channel = C
|
||||
return TRUE
|
||||
C.add_client(src)
|
||||
message_dead(FONT_SMALL("<b>([C.get_dead_title()]) A new client ([username]) has entered the chat.</b>"))
|
||||
channel = C
|
||||
if(href_list["PRG_leavechannel"])
|
||||
. = TRUE
|
||||
if(channel && !channel.direct)
|
||||
channel.remove_client(src)
|
||||
message_dead(FONT_SMALL(FONT_SMALL("<b>([channel.get_dead_title()]) A client ([username]) has left the chat.</b>")))
|
||||
channel = null
|
||||
if(href_list["PRG_backtomain"])
|
||||
. = TRUE
|
||||
channel = null
|
||||
if(href_list["PRG_newchannel"])
|
||||
. = TRUE
|
||||
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(channel_title)
|
||||
C.add_client(src)
|
||||
C.operator = src
|
||||
channel = C
|
||||
message_dead(FONT_SMALL("<b>([channel.get_dead_title()]) A new channel has been made by [username].</b>"))
|
||||
if(href_list["PRG_toggleadmin"])
|
||||
. = TRUE
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["send"]["target"])
|
||||
var/message = href_list["send"]["message"]
|
||||
if(istype(conv) && message)
|
||||
if(ishuman(user))
|
||||
user.visible_message("[SPAN_BOLD("\The [user]")] taps on [user.get_pronoun("his")] [computer.lexical_name]'s screen.")
|
||||
conv.cl_send(src, message, user)
|
||||
if(href_list["join"])
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["join"]["target"])
|
||||
var/password = href_list["join"]["password"]
|
||||
if(istype(conv))
|
||||
if(conv.password)
|
||||
if(conv.password == password)
|
||||
conv.cl_join(src)
|
||||
else
|
||||
// How do I alert of password invalid?
|
||||
else
|
||||
conv.cl_join(src)
|
||||
if(href_list["leave"])
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["leave"])
|
||||
if(istype(conv))
|
||||
conv.cl_leave(src)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
if(href_list["kick"])
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["kick"]["target"])
|
||||
var/datum/ntnet_user/tUser = locate(href_list["kick"]["user"])
|
||||
if(istype(conv) && istype(tUser))
|
||||
conv.cl_kick(src, tUser)
|
||||
if(href_list["set_password"])
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["set_password"]["target"])
|
||||
var/password = href_list["set_password"]["password"]
|
||||
if(istype(conv))
|
||||
conv.cl_set_password(src, password)
|
||||
if(href_list["change_title"])
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["change_title"]["target"])
|
||||
var/newTitle = href_list["change_title"]["title"]
|
||||
if(istype(conv))
|
||||
conv.cl_change_title(src, newTitle)
|
||||
if(href_list["new_channel"])
|
||||
ntnet_global.begin_conversation(src, sanitize(href_list["new_channel"]))
|
||||
if(href_list["delete"])
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["delete"])
|
||||
if(istype(conv) && conv.can_manage(src))
|
||||
ntnet_global.chat_channels.Remove(conv)
|
||||
qdel(conv)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
if(href_list["direct"])
|
||||
var/datum/ntnet_user/tUser = locate(href_list["direct"])
|
||||
ntnet_global.begin_direct(src, tUser)
|
||||
|
||||
if(href_list["toggleadmin"])
|
||||
if(netadmin_mode)
|
||||
netadmin_mode = FALSE
|
||||
if(channel)
|
||||
channel.remove_client(src) // We shouldn't be in channel's user list, but just in case...
|
||||
channel = null
|
||||
return TRUE
|
||||
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
|
||||
var/mob/living/user = usr
|
||||
if(can_run(user, TRUE, access_network))
|
||||
netadmin_mode = TRUE
|
||||
if(href_list["PRG_changename"])
|
||||
. = TRUE
|
||||
var/mob/living/user = usr
|
||||
var/new_name = sanitize(input(user, "Enter new nickname or leave blank to cancel:"))
|
||||
if(!new_name)
|
||||
return TRUE
|
||||
var/comp_name = ckey(new_name)
|
||||
for(var/cl in ntnet_global.chat_clients)
|
||||
var/datum/computer_file/program/chatclient/C = cl
|
||||
if(ckey(C.username) == comp_name || comp_name == "cancel")
|
||||
alert(user, "This nickname is already taken.")
|
||||
return TRUE
|
||||
for(var/datum/ntnet_conversation/channel in ntnet_global.chat_channels)
|
||||
if(src in channel.clients)
|
||||
channel.add_status_message("[username] is now known as [new_name].")
|
||||
username = new_name
|
||||
if(href_list["PRG_savelog"])
|
||||
. = TRUE
|
||||
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 TRUE
|
||||
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.filename = logname
|
||||
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_with("Var computer is null!")
|
||||
return TRUE
|
||||
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"])
|
||||
. = TRUE
|
||||
if(!operator_mode || !channel)
|
||||
return TRUE
|
||||
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"])
|
||||
. = TRUE
|
||||
if(channel && ((channel.operator == src) || netadmin_mode))
|
||||
qdel(channel)
|
||||
channel = null
|
||||
if(href_list["PRG_setpassword"])
|
||||
. = TRUE
|
||||
if(!channel || ((channel.operator != src) && !netadmin_mode))
|
||||
return TRUE
|
||||
|
||||
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 TRUE
|
||||
|
||||
if(newpassword == "nopassword")
|
||||
channel.password = ""
|
||||
else
|
||||
channel.password = newpassword
|
||||
if(href_list["PRG_directmessage"])
|
||||
. = TRUE
|
||||
direct_message(usr)
|
||||
|
||||
/datum/computer_file/program/chatclient/proc/send_message()
|
||||
SSvueui.check_uis_for_change(src)
|
||||
if(href_list["Reply"])
|
||||
var/mob/living/user = usr
|
||||
var/datum/ntnet_conversation/conv = locate(href_list["Reply"])
|
||||
var/message = input(user, "Enter message or leave blank to cancel: ")
|
||||
if(istype(conv) && message)
|
||||
if(ishuman(user))
|
||||
user.visible_message("[SPAN_BOLD("\The [user]")] taps on [user.get_pronoun("his")] computer's screen.")
|
||||
var/message = sanitize(input(user, "Enter a message to send: ") as null|text)
|
||||
if(!message)
|
||||
return
|
||||
return message
|
||||
user.visible_message("[SPAN_BOLD("\The [user]")] taps on [user.get_pronoun("his")] [computer.lexical_name]'s screen.")
|
||||
conv.cl_send(src, message, user)
|
||||
|
||||
/datum/computer_file/program/chatclient/proc/add_message(var/message, var/datum/ntnet_conversation/specific_channel)
|
||||
if(!message)
|
||||
return
|
||||
var/datum/ntnet_conversation/sent_channel
|
||||
if(specific_channel)
|
||||
sent_channel = specific_channel
|
||||
|
||||
/datum/computer_file/program/chat_client/service_activate()
|
||||
. = ..()
|
||||
if(istype(my_user) && get_signal(NTNET_COMMUNICATION))
|
||||
activate_chat_client()
|
||||
return TRUE
|
||||
else
|
||||
sent_channel = channel
|
||||
if(!sent_channel) // panikk - geeves
|
||||
return
|
||||
sent_channel.add_message(message, username, usr)
|
||||
message_dead(FONT_SMALL("<b>([sent_channel.get_dead_title()]) [username]:</b> [message]"))
|
||||
|
||||
/datum/computer_file/program/chatclient/proc/direct_message(var/mob/user)
|
||||
var/clients = list()
|
||||
var/names = list()
|
||||
for(var/cl in ntnet_global.chat_clients - src)
|
||||
var/datum/computer_file/program/chatclient/C = cl
|
||||
if(C.set_offline)
|
||||
continue
|
||||
clients[C.username] = C
|
||||
names += C.username
|
||||
if(!length(names))
|
||||
to_chat(user, SPAN_WARNING("You are the only user with an active account!"))
|
||||
return
|
||||
var/picked = input(user, "Select with whom you would like to start a conversation.") as null|anything in names
|
||||
if(!picked)
|
||||
return
|
||||
var/datum/computer_file/program/chatclient/otherClient = clients[picked]
|
||||
if(picked)
|
||||
if(directmessagechannels[otherClient])
|
||||
channel = directmessagechannels[otherClient]
|
||||
return
|
||||
var/datum/ntnet_conversation/C = new /datum/ntnet_conversation("", TRUE)
|
||||
C.begin_direct(src, otherClient)
|
||||
channel = C
|
||||
directmessagechannels[otherClient] = C
|
||||
otherClient.directmessagechannels[src] = C
|
||||
|
||||
|
||||
/datum/computer_file/program/chatclient/process_tick()
|
||||
..()
|
||||
if(program_state != PROGRAM_STATE_KILLED)
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
if(channel)
|
||||
// Remember the last message. If there is no message in the channel remember null.
|
||||
if(length(channel.messages) > 1) // len - 1 = 0 and that's array out of bounds
|
||||
last_message = channel.messages[channel.messages.len - 1]
|
||||
else
|
||||
last_message = null
|
||||
else
|
||||
last_message = null
|
||||
return 1
|
||||
if(channel?.messages?.len)
|
||||
ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif"
|
||||
else
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
|
||||
/datum/computer_file/program/chatclient/kill_program(var/forced = FALSE)
|
||||
if(!forced)
|
||||
var/confirm = alert("Are you sure you want to close the NTNRC Client? You will not be reachable via messaging if you do so.", "Close?", "Yes", "No")
|
||||
if((confirm != "Yes") || (CanUseTopic(usr) != STATUS_INTERACTIVE))
|
||||
return FALSE
|
||||
|
||||
ntnet_global.chat_clients -= src
|
||||
/datum/computer_file/program/chat_client/service_deactivate()
|
||||
. = ..()
|
||||
deactivate_chat_client()
|
||||
|
||||
channel = null
|
||||
..(forced)
|
||||
return TRUE
|
||||
/datum/computer_file/program/chat_client/process_tick()
|
||||
. = ..()
|
||||
|
||||
/datum/computer_file/program/chatclient/run_program(var/mob/user)
|
||||
if(!computer)
|
||||
return
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
if((!computer.registered_id && !computer.register_account(src)))
|
||||
return
|
||||
if(!(src in ntnet_global.chat_clients))
|
||||
ntnet_global.chat_clients += src
|
||||
if(!username)
|
||||
username = username_from_id()
|
||||
return ..(user)
|
||||
/datum/computer_file/program/chat_client/kill_program(var/forced = FALSE)
|
||||
return ..(forced)
|
||||
|
||||
/datum/computer_file/program/chatclient/proc/username_from_id()
|
||||
/datum/computer_file/program/chat_client/run_program(var/mob/user)
|
||||
if(!istype(my_user))
|
||||
if(istype(computer, /obj/item/modular_computer/silicon))
|
||||
var/obj/item/modular_computer/silicon/SC = computer
|
||||
return SC.computer_host.name
|
||||
if(!computer.registered_id)
|
||||
return "Unknown"
|
||||
|
||||
return "[computer.registered_id.registered_name] ([computer.registered_id.assignment])"
|
||||
|
||||
/datum/computer_file/program/chatclient/event_unregistered()
|
||||
..()
|
||||
computer.set_autorun(filename)
|
||||
ntnet_global.chat_clients -= src
|
||||
kill_program(TRUE)
|
||||
|
||||
/datum/computer_file/program/chatclient/event_silentmode()
|
||||
..()
|
||||
if(computer.silent != silent)
|
||||
silent = computer.silent
|
||||
/datum/nano_module/program/computer_chatclient
|
||||
name = "Chat Client"
|
||||
|
||||
/datum/nano_module/program/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)
|
||||
var/mob/living/silicon/S = SC.computer_host
|
||||
S.id_card.InitializeChatUser()
|
||||
my_user = S.id_card.chat_user
|
||||
else
|
||||
if((!computer.registered_id && !computer.register_account(src)))
|
||||
return
|
||||
if(service_state == PROGRAM_STATE_DISABLED)
|
||||
if(!computer.enable_service(null, user, src))
|
||||
return
|
||||
return ..(user)
|
||||
|
||||
var/datum/computer_file/program/chatclient/C = program
|
||||
/datum/computer_file/program/chat_client/event_registered()
|
||||
. = ..()
|
||||
computer.registered_id.InitializeChatUser()
|
||||
my_user = computer.registered_id.chat_user
|
||||
if(service_state > PROGRAM_STATE_KILLED)
|
||||
activate_chat_client()
|
||||
|
||||
if(C.computer.hidden_uplink && C.syndi_auth)
|
||||
if(alert(user, "Resume or close and secure?", name, "Resume", "Close") == "Resume")
|
||||
C.computer.hidden_uplink.trigger(user)
|
||||
|
||||
/datum/computer_file/program/chat_client/event_unregistered()
|
||||
. = ..()
|
||||
if(service_state > PROGRAM_STATE_KILLED)
|
||||
deactivate_chat_client()
|
||||
my_user = null
|
||||
|
||||
/datum/computer_file/program/chat_client/event_silentmode()
|
||||
. = ..()
|
||||
silent = computer.silent
|
||||
|
||||
/datum/computer_file/program/chat_client/ui_interact(var/mob/user)
|
||||
if(computer.hidden_uplink && syndi_auth)
|
||||
if(alert(user, "Resume or close and secure?", filedesc, "Resume", "Close") == "Resume")
|
||||
computer.hidden_uplink.trigger(user)
|
||||
return
|
||||
else
|
||||
C.syndi_auth = FALSE
|
||||
syndi_auth = FALSE
|
||||
|
||||
var/list/data = list()
|
||||
if(program)
|
||||
data = list("_PC" = program.get_header_data())
|
||||
|
||||
if(!istype(C))
|
||||
return
|
||||
|
||||
data["adminmode"] = C.netadmin_mode
|
||||
if(C.channel)
|
||||
data["title"] = C.channel.get_title(C)
|
||||
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,
|
||||
"active" = cl.program_state > PROGRAM_STATE_KILLED
|
||||
)))
|
||||
data["clients"] = clients
|
||||
C.operator_mode = (C.channel.operator == C) ? 1 : 0
|
||||
data["is_operator"] = C.operator_mode || C.netadmin_mode
|
||||
data["is_direct"] = C.channel.direct
|
||||
else // Channel selection screen
|
||||
var/list/all_channels[0]
|
||||
for(var/datum/ntnet_conversation/conv in ntnet_global.chat_channels)
|
||||
if(conv && conv.title && conv.can_see(program))
|
||||
all_channels.Add(list(list(
|
||||
"chan" = conv.get_title(C),
|
||||
"id" = conv.id,
|
||||
"con" = (program in conv.clients)
|
||||
)))
|
||||
data["all_channels"] = all_channels
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
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 = new /datum/vueui/modularcomputer(user, src, "mcomputer-chat-index", 600, 500, capitalize(filedesc))
|
||||
ui.open()
|
||||
ui.set_auto_update(TRUE)
|
||||
|
||||
/datum/computer_file/program/chat_client/vueui_transfer(oldobj)
|
||||
SSvueui.transfer_uis(oldobj, src, "mcomputer-chat-index", 600, 500, capitalize(filedesc))
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/chat_client/vueui_data_change(var/list/data, var/mob/user, var/datum/vueui/ui)
|
||||
. = ..()
|
||||
data = . || data || list()
|
||||
// Gather data for computer header
|
||||
var/headerdata = get_header_data(data["_PC"])
|
||||
if(headerdata)
|
||||
data["_PC"] = headerdata
|
||||
. = data
|
||||
|
||||
data["service"] = service_state > PROGRAM_STATE_KILLED
|
||||
data["registered"] = istype(my_user)
|
||||
data["signal"] = get_signal(NTNET_COMMUNICATION)
|
||||
data["ringtone"] = ringtone
|
||||
data["netadmin_mode"] = netadmin_mode
|
||||
data["can_netadmin_mode"] = can_run(user, FALSE, access_network)
|
||||
|
||||
if(data["registered"] && data["service"] && data["signal"])
|
||||
data["channels"] = list()
|
||||
for(var/c in ntnet_global.chat_channels)
|
||||
var/datum/ntnet_conversation/Channel = c
|
||||
if(istype(Channel) && Channel.can_see(src))
|
||||
var/ref = ref(Channel)
|
||||
var/can_interact = Channel.can_interact(src)
|
||||
var/can_manage = Channel.can_manage(src)
|
||||
data["channels"][ref] = list(
|
||||
"title" = Channel.get_title(src),
|
||||
"direct" = Channel.direct,
|
||||
"password" = !!Channel.password,
|
||||
"can_interact" = can_interact,
|
||||
"can_manage" = can_manage
|
||||
)
|
||||
if(can_interact)
|
||||
data["channels"][ref]["msg"] = Channel.messages
|
||||
data["channels"][ref]["users"] = list()
|
||||
for(var/datum/ntnet_user/U in Channel.users)
|
||||
var/uref = ref(U)
|
||||
data["channels"][ref]["users"][uref] = U.username
|
||||
data["users"] = list()
|
||||
for(var/u in ntnet_global.chat_users)
|
||||
var/datum/ntnet_user/nUser = u
|
||||
if(nUser != my_user)
|
||||
var/ref = ref(nUser)
|
||||
data["users"][ref] = nUser.username
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/chat_client/proc/activate_chat_client()
|
||||
if(!istype(my_user))
|
||||
return
|
||||
if(!(src in my_user.clients))
|
||||
my_user.clients.Add(src)
|
||||
if(!(src in ntnet_global.chat_clients))
|
||||
ntnet_global.chat_clients.Add(src)
|
||||
|
||||
/datum/computer_file/program/chat_client/proc/deactivate_chat_client()
|
||||
if(!istype(my_user))
|
||||
return
|
||||
if(src in my_user.clients)
|
||||
my_user.clients.Remove(src)
|
||||
if(src in ntnet_global.chat_clients)
|
||||
ntnet_global.chat_clients.Remove(src)
|
||||
@@ -70,7 +70,7 @@
|
||||
computer.enrolled = 2 // private devices
|
||||
computer.hard_drive.store_file(new /datum/computer_file/program/filemanager(computer))
|
||||
computer.hard_drive.store_file(new /datum/computer_file/program/ntnetdownload(computer))
|
||||
computer.hard_drive.store_file(new /datum/computer_file/program/chatclient(computer))
|
||||
computer.hard_drive.store_file(new /datum/computer_file/program/chat_client(computer))
|
||||
return TRUE
|
||||
|
||||
//Set´s up the programs from the preset
|
||||
|
||||
6
html/changelogs/chat meesenger.yml
Normal file
6
html/changelogs/chat meesenger.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
author: Karolis2011
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Modular computer chat client UI and internals been revamped."
|
||||
- tweak: "Newest chat messages are now at the top instead of bottom of chat window."
|
||||
- rscadd: "Now you can use chat client simultaneously on multiple devices."
|
||||
@@ -1,84 +0,0 @@
|
||||
{{if data.adminmode}}
|
||||
<h1>ADMINISTRATIVE MODE</h1>
|
||||
{{/if}}
|
||||
|
||||
{{if data.title}}
|
||||
<div class="itemLabel">
|
||||
Current channel:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.title}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Operator access:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.is_operator}}
|
||||
<b>Enabled</b>
|
||||
{{else}}
|
||||
<b>Disabled</b>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Chat Controls:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<table>
|
||||
<tr><td>{{:helper.link("Return to channel list", null, {'PRG_backtomain' : 1})}}
|
||||
<tr><td>{{:helper.link("Direct message", null, {'PRG_directmessage' : 1})}}
|
||||
<tr><td>{{:helper.link("Change nickname", null, {'PRG_changename' : 1})}}
|
||||
<tr><td>{{:helper.link("Toggle administration mode", null, {'PRG_toggleadmin' : 1})}}
|
||||
{{if !data.is_direct}}
|
||||
<tr><td>{{:helper.link("Leave channel", null, {'PRG_leavechannel' : 1})}}
|
||||
{{/if}}
|
||||
<tr><td>{{:helper.link("Save log to local drive", null, {'PRG_savelog' : 1})}}
|
||||
{{if data.is_operator}}
|
||||
<tr><td>{{:helper.link("Rename channel", null, {'PRG_renamechannel' : 1})}}
|
||||
<tr><td>{{:helper.link("Set password", null, {'PRG_setpassword' : 1})}}
|
||||
<tr><td>{{:helper.link("Delete channel", null, {'PRG_deletechannel' : 1})}}
|
||||
{{/if}}
|
||||
</table>
|
||||
</div>
|
||||
<b>Connected Users</b><br>
|
||||
{{for data.clients}}
|
||||
{{:value.name}}
|
||||
{{if !value.active}}
|
||||
<i>(Away)</i>
|
||||
{{/if}}
|
||||
<br>
|
||||
{{/for}}
|
||||
<b>Chat Window</b>
|
||||
<div class="statusDisplay" style="overflow: auto;">
|
||||
<div class="item">
|
||||
<div class="itemContent" style="width: 100%;">
|
||||
{{for data.messages}}
|
||||
{{:value.msg}}<br>
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Messaging:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<table>
|
||||
<tr><td>{{:helper.link("Send message", null, {'PRG_speak' : 1})}}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
{{else}}
|
||||
<b>Controls:</b>
|
||||
<table>
|
||||
<tr><td>{{:helper.link("Direct message", null, {'PRG_directmessage' : 1})}}
|
||||
<tr><td>{{:helper.link("Change nickname", null, {'PRG_changename' : 1})}}
|
||||
<tr><td>{{:helper.link("New Channel", null, {'PRG_newchannel' : 1})}}
|
||||
<tr><td>{{:helper.link("Toggle Administration Mode", null, {'PRG_toggleadmin' : 1})}}
|
||||
<tr><td>{{:helper.link("Toggle Ringer", null, {'PRG_toggleringer' : 1})}}
|
||||
<tr><td>{{:helper.link("Set Ringtone", null, {'PRG_setringtone' : 1})}}
|
||||
</table>
|
||||
<b>Available channels:</b>
|
||||
<table>
|
||||
{{for data.all_channels}}
|
||||
<tr><td>{{:helper.link(value.chan, null, {'PRG_joinchannel' : value.id}, null, value.con ? 'selected' : null)}}<br>
|
||||
{{/for}}
|
||||
</table>
|
||||
{{/if}}
|
||||
@@ -1,101 +0,0 @@
|
||||
<i>Welcome to NT IT client manager</i><hr>
|
||||
<div>This is the Client Management Application of the Nanotrasen IT Department. It is used ensure that the clients comply with the corporate IT policy, enroll new clients and manage clients remotely</div>
|
||||
<br>
|
||||
{{if data.error_message}}
|
||||
<div class="itemContent" style="color: red; text-align: center; width: 100%;">
|
||||
<b>Error:</b> {{:data.error_message}}
|
||||
</div>
|
||||
<br>
|
||||
{{/if}}
|
||||
<div>
|
||||
<h2>Status</h2>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Enrollment Status:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.status_enrollment == 0}}
|
||||
Unconfigured
|
||||
{{else data.status_enrollment == 1}}
|
||||
Work Device
|
||||
{{else data.status_enrollment == 2}}
|
||||
Private Device
|
||||
{{else}}
|
||||
Error - Contact the IT Department
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{if data.status_enrollment == 1}}
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Policy Compliance Status:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.status_compliance == 0}}
|
||||
Not Compliant
|
||||
{{else data.status_compliance == 1}}
|
||||
Compliant
|
||||
{{else}}
|
||||
Error - Contact the IT Department
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Remote Management Status:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.status_remote == 0}}
|
||||
Inactive
|
||||
{{else data.status_remote == 1}}
|
||||
Active
|
||||
{{else}}
|
||||
Error - Contact the IT Department
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{if data.status_enrollment == 0}}
|
||||
</div>
|
||||
<div>
|
||||
<div><h2>Device Enrollment</h2></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td width="150px">
|
||||
<div><b>Device Type:</b></div>
|
||||
<div>
|
||||
{{:helper.link('Company', null, { "PRG_dev_type" : 1 }, data.dev_type == 1 ? 'selected' : null)}}
|
||||
{{:helper.link('Private', null, { "PRG_dev_type" : 2 }, data.dev_type == 2 ? 'selected' : null)}}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{if data.dev_type == 1}}
|
||||
<div><b>Device Preset:</b></div>
|
||||
<div>
|
||||
{{for data.dev_presets}}
|
||||
<div>{{:helper.link(value.display_name,null,{"PRG_dev_preset" : value.name}, value.name == data.dev_preset ? 'selected' : null)}}</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div><b>Enroll Device:</b></div>
|
||||
<div>{{:helper.link('Confirm', null, { "PRG_enroll" : 1 })}}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{{else data.status_enrollment == 1}}
|
||||
<div>
|
||||
<h2>Control</h2>
|
||||
<div>{{:helper.link("Request Support",null,{"PRG_req_support" : 1}, 'disabled')}}</div>
|
||||
<div>{{:helper.link("Reset Device",null,{"PRG_reset_device" : 1}, 'disabled')}}</div>
|
||||
</div>
|
||||
{{else data.status_enrollment == 2}}
|
||||
<div>
|
||||
<h2>Control</h2>
|
||||
<div>{{:helper.link("Reset Device",null,{"PRG_reset_device" : 1}, 'disabled')}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -1,132 +0,0 @@
|
||||
<i>Welcome to software download utility. Please select which software you wish to download.</i><hr>
|
||||
{{if data.error}}
|
||||
<h2>Download Error</h2>
|
||||
<div class="itemLabel">
|
||||
Information:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.error}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Reset Program:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link("RESET", null, {'PRG_reseterror' : 1})}}
|
||||
</div>
|
||||
{{else data.downloadname}}
|
||||
<h2>Download Running</h2>
|
||||
<i>Please wait...</i>
|
||||
<div class="itemLabel">
|
||||
File description:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.downloaddesc}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
File name:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.downloadname}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
File size:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.downloadcompletion}}GQ / {{:data.downloadsize}}GQ
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Transfer Rate:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.downloadspeed}} GQ/s
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Download progress:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.displayBar(data.downloadcompletion, 0, data.downloadsize, 'good')}}
|
||||
</div>
|
||||
{{else}}
|
||||
<h2>Primary software repository</h2>
|
||||
<div class="itemLabel">
|
||||
Hard drive:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.displayBar(data.disk_used, 0, data.disk_size, 'good')}}
|
||||
{{:data.disk_used}}GQ / {{:data.disk_size}}GQ
|
||||
</div>
|
||||
<br>
|
||||
{{for data.downloadable_programs}}
|
||||
<hr>
|
||||
<div class = "item">
|
||||
<div class="itemLabel">
|
||||
Program name:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<b>{{:value.filedesc}}</b>
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
File name:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.filename}} ({{:value.size}} GQ)
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Description:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.fileinfo}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
File controls:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link("Download", null, {'PRG_downloadfile' : value.filename})}}
|
||||
</div>
|
||||
</div>
|
||||
{{empty}}
|
||||
<hr><br>
|
||||
{{if data.locked}}
|
||||
<div class="itemContent" style="color: red; text-align: center; width: 100%;"><b>ERROR: This terminal is locked, users are disallowed from downloading software. Please contact your system administrator.</b></div>
|
||||
{{else}}
|
||||
<div class="itemContent" style="text-align: center; width: 100%;"><b>There are no available programs for your clearance level at this time.</b></div>
|
||||
{{/if}}
|
||||
<br>
|
||||
{{/for}}
|
||||
{{if data.hackedavailable}}
|
||||
<h2>*UNKNOWN* software repository</h2>
|
||||
<i>Please note that NanoTrasen does not recommend download of software from non-official servers.</i>
|
||||
{{for data.hacked_programs}}
|
||||
<div class = "item">
|
||||
<div class="itemLabel">
|
||||
Program name:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.filedesc}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
File name:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.filename}} ({{:value.size}} GQ)
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
Description:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.fileinfo}}
|
||||
</div>
|
||||
<div class="itemLabel">
|
||||
File controls:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link("Download", null, {'PRG_downloadfile' : value.filename})}}
|
||||
</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
<br><br>
|
||||
|
||||
<div style="position: fixed; bottom: 5px;"><hr><i>NTOS v2.0.6 Copyright NanoTrasen 2450 - 2460</i></div>
|
||||
42
vueui/src/components/view/mcomputer/chat/channel-btn.vue
Normal file
42
vueui/src/components/view/mcomputer/chat/channel-btn.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<vui-button v-if="password == null" @click="join">{{ ch.title }}</vui-button>
|
||||
<template v-else>
|
||||
<input type="text" v-model="password" @keydown.enter="join_with">
|
||||
<vui-button :params="{join: {target: re, password: password}}">Join {{ ch.title }}</vui-button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sendToTopic } from '@/utils'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
password: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
join() {
|
||||
if(this.ch.password) {
|
||||
this.password = ''
|
||||
} else {
|
||||
sendToTopic({join: {target: this.re}})
|
||||
}
|
||||
},
|
||||
join_with() {
|
||||
sendToTopic({join: {target: this.re, password: this.password}})
|
||||
}
|
||||
},
|
||||
props: {
|
||||
ch: {
|
||||
type: Object,
|
||||
default: {},
|
||||
},
|
||||
re: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
119
vueui/src/components/view/mcomputer/chat/chat.vue
Normal file
119
vueui/src/components/view/mcomputer/chat/chat.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3>{{ channel.title }}</h3>
|
||||
<div>
|
||||
<template v-if="!channel.direct">
|
||||
<vui-button :params="{leave: reference}" @click="$emit('on-leave')">Leave</vui-button>
|
||||
</template>
|
||||
<template v-if="channel.can_manage">
|
||||
<template v-if="password != null">
|
||||
<input type="text" v-model="password" @keydown.enter="set_password">
|
||||
<vui-button @click="set_password">Set password</vui-button>
|
||||
</template>
|
||||
<vui-button v-else-if="!channel.direct" @click="password = ''">Set password</vui-button>
|
||||
<template v-if="title != null">
|
||||
<input type="text" v-model="title" @keydown.enter="set_title">
|
||||
<vui-button @click="set_title">Change title</vui-button>
|
||||
</template>
|
||||
<vui-button v-else-if="!channel.direct" @click="title = channel.title">Change title</vui-button>
|
||||
<vui-button :params="{delete: reference}" @click="$emit('on-leave')">Delete channel</vui-button>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<div v-for="(user, uref) in channel.users" :key="uref">
|
||||
{{ user }}
|
||||
<vui-button v-if="channel.can_manage && !channel.direct" :params="{kick: {target: reference, user: uref}}">Kick</vui-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-chat" ref="chat">
|
||||
<div v-for="(msg, index) in messages" :key="index">{{ msg }}</div>
|
||||
</div>
|
||||
<div class="message-container">
|
||||
<input class="message-input" type="text" v-model="send_buffer" @keydown.enter="send_msg"/>
|
||||
<vui-button @click="send_msg" class="message-send">Send</vui-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sendToTopic } from '@/utils'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
s: this.$root.$data.state,
|
||||
send_buffer: "",
|
||||
password: null,
|
||||
title: null,
|
||||
wasAtBottom: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
channel() {
|
||||
return this.s.channels[this.reference]
|
||||
},
|
||||
messages() {
|
||||
return this.channel.msg
|
||||
}
|
||||
},
|
||||
props: {
|
||||
reference: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
send_msg() {
|
||||
sendToTopic({
|
||||
send: { message: this.send_buffer, target: this.reference },
|
||||
})
|
||||
this.send_buffer = ""
|
||||
},
|
||||
set_password() {
|
||||
sendToTopic({set_password: {target: this.reference, password: this.password}})
|
||||
this.password = null
|
||||
},
|
||||
set_title() {
|
||||
sendToTopic({change_title: {target: this.reference, title: this.title}})
|
||||
this.title = null
|
||||
},
|
||||
scrollBottom() {
|
||||
let chat = this.$refs.chat
|
||||
chat.scrollTop = chat.scrollHeight
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.scrollBottom()
|
||||
},
|
||||
beforeUpdate() {
|
||||
let chat = this.$refs.chat
|
||||
this.wasAtBottom = (chat.scrollHeight - chat.scrollTop === chat.clientHeight)
|
||||
},
|
||||
updated() {
|
||||
if(this.wasAtBottom) {
|
||||
this.scrollBottom()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.message-chat {
|
||||
width: 100%;
|
||||
background: #000000;
|
||||
color: #ffffff;
|
||||
border: 1px solid #40628a;
|
||||
padding: 0.4em;
|
||||
box-sizing: border-box;
|
||||
height: 20em;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.message-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.message-input {
|
||||
width: 80%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
||||
41
vueui/src/components/view/mcomputer/chat/explore.vue
Normal file
41
vueui/src/components/view/mcomputer/chat/explore.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="channelTitle != null">
|
||||
<input type="text" v-model="channelTitle" @keydown.enter="new_channel()">
|
||||
<vui-button @click="new_channel()">New channel</vui-button>
|
||||
</template>
|
||||
<vui-button v-else @click="channelTitle = ''">New channel</vui-button><br>
|
||||
<view-mcomputer-chat-channel-btn v-for="ref in displayed" :key="ref" :re="ref" :ch="s.channels[ref]"/>
|
||||
<h2>Users:</h2>
|
||||
<vui-input-search :input="users" v-model="users_result" :keys="['user']"/><br/>
|
||||
<div v-for="u in users_result" :key="u.ref"><vui-button :params="{direct: u.ref}">{{ u.user }}</vui-button></div>
|
||||
<pre>{{ users_result }}</pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sendToTopic } from '@/utils'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
s: this.$root.$data.state,
|
||||
channelTitle: null,
|
||||
users_result: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
new_channel() {
|
||||
sendToTopic({new_channel: this.channelTitle})
|
||||
this.channelTitle = null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
displayed() {
|
||||
return Object.keys(this.s.channels).filter(key => !this.s.channels[key].can_interact)
|
||||
},
|
||||
users() {
|
||||
return Object.entries(this.s.users).map(v => ({ref: v[0], user: v[1]}))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
49
vueui/src/components/view/mcomputer/chat/index.vue
Normal file
49
vueui/src/components/view/mcomputer/chat/index.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 v-if="!s.service" class="red">Chat service is not enabled, please enble it from main menu.</h2>
|
||||
<h2 v-else-if="!s.registered" class="red">No registered user detected.</h2>
|
||||
<h2 v-else-if="!s.signal" class="red">No network signal.</h2>
|
||||
<template v-else>
|
||||
<div>
|
||||
<vui-button v-if="s.can_netadmin_mode || s.netadmin_mode" :class="{ on: s.netadmin_mode }" :params="{toggleadmin: 1}">Admin Mode</vui-button>
|
||||
Ringtone:
|
||||
<vui-button v-if="ringtone == null" @click="ringtone = s.ringtone">{{ s.ringtone }}</vui-button>
|
||||
<template v-else>
|
||||
<input type="text" v-model="ringtone" @keypress.enter="set_ringtone">
|
||||
<vui-button @click="set_ringtone">Set ringtone</vui-button>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<vui-button :class="{ on: active == null }" @click="active = null">Explore</vui-button>
|
||||
<vui-button v-for="ref in tab_channels" :key="ref" :class="{ on: active == ref }" @click="active = ref">{{ s.channels[ref].title }}</vui-button>
|
||||
</div>
|
||||
<hr>
|
||||
<view-mcomputer-chat-explore v-if="active == null"/>
|
||||
<view-mcomputer-chat-chat v-else :reference="active" @on-leave="active = null"/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { sendToTopic } from '@/utils'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
s: this.$root.$data.state,
|
||||
active: null,
|
||||
ringtone: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
tab_channels() {
|
||||
return Object.keys(this.s.channels).filter(key => this.s.channels[key].can_interact)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
set_ringtone() {
|
||||
sendToTopic({ringtone: this.ringtone})
|
||||
this.ringtone = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user