mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-25 01:22:13 +00:00
pAIs, Computers and ntIRC (#8757)
#8005 just revived. Tasks to acomplish while here: Fix merge conflicts Add ntIRC direct messaging Things I migth consider adding in future PR: Porting IRC to VueUI Porting File Manager to VueUI.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
/obj/item/modular_computer/initial_data()
|
||||
return list("_PC" = get_header_data())
|
||||
|
||||
/datum/computer_file/program/initial_data()
|
||||
return list("_PC" = get_header_data())
|
||||
|
||||
/obj/item/modular_computer/update_layout()
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
return
|
||||
|
||||
computer.visible_message(SPAN_NOTICE("\The [computer]'s screen brightly flashes and emits a loud electrical buzzing."))
|
||||
computer.enabled = FALSE
|
||||
computer.update_icon()
|
||||
computer.shutdown_computer(0)
|
||||
spark(get_turf(src), 10, alldirs)
|
||||
|
||||
if(computer.hard_drive)
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
requires_ntnet = TRUE
|
||||
network_destination = "atmospheric control system"
|
||||
requires_ntnet_feature = NTNET_SYSTEMCONTROL
|
||||
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_SILICON
|
||||
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_STATIONBOUND
|
||||
size = 17
|
||||
color = LIGHT_COLOR_CYAN
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
requires_ntnet = TRUE
|
||||
network_destination = "RCON remote control system"
|
||||
requires_ntnet_feature = NTNET_SYSTEMCONTROL
|
||||
usage_flags = PROGRAM_CONSOLE | PROGRAM_SILICON
|
||||
usage_flags = PROGRAM_CONSOLE | PROGRAM_STATIONBOUND
|
||||
size = 19
|
||||
color = LIGHT_COLOR_GREEN
|
||||
|
||||
@@ -103,6 +103,6 @@
|
||||
requires_ntnet = TRUE
|
||||
network_destination = "APC Coordinator"
|
||||
requires_ntnet_feature = NTNET_SYSTEMCONTROL
|
||||
usage_flags = PROGRAM_CONSOLE | PROGRAM_SILICON
|
||||
usage_flags = PROGRAM_CONSOLE | PROGRAM_STATIONBOUND
|
||||
size = 9
|
||||
color = LIGHT_COLOR_GREEN
|
||||
@@ -0,0 +1,44 @@
|
||||
/datum/computer_file/program/manifest
|
||||
filename = "manifest"
|
||||
filedesc = "Crew Manifest"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program is used for viewing the crew manifest."
|
||||
size = 3
|
||||
|
||||
requires_ntnet = 1
|
||||
available_on_ntnet = 1
|
||||
|
||||
|
||||
/datum/computer_file/program/manifest/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if (!ui)
|
||||
ui = new /datum/vueui/modularcomputer(user, src, "manifest", 450, 600, "Crew Manifest")
|
||||
ui.open()
|
||||
|
||||
/datum/computer_file/program/manifest/vueui_transfer(oldobj)
|
||||
SSvueui.transfer_uis(oldobj, src, "manifest", 450, 600, "Crew Manifest")
|
||||
return TRUE
|
||||
|
||||
// Gaters data for ui
|
||||
/datum/computer_file/program/manifest/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
|
||||
|
||||
VUEUI_SET_CHECK(data["manifest"], SSrecords.get_manifest_list(), ., data)
|
||||
|
||||
/datum/computer_file/program/manifest/Topic(href, href_list)
|
||||
. = ..()
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
host.radio.Topic(href, href_list)
|
||||
@@ -15,6 +15,7 @@
|
||||
var/datum/ntnet_conversation/channel
|
||||
var/operator_mode = FALSE // Channel operator mode
|
||||
var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords)
|
||||
var/list/directmessagechannels = list()
|
||||
color = LIGHT_COLOR_GREEN
|
||||
|
||||
/datum/computer_file/program/chatclient/New()
|
||||
@@ -60,9 +61,12 @@
|
||||
channel = C
|
||||
if(href_list["PRG_leavechannel"])
|
||||
. = TRUE
|
||||
if(channel)
|
||||
if(channel && !channel.direct)
|
||||
channel.remove_client(src)
|
||||
channel = null
|
||||
if(href_list["PRG_backtomain"])
|
||||
. = TRUE
|
||||
channel = null
|
||||
if(href_list["PRG_newchannel"])
|
||||
. = TRUE
|
||||
var/mob/living/user = usr
|
||||
@@ -98,10 +102,16 @@
|
||||
var/new_name = sanitize(input(user, "Enter new nickname or leave blank to cancel:"))
|
||||
if(!new_name)
|
||||
return TRUE
|
||||
if(channel)
|
||||
channel.add_status_message("[username] is now known as [new_name].")
|
||||
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)
|
||||
@@ -156,6 +166,30 @@
|
||||
channel.password = ""
|
||||
else
|
||||
channel.password = newpassword
|
||||
if(href_list["PRG_directmessage"])
|
||||
. = TRUE
|
||||
var/clients = list()
|
||||
var/names = list()
|
||||
for(var/cl in ntnet_global.chat_clients)
|
||||
var/datum/computer_file/program/chatclient/C = cl
|
||||
clients[C.username] = C
|
||||
names += C.username
|
||||
names -= username // Remove ourselves
|
||||
names += "== Cancel =="
|
||||
var/picked = input(usr, "Select with whom you would like to start a conversation.") in names
|
||||
if(picked == "== Cancel ==")
|
||||
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()
|
||||
..()
|
||||
@@ -176,11 +210,14 @@
|
||||
ui_header = "ntnrc_idle.gif"
|
||||
|
||||
/datum/computer_file/program/chatclient/kill_program(var/forced = FALSE)
|
||||
if(channel)
|
||||
channel.remove_client(src)
|
||||
channel = null
|
||||
channel = null
|
||||
ntnet_global.chat_clients -= src
|
||||
..(forced)
|
||||
|
||||
/datum/computer_file/program/chatclient/run_program(var/mob/user)
|
||||
ntnet_global.chat_clients += src
|
||||
return ..(user)
|
||||
|
||||
/datum/nano_module/program/computer_chatclient
|
||||
name = "NTNet Relay Chat Client"
|
||||
|
||||
@@ -198,7 +235,7 @@
|
||||
|
||||
data["adminmode"] = C.netadmin_mode
|
||||
if(C.channel)
|
||||
data["title"] = C.channel.title
|
||||
data["title"] = C.channel.get_title(C)
|
||||
var/list/messages[0]
|
||||
for(var/M in C.channel.messages)
|
||||
messages.Add(list(list(
|
||||
@@ -208,19 +245,21 @@
|
||||
var/list/clients[0]
|
||||
for(var/datum/computer_file/program/chatclient/cl in C.channel.clients)
|
||||
clients.Add(list(list(
|
||||
"name" = cl.username
|
||||
"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)
|
||||
if(conv && conv.title && conv.can_see(program))
|
||||
all_channels.Add(list(list(
|
||||
"chan" = conv.title,
|
||||
"id" = conv.id
|
||||
"chan" = conv.get_title(C),
|
||||
"id" = conv.id,
|
||||
"con" = (program in conv.clients)
|
||||
)))
|
||||
data["all_channels"] = all_channels
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
requires_ntnet = TRUE
|
||||
requires_ntnet_feature = NTNET_SYSTEMCONTROL
|
||||
requires_access_to_run = PROGRAM_ACCESS_LIST_ONE
|
||||
usage_flags = PROGRAM_ALL_REGULAR | PROGRAM_STATIONBOUND
|
||||
|
||||
var/records_type = RECORD_GENERAL | RECORD_MEDICAL | RECORD_SECURITY | RECORD_VIRUS | RECORD_WARRANT | RECORD_LOCKED
|
||||
var/edit_type = RECORD_GENERAL | RECORD_MEDICAL | RECORD_SECURITY | RECORD_VIRUS | RECORD_WARRANT | RECORD_LOCKED
|
||||
@@ -77,6 +78,12 @@
|
||||
program_icon_state = "employment_record"
|
||||
color = LIGHT_COLOR_BLUE
|
||||
|
||||
/datum/computer_file/program/records/pai
|
||||
available_on_ntnet = 1
|
||||
extended_desc = "This program is used to view crew records."
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
edit_type = 0
|
||||
|
||||
/datum/computer_file/program/records/New()
|
||||
. = ..()
|
||||
listener = new(src)
|
||||
@@ -339,4 +346,4 @@
|
||||
var/datum/computer_file/program/records/t = target
|
||||
if(istype(t) && !t.isEditing)
|
||||
if(t.active == r || t.active_virus == r)
|
||||
SSvueui.check_uis_for_change(t)
|
||||
SSvueui.check_uis_for_change(t)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
requires_ntnet = TRUE
|
||||
network_destination = "crew lifesigns monitoring system"
|
||||
size = 11
|
||||
usage_flags = PROGRAM_ALL_REGULAR
|
||||
usage_flags = PROGRAM_ALL_REGULAR | PROGRAM_STATIONBOUND
|
||||
color = LIGHT_COLOR_CYAN
|
||||
|
||||
/datum/computer_file/program/suit_sensors/ui_interact(mob/user)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/datum/computer_file/program/pai_atmos
|
||||
filename = "pai_atmos"
|
||||
filedesc = "Atmosphere Sensor"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program is for viewing local atmospheric data."
|
||||
size = 0
|
||||
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_atmos/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if (!ui)
|
||||
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-pai-atmosphere", 400, 200, "pAI Atmosphere Sensor")
|
||||
ui.open()
|
||||
|
||||
/datum/computer_file/program/pai_atmos/vueui_transfer(oldobj)
|
||||
SSvueui.transfer_uis(oldobj, src, "mcomputer-pai-atmosphere", 400, 200, "pAI Atmosphere Sensor")
|
||||
return TRUE
|
||||
|
||||
// Gaters data for ui
|
||||
/datum/computer_file/program/pai_atmos/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
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
var/turf/T = get_turf_or_move(host.loc)
|
||||
|
||||
|
||||
if(T)
|
||||
var/datum/gas_mixture/env = T.return_air()
|
||||
VUEUI_SET_CHECK(data["read"], TRUE, ., data)
|
||||
VUEUI_SET_CHECK(data["press"], env.return_pressure(), ., data)
|
||||
VUEUI_SET_CHECK(data["temp"], env.temperature, ., data)
|
||||
VUEUI_SET_CHECK(data["tempC"], env.temperature-T0C, ., data)
|
||||
VUEUI_SET_CHECK_IFNOTSET(data["gas"], list("_" = "_"), ., data)
|
||||
for(var/g in gas_data.gases)
|
||||
if(!(g in env.gas))
|
||||
VUEUI_SET_CHECK(data["gas"][g], null, ., data)
|
||||
else
|
||||
VUEUI_SET_CHECK(data["gas"][g], env.gas[g], ., data)
|
||||
else
|
||||
VUEUI_SET_CHECK(data["read"], FALSE, ., data)
|
||||
VUEUI_SET_CHECK(data["press"], 0, ., data)
|
||||
VUEUI_SET_CHECK(data["temp"], T0C, ., data)
|
||||
VUEUI_SET_CHECK(data["tempC"], 0, ., data)
|
||||
VUEUI_SET_CHECK_IFNOTSET(data["gas"], list("_" = "_"), ., data)
|
||||
for(var/g in gas_data.gases)
|
||||
VUEUI_SET_CHECK(data["gas"][g], null, ., data)
|
||||
@@ -0,0 +1,79 @@
|
||||
/datum/computer_file/program/pai_directives
|
||||
filename = "pai_directives"
|
||||
filedesc = "pAI Directives"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program is for viewing currently assigned directives."
|
||||
size = 0
|
||||
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_directives/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if (!ui)
|
||||
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-pai-directives", 450, 500, "pAI directives")
|
||||
ui.open()
|
||||
|
||||
/datum/computer_file/program/pai_directives/vueui_transfer(oldobj)
|
||||
SSvueui.transfer_uis(oldobj, src, "mcomputer-pai-directives", 450, 500, "pAI directives")
|
||||
return TRUE
|
||||
|
||||
// Gaters data for ui
|
||||
/datum/computer_file/program/pai_directives/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
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
VUEUI_SET_CHECK(data["master"], host.master, ., data)
|
||||
VUEUI_SET_CHECK(data["dna"], host.master_dna, ., data)
|
||||
VUEUI_SET_CHECK(data["prime"], host.pai_law0, ., data)
|
||||
VUEUI_SET_CHECK(data["supplemental"], host.pai_laws, ., data)
|
||||
|
||||
/datum/computer_file/program/pai_directives/Topic(href, href_list)
|
||||
. = ..()
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
if(href_list["getdna"])
|
||||
var/mob/living/M = host.loc
|
||||
var/count = 0
|
||||
|
||||
// Find the carrier
|
||||
while(!istype(M, /mob/living))
|
||||
if(!M || !M.loc || count > 6)
|
||||
//For a runtime where M ends up in nullspace (similar to bluespace but less colourful)
|
||||
to_chat(src, SPAN_WARNING("You are not being carried by anyone!"))
|
||||
return 0
|
||||
M = M.loc
|
||||
count++
|
||||
|
||||
// Check the carrier
|
||||
var/answer = input(M, "[host] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[host] Check DNA", "No") in list("Yes", "No")
|
||||
if(answer == "Yes")
|
||||
var/turf/T = get_turf_or_move(host.loc)
|
||||
for (var/mob/v in viewers(T))
|
||||
v.show_message(SPAN_NOTICE("[M] presses \his thumb against [host]."), 3, SPAN_NOTICE("[host] makes a sharp clicking sound as it extracts DNA material from [M]."), 2)
|
||||
var/datum/dna/dna = M.dna
|
||||
to_chat(host, "<font color = red><h3>[M]'s UE string : [dna.unique_enzymes]</h3></font>")
|
||||
if(dna.unique_enzymes == host.master_dna)
|
||||
to_chat(host, SPAN_NOTICE("<b>Provided DNA is a match to stored Master DNA.</b>"))
|
||||
else
|
||||
to_chat(host, SPAN_WARNING("<b>Provided DNA does not match stored Master DNA.</b>"))
|
||||
else
|
||||
to_chat(host, SPAN_WARNING("[M] does not seem like \he [gender_datums[M.gender].is] going to provide a DNA sample willingly."))
|
||||
return 1
|
||||
@@ -0,0 +1,106 @@
|
||||
/datum/computer_file/program/pai_doorjack
|
||||
filename = "doorjack"
|
||||
filedesc = "Door Jack"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program is used to access standard-issue pAI door jack systems."
|
||||
size = 12
|
||||
|
||||
available_on_ntnet = 1
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_doorjack/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if (!ui)
|
||||
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-pai-doorjack", 400, 150, "Door Jack")
|
||||
ui.auto_update_content = TRUE
|
||||
ui.open()
|
||||
|
||||
/datum/computer_file/program/pai_doorjack/vueui_transfer(oldobj)
|
||||
var/uis = SSvueui.transfer_uis(oldobj, src, "mcomputer-pai-doorjack", 400, 150, "Door Jack")
|
||||
for(var/i in uis)
|
||||
var/datum/vueui/ui = i
|
||||
ui.auto_update_content = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/pai_doorjack/vueui_on_transfer(datum/vueui/ui)
|
||||
. = ..()
|
||||
ui.auto_update_content = FALSE
|
||||
|
||||
// Gaters data for ui
|
||||
/datum/computer_file/program/pai_doorjack/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
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
VUEUI_SET_CHECK(data["extended"], !!host.cable, ., data)
|
||||
VUEUI_SET_CHECK(data["connected"], !!host.cable?.machine , ., data)
|
||||
VUEUI_SET_CHECK(data["ishacking"], !!host.hackdoor, ., data)
|
||||
VUEUI_SET_CHECK(data["progress"], host.hackprogress, ., data)
|
||||
VUEUI_SET_CHECK(data["aborted"], host.hack_aborted, ., data)
|
||||
|
||||
/datum/computer_file/program/pai_doorjack/Topic(href, href_list)
|
||||
. = ..()
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
if(href_list["hack"])
|
||||
if(host.cable && host.cable.machine)
|
||||
host.hackdoor = host.cable.machine
|
||||
host.hackloop()
|
||||
return 1
|
||||
if(href_list["cancel"])
|
||||
host.hackdoor = null
|
||||
return 1
|
||||
if(href_list["extend"])
|
||||
var/turf/T = get_turf_or_move(host.loc)
|
||||
host.hack_aborted = 0
|
||||
host.cable = new /obj/item/pai_cable(T)
|
||||
T.visible_message(SPAN_WARNING("A port on [host] opens to reveal [host.cable], which promptly falls to the floor."),
|
||||
SPAN_WARNING("You hear the soft click of something light and hard falling to the ground."))
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/pai/proc/hackloop()
|
||||
var/turf/T = get_turf_or_move(src.loc)
|
||||
for(var/mob/living/silicon/ai/AI in player_list)
|
||||
if(T.loc)
|
||||
to_chat(AI, "<font color = red><b>Network Alert: Brute-force encryption crack in progress in [T.loc].</b></font>")
|
||||
else
|
||||
to_chat(AI, "<font color = red><b>Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location.</b></font>")
|
||||
var/obj/machinery/door/airlock/D = cable.machine
|
||||
if(!istype(D))
|
||||
hack_aborted = 1
|
||||
hackprogress = 0
|
||||
cable.machine = null
|
||||
hackdoor = null
|
||||
return
|
||||
while(hackprogress < 1000)
|
||||
if(cable && cable.machine == D && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1)
|
||||
hackprogress = min(hackprogress+rand(1, 20), 1000)
|
||||
else
|
||||
hack_aborted = 1
|
||||
hackprogress = 0
|
||||
hackdoor = null
|
||||
return
|
||||
if(hackprogress >= 1000)
|
||||
hackprogress = 0
|
||||
D.unlock() //unbolts door as long as bolt wires aren't cut
|
||||
D.open()
|
||||
cable.machine = null
|
||||
return
|
||||
sleep(10) // Update every second
|
||||
@@ -0,0 +1,57 @@
|
||||
/datum/computer_file/program/pai_sechud
|
||||
filename = "sechud"
|
||||
filedesc = "pAI Security HUD"
|
||||
extended_desc = "This service enables the integrated security HUD."
|
||||
size = 10
|
||||
program_type = PROGRAM_SERVICE
|
||||
available_on_ntnet = 1
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_sechud/service_activate()
|
||||
. = ..()
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
host.secHUD = TRUE
|
||||
|
||||
/datum/computer_file/program/pai_sechud/service_deactivate()
|
||||
. = ..()
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
host.secHUD = FALSE
|
||||
|
||||
/datum/computer_file/program/pai_medhud
|
||||
filename = "medhud"
|
||||
filedesc = "pAI Medical HUD"
|
||||
extended_desc = "This service enables the integrated medical HUD."
|
||||
size = 10
|
||||
program_type = PROGRAM_SERVICE
|
||||
available_on_ntnet = 1
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_medhud/service_activate()
|
||||
. = ..()
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
host.medHUD = TRUE
|
||||
|
||||
/datum/computer_file/program/pai_medhud/service_deactivate()
|
||||
. = ..()
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
host.medHUD = FALSE
|
||||
@@ -0,0 +1,56 @@
|
||||
/datum/computer_file/program/pai_radio
|
||||
filename = "pai_radio"
|
||||
filedesc = "Radio Configuration"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program is used to configure the integrated pAI radio."
|
||||
size = 0
|
||||
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_radio/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if (!ui)
|
||||
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-pai-radio", 400, 150, "pAI Radio Configuration")
|
||||
ui.open()
|
||||
|
||||
/datum/computer_file/program/pai_radio/vueui_transfer(oldobj)
|
||||
SSvueui.transfer_uis(oldobj, src, "mcomputer-pai-radio", 400, 150, "pAI Radio Configuration")
|
||||
return TRUE
|
||||
|
||||
// Gaters data for ui
|
||||
/datum/computer_file/program/pai_radio/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
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
VUEUI_SET_CHECK(data["listening"], host.radio.broadcasting, ., data)
|
||||
VUEUI_SET_CHECK(data["frequency"], format_frequency(host.radio.frequency), ., data)
|
||||
|
||||
LAZYINITLIST(data["channels"])
|
||||
for(var/ch_name in host.radio.channels)
|
||||
var/ch_stat = host.radio.channels[ch_name]
|
||||
VUEUI_SET_CHECK(data["channels"][ch_name], !!(ch_stat & host.radio.FREQ_LISTENING), ., data)
|
||||
|
||||
/datum/computer_file/program/pai_radio/Topic(href, href_list)
|
||||
. = ..()
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
host.radio.Topic(href, href_list)
|
||||
SSvueui.check_uis_for_change(src)
|
||||
@@ -0,0 +1,69 @@
|
||||
/datum/computer_file/program/pai_signaler
|
||||
filename = "signaler"
|
||||
filedesc = "Remote Signaller"
|
||||
program_icon_state = "generic"
|
||||
extended_desc = "This program can be used to send wide-range signals of various frequencies."
|
||||
size = 3
|
||||
available_on_ntnet = 1
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_signaler/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if (!ui)
|
||||
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-pai-signaler", 400, 150, "pAI Signaller")
|
||||
ui.open()
|
||||
|
||||
/datum/computer_file/program/pai_signaler/vueui_transfer(oldobj)
|
||||
SSvueui.transfer_uis(oldobj, src, "mcomputer-pai-signaler", 400, 150, "pAI Signaller")
|
||||
return TRUE
|
||||
|
||||
// Gaters data for ui
|
||||
/datum/computer_file/program/pai_signaler/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
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
VUEUI_SET_CHECK(data["code"], host.sradio.code, ., data)
|
||||
VUEUI_SET_CHECK(data["frequency"], format_frequency(host.sradio.frequency), ., data)
|
||||
|
||||
|
||||
/datum/computer_file/program/pai_signaler/Topic(href, href_list)
|
||||
. = ..()
|
||||
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
if(href_list["send"])
|
||||
host.sradio.send_signal("ACTIVATE")
|
||||
for(var/mob/O in hearers(1, host.loc))
|
||||
O.show_message(text("\icon[] *beep* *beep*", host), 3, "*beep* *beep*", 2)
|
||||
return 1
|
||||
|
||||
else if(href_list["freq"])
|
||||
var/new_frequency = (host.sradio.frequency + href_list["freq"])
|
||||
if(new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ)
|
||||
new_frequency = sanitize_frequency(new_frequency)
|
||||
host.sradio.set_frequency(new_frequency)
|
||||
return 1
|
||||
|
||||
else if(href_list["code"])
|
||||
host.sradio.code += href_list["code"]
|
||||
host.sradio.code = round(host.sradio.code)
|
||||
host.sradio.code = min(100, host.sradio.code)
|
||||
host.sradio.code = max(1, host.sradio.code)
|
||||
return 1
|
||||
@@ -0,0 +1,40 @@
|
||||
/datum/computer_file/program/pai_translator
|
||||
filename = "translator"
|
||||
filedesc = "pAI Universal Translator"
|
||||
extended_desc = "This service enables the integrated universal translation systems."
|
||||
size = 12
|
||||
program_type = PROGRAM_SERVICE
|
||||
available_on_ntnet = 1
|
||||
usage_flags = PROGRAM_SILICON_PAI
|
||||
|
||||
/datum/computer_file/program/pai_translator/service_activate()
|
||||
. = ..()
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
if(!host.translator_on)
|
||||
host.add_language(LANGUAGE_UNATHI)
|
||||
host.add_language(LANGUAGE_SIIK_MAAS)
|
||||
host.add_language(LANGUAGE_SKRELLIAN)
|
||||
host.add_language(LANGUAGE_ROOTSONG)
|
||||
host.translator_on = TRUE
|
||||
|
||||
/datum/computer_file/program/pai_translator/service_deactivate()
|
||||
. = ..()
|
||||
if(!istype(computer, /obj/item/modular_computer/silicon))
|
||||
return
|
||||
var/obj/item/modular_computer/silicon/true_computer = computer
|
||||
if(!istype(true_computer.computer_host, /mob/living/silicon/pai))
|
||||
return
|
||||
var/mob/living/silicon/pai/host = true_computer.computer_host
|
||||
|
||||
if(host.translator_on)
|
||||
host.remove_language(LANGUAGE_UNATHI)
|
||||
host.remove_language(LANGUAGE_SIIK_MAAS)
|
||||
host.remove_language(LANGUAGE_SKRELLIAN)
|
||||
host.remove_language(LANGUAGE_ROOTSONG)
|
||||
host.translator_on = FALSE
|
||||
@@ -7,7 +7,7 @@
|
||||
requires_ntnet = TRUE
|
||||
required_access_run = access_network
|
||||
required_access_download = access_heads
|
||||
usage_flags = PROGRAM_CONSOLE
|
||||
usage_flags = PROGRAM_CONSOLE | PROGRAM_SILICON_AI
|
||||
color = LIGHT_COLOR_GREEN
|
||||
|
||||
available_on_ntnet = TRUE
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
required_access_download = access_hos
|
||||
required_access_run = access_security
|
||||
nanomodule_path = /datum/nano_module/program/digitalwarrant
|
||||
usage_flags = PROGRAM_ALL_REGULAR | PROGRAM_STATIONBOUND
|
||||
|
||||
/datum/nano_module/program/digitalwarrant
|
||||
name = "Warrant Assistant"
|
||||
|
||||
@@ -9,231 +9,224 @@
|
||||
size = 4
|
||||
requires_ntnet = TRUE
|
||||
requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD
|
||||
available_on_ntnet = FALSE
|
||||
nanomodule_path = /datum/nano_module/program/computer_ntnetdownload
|
||||
available_on_ntnet = 0
|
||||
ui_header = "downloader_finished.gif"
|
||||
var/datum/computer_file/program/downloaded_file
|
||||
var/hacked_download = FALSE
|
||||
var/download_completion = 0 //GQ of downloaded data.
|
||||
var/download_netspeed = 0
|
||||
var/download_last_update = 0 // For tracking download rates and completion.
|
||||
var/downloaderror = ""
|
||||
var/downstream_variance = 0.1
|
||||
var/list/download_queue = list()
|
||||
var/list/download_files = list()
|
||||
var/queue_size = 0
|
||||
var/active_download = null
|
||||
var/last_update = 0
|
||||
var/speed = 0
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/begin_file_download(var/filename, var/user)
|
||||
if(downloaded_file)
|
||||
return FALSE
|
||||
|
||||
var/datum/computer_file/program/PRG = ntnet_global.find_ntnet_file_by_name(filename)
|
||||
/datum/computer_file/program/ntnetdownload/ui_interact(mob/user, var/datum/topic_state/state = default_state)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if (!ui)
|
||||
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-system-downloader", 575, 700, "NTNet Download Program", state = state)
|
||||
ui.open()
|
||||
|
||||
if(!PRG || !istype(PRG))
|
||||
return FALSE
|
||||
/datum/computer_file/program/ntnetdownload/vueui_transfer(oldobj)
|
||||
SSvueui.transfer_uis(oldobj, src, "mcomputer-system-downloader", 575, 700, "NTNet Download Program")
|
||||
return TRUE
|
||||
|
||||
// Gaters data for ui
|
||||
/datum/computer_file/program/ntnetdownload/vueui_data_change(var/list/data, var/mob/user, var/datum/vueui/ui)
|
||||
. = ..()
|
||||
data = . || data || list("queue" = download_queue)
|
||||
|
||||
if(!istype(computer))
|
||||
return
|
||||
|
||||
// Gather data for computer header
|
||||
var/headerdata = get_header_data(data["_PC"])
|
||||
if(headerdata)
|
||||
data["_PC"] = headerdata
|
||||
. = data
|
||||
|
||||
// Let's send all installed programs
|
||||
LAZYINITLIST(data["installed"])
|
||||
for(var/datum/computer_file/program/I in hard_drive.stored_files)
|
||||
LAZYINITLIST(data["installed"][I.filename])
|
||||
VUEUI_SET_CHECK(data["installed"][I.filename]["name"], I.filedesc, ., data)
|
||||
VUEUI_SET_CHECK(data["installed"][I.filename]["size"], I.size, ., data)
|
||||
|
||||
// Now lets send all avaivable programs with there status.
|
||||
// Statuses (rest): 0 - ALL OK, 1 - can't download due to access, 2 - unsuported hardware, 3 - sindies only
|
||||
LAZYINITLIST(data["avaivable"])
|
||||
for(var/datum/computer_file/program/P in ntnet_global.available_software)
|
||||
LAZYINITLIST(data["avaivable"][P.filename])
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["name"], P.filedesc, ., data)
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["desc"], P.extended_desc, ., data)
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["size"], P.size, ., data)
|
||||
if(computer_emagged)
|
||||
if(!P.is_supported_by_hardware(computer.hardware_flag))
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["rest"], 2, ., data)
|
||||
else
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["rest"], 0, ., data)
|
||||
else
|
||||
if(!P.available_on_ntnet)
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["rest"], 3, ., data)
|
||||
else if(!P.can_download(user) && P.requires_access_to_download)
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["rest"], 1, ., data)
|
||||
else if(!P.is_supported_by_hardware(computer.hardware_flag))
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["rest"], 2, ., data)
|
||||
else
|
||||
VUEUI_SET_CHECK(data["avaivable"][P.filename]["rest"], 0, ., data)
|
||||
|
||||
VUEUI_SET_CHECK(data["disk_size"], hard_drive.max_capacity, ., data)
|
||||
VUEUI_SET_CHECK(data["disk_used"], hard_drive.used_capacity, ., data)
|
||||
VUEUI_SET_CHECK(data["queue_size"], queue_size, ., data)
|
||||
VUEUI_SET_CHECK(data["speed"], speed, ., data)
|
||||
|
||||
for(var/name in download_queue)
|
||||
VUEUI_SET_CHECK(data["queue"][name], download_queue[name], ., data)
|
||||
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
var/datum/vueui/ui = href_list["vueui"]
|
||||
if(!istype(ui))
|
||||
return
|
||||
|
||||
if(href_list["download"])
|
||||
var/datum/computer_file/program/PRG = ntnet_global.find_ntnet_file_by_name(href_list["download"])
|
||||
|
||||
if(!istype(PRG))
|
||||
return 1
|
||||
return add_to_queue(PRG, ui.user)
|
||||
|
||||
if(href_list["cancel"])
|
||||
return cancel_from_queue(href_list["cancel"])
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/add_to_queue(var/datum/computer_file/program/PRG, var/mob/user)
|
||||
// Attempting to download antag only program, but without having emagged computer. No.
|
||||
if(PRG.available_on_syndinet && !computer_emagged)
|
||||
return FALSE
|
||||
|
||||
if(!hard_drive.can_store_file(queue_size + PRG.size))
|
||||
to_chat(user, SPAN_WARNING("You can't download this program as queued items exceed hard drive capacity."))
|
||||
return TRUE
|
||||
|
||||
if(!computer?.hard_drive?.try_store_file(PRG))
|
||||
return FALSE
|
||||
|
||||
if(computer.enrolled == TRUE && !computer_emagged)
|
||||
if(!computer_emagged && !PRG.can_download(user) && PRG.requires_access_to_download)
|
||||
return TRUE
|
||||
|
||||
if(!PRG.is_supported_by_hardware(computer.hardware_flag))
|
||||
return FALSE
|
||||
|
||||
ui_header = "downloader_running.gif"
|
||||
|
||||
if(PRG in ntnet_global.available_station_software)
|
||||
if(PRG.available_on_ntnet)
|
||||
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.")
|
||||
hacked_download = FALSE
|
||||
else if(PRG in ntnet_global.available_antag_software)
|
||||
else if (PRG.available_on_syndinet)
|
||||
generate_network_log("Began downloading file **ENCRYPTED**.[PRG.filetype] from unspecified server.")
|
||||
hacked_download = TRUE
|
||||
else
|
||||
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from unspecified server.")
|
||||
hacked_download = FALSE
|
||||
|
||||
downloaded_file = PRG.clone()
|
||||
if(user)
|
||||
spawn()
|
||||
ui_interact(user)
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/abort_file_download()
|
||||
if(!downloaded_file)
|
||||
download_files[PRG.filename] = PRG.clone()
|
||||
queue_size += PRG.size
|
||||
download_queue[PRG.filename] = 0
|
||||
for(var/i in SSvueui.get_open_uis(src))
|
||||
var/datum/vueui/ui = i
|
||||
ui.data["queue"][PRG.filename] = 0
|
||||
ui.push_change()
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/cancel_from_queue(var/name)
|
||||
if(!download_files[name])
|
||||
return
|
||||
generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : downloaded_file.filename].[downloaded_file.filetype].")
|
||||
downloaded_file = null
|
||||
download_completion = 0
|
||||
download_last_update = 0
|
||||
ui_header = "downloader_finished.gif"
|
||||
var/datum/computer_file/program/PRG = download_files[name]
|
||||
var/hacked_download = PRG.available_on_syndinet && !PRG.available_on_ntnet
|
||||
generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : PRG.filename].[PRG.filetype].")
|
||||
download_queue -= name
|
||||
download_files -= name
|
||||
queue_size -= PRG.size
|
||||
for(var/i in SSvueui.get_open_uis(src))
|
||||
var/datum/vueui/ui = i
|
||||
ui.data["queue"] -= name
|
||||
ui.push_change()
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/proc/complete_file_download()
|
||||
if(!downloaded_file)
|
||||
/datum/computer_file/program/ntnetdownload/proc/finish_from_queue(var/name)
|
||||
if(!download_files[name])
|
||||
return
|
||||
generate_network_log("Completed download of file [hacked_download ? "**ENCRYPTED**" : downloaded_file.filename].[downloaded_file.filetype].")
|
||||
if(!computer?.hard_drive?.store_file(downloaded_file))
|
||||
// The download failed
|
||||
downloaderror = "I/O ERROR - Unable to save file. Check whether you have enough free space on your hard drive and whether your hard drive is properly connected. If the issue persists contact your system administrator for assistance."
|
||||
else
|
||||
playsound(get_turf(computer), 'sound/machines/ping.ogg', 40, 0)
|
||||
computer.output_message("\icon[computer] <b>[capitalize_first_letters(computer)]</b> pings, \"Software download completed successfully!\"", 1)
|
||||
downloaded_file = null
|
||||
download_completion = 0
|
||||
download_last_update = 0
|
||||
ui_header = "downloader_finished.gif"
|
||||
|
||||
var/datum/computer_file/program/PRG = download_files[name]
|
||||
var/hacked_download = PRG.available_on_syndinet && !PRG.available_on_ntnet
|
||||
generate_network_log("Completed download of file [hacked_download ? "**ENCRYPTED**" : PRG.filename].[PRG.filetype].")
|
||||
if(!computer?.hard_drive?.store_file(PRG))
|
||||
download_queue[name] = -1
|
||||
for(var/i in SSvueui.get_open_uis(src))
|
||||
var/datum/vueui/ui = i
|
||||
ui.data["queue"] = -1
|
||||
ui.push_change()
|
||||
return
|
||||
|
||||
download_queue -= name
|
||||
download_files -= name
|
||||
queue_size -= PRG.size
|
||||
for(var/i in SSvueui.get_open_uis(src))
|
||||
var/datum/vueui/ui = i
|
||||
ui.data["queue"] -= name
|
||||
ui.push_change()
|
||||
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/process_tick()
|
||||
if(!downloaded_file)
|
||||
if(!queue_size)
|
||||
ui_header = "downloader_finished.gif"
|
||||
return
|
||||
if(download_completion >= downloaded_file.size)
|
||||
complete_file_download()
|
||||
return
|
||||
// Download speed according to connectivity state. NTNet server is assumed to be on unlimited speed so we're limited by our local connectivity
|
||||
download_netspeed = 0
|
||||
// Speed defines are found in misc.dm
|
||||
switch(ntnet_status)
|
||||
if(1)
|
||||
download_netspeed = NTNETSPEED_LOWSIGNAL
|
||||
downstream_variance = 0.3
|
||||
if(2)
|
||||
download_netspeed = NTNETSPEED_HIGHSIGNAL
|
||||
downstream_variance = 0.2
|
||||
if(3)
|
||||
download_netspeed = NTNETSPEED_ETHERNET
|
||||
ui_header = "downloader_running.gif"
|
||||
|
||||
// We recovered connection or started a new download.
|
||||
// So we don't have any bytes yet. We'll get them next time!
|
||||
if (!download_last_update)
|
||||
download_last_update = world.time
|
||||
return
|
||||
|
||||
var/delta = ((rand() - 0.5) * 2) * downstream_variance * download_netspeed
|
||||
//Download speed varies +/- 10% each proc. Adds a more realistic feel
|
||||
|
||||
download_netspeed += delta
|
||||
download_netspeed = round(download_netspeed, 0.002)//3 decimal places
|
||||
|
||||
var/delta_seconds = (world.time - download_last_update) / 10
|
||||
|
||||
download_completion = min(download_completion + delta_seconds * download_netspeed, downloaded_file.size)
|
||||
|
||||
// No connection, so cancel the download.
|
||||
// This is done at the end because of logic reasons.
|
||||
// Trust me, it's fine. - Skull132
|
||||
if (!download_netspeed)
|
||||
download_last_update = 0
|
||||
else
|
||||
download_last_update = world.time
|
||||
|
||||
/datum/computer_file/program/ntnetdownload/Topic(href, href_list)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(href_list["PRG_downloadfile"])
|
||||
if(!downloaded_file)
|
||||
begin_file_download(href_list["PRG_downloadfile"], usr)
|
||||
return TRUE
|
||||
if(href_list["PRG_reseterror"])
|
||||
if(downloaderror)
|
||||
download_completion = 0
|
||||
download_netspeed = 0
|
||||
downloaded_file = null
|
||||
downloaderror = ""
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/nano_module/program/computer_ntnetdownload
|
||||
name = "Network Downloader"
|
||||
var/obj/item/modular_computer/my_computer
|
||||
|
||||
/datum/nano_module/program/computer_ntnetdownload/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
if(program)
|
||||
my_computer = program.computer
|
||||
|
||||
if(!istype(my_computer))
|
||||
return
|
||||
|
||||
var/list/data = list()
|
||||
var/datum/computer_file/program/ntnetdownload/prog = program
|
||||
// For now limited to execution by the downloader program
|
||||
if(!prog || !istype(prog))
|
||||
return
|
||||
if(program)
|
||||
data = list("_PC" = program.get_header_data())
|
||||
|
||||
// This IF cuts on data transferred to client, so i guess it's worth it.
|
||||
if(prog.downloaderror) // Download errored. Wait until user resets the program.
|
||||
data["error"] = prog.downloaderror
|
||||
else if(prog.downloaded_file) // Download running. Wait please..
|
||||
if (ui)
|
||||
ui.set_auto_update(TRUE)
|
||||
data["downloadname"] = prog.downloaded_file.filename
|
||||
data["downloaddesc"] = prog.downloaded_file.filedesc
|
||||
data["downloadsize"] = prog.downloaded_file.size
|
||||
data["downloadspeed"] = prog.download_netspeed //Even if it does update every 2 seconds, this is bad coding on everyone's count. :ree:
|
||||
data["downloadcompletion"] = round(prog.download_completion, 0.01)
|
||||
else // No download running, pick file.
|
||||
if (ui)
|
||||
ui.set_auto_update(FALSE)//No need for auto updating on the software menu
|
||||
data["disk_size"] = my_computer.hard_drive.max_capacity
|
||||
data["disk_used"] = my_computer.hard_drive.used_capacity
|
||||
if(my_computer.enrolled == 2) //To lock installation of software on work computers until the IT Department is properly implemented - Then check for access on enrolled computers
|
||||
data += get_programlist(user)
|
||||
else
|
||||
data["downloadable_programs"] = list()
|
||||
data["locked"] = TRUE
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "ntnet_downloader.tmpl", "NTNet Download Program", 575, 700, state = state)
|
||||
ui.auto_update_layout = TRUE
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(TRUE)
|
||||
|
||||
|
||||
/datum/nano_module/program/computer_ntnetdownload/proc/get_programlist(var/mob/user)
|
||||
var/list/all_entries[0]
|
||||
var/datum/computer_file/program/ntnetdownload/prog = program
|
||||
var/list/data = list()
|
||||
data["hackedavailable"] = FALSE
|
||||
for(var/datum/computer_file/program/P in ntnet_global.available_station_software)
|
||||
var/installed = FALSE
|
||||
for(var/datum/computer_file/program/Q in program.hard_drive.stored_files)
|
||||
if(istype(P, Q.type))
|
||||
installed = TRUE
|
||||
if(download_queue[active_download] == null)
|
||||
for(var/name in download_queue)
|
||||
if(download_queue[name] >= 0)
|
||||
active_download = name
|
||||
break
|
||||
if(download_queue[active_download] == null)
|
||||
return
|
||||
|
||||
if(!installed)
|
||||
// Only those programs our user can run will show in the list
|
||||
if(!P.can_download(user) && P.requires_access_to_download)
|
||||
continue
|
||||
var/datum/computer_file/active_download_file = download_files[active_download]
|
||||
if(download_queue[active_download] >= 0)
|
||||
if (!last_update)
|
||||
last_update = world.time
|
||||
return
|
||||
speed = 0
|
||||
var/variance = 0.1
|
||||
switch(ntnet_status)
|
||||
if(1)
|
||||
speed = NTNETSPEED_LOWSIGNAL
|
||||
variance = 0.3
|
||||
if(2)
|
||||
speed = NTNETSPEED_HIGHSIGNAL
|
||||
variance = 0.2
|
||||
if(3)
|
||||
speed = NTNETSPEED_ETHERNET
|
||||
|
||||
if(!P.is_supported_by_hardware(program.computer.hardware_flag))
|
||||
continue
|
||||
var/delta = ((rand() - 0.5) * 2) * variance * speed
|
||||
//Download speed varies +/- 10% each proc. Adds a more realistic feels
|
||||
speed += delta
|
||||
speed = round(speed, 0.002)//3 decimal places
|
||||
|
||||
all_entries.Add(list(list(
|
||||
"filename" = P.filename,
|
||||
"filedesc" = P.filedesc,
|
||||
"fileinfo" = P.extended_desc,
|
||||
"size" = P.size
|
||||
)))
|
||||
var/delta_seconds = (world.time - last_update) / 10
|
||||
|
||||
if(prog.computer_emagged) // If we are running on emagged computer we have access to some "bonus" software
|
||||
var/list/hacked_programs[0]
|
||||
for(var/datum/computer_file/program/P in ntnet_global.available_antag_software)
|
||||
var/installed = FALSE
|
||||
for(var/datum/computer_file/program/Q in program.hard_drive.stored_files)
|
||||
if(istype(P, Q.type))
|
||||
installed = TRUE
|
||||
break
|
||||
download_queue[active_download] = min(download_queue[active_download] + delta_seconds * speed, active_download_file.size)
|
||||
|
||||
if(!installed)
|
||||
data["hackedavailable"] = TRUE
|
||||
hacked_programs.Add(list(list(
|
||||
"filename" = P.filename,
|
||||
"filedesc" = P.filedesc,
|
||||
"fileinfo" = P.extended_desc,
|
||||
"size" = P.size
|
||||
)))
|
||||
data["hacked_programs"] = hacked_programs
|
||||
// No connection, so cancel the download.
|
||||
// This is done at the end because of logic reasons.
|
||||
// Trust me, it's fine. - Skull132
|
||||
if (!speed)
|
||||
last_update = 0
|
||||
else
|
||||
last_update = world.time
|
||||
|
||||
|
||||
data["downloadable_programs"] = all_entries
|
||||
return data
|
||||
if(download_queue[active_download] >= active_download_file.size)
|
||||
finish_from_queue(active_download)
|
||||
active_download = null
|
||||
playsound(get_turf(computer), 'sound/machines/ping.ogg', 40, 0)
|
||||
computer.output_message("\icon[computer] <b>[capitalize_first_letters(computer)]</b> pings, \"Software download completed successfully!\"", 1)
|
||||
|
||||
SSvueui.check_uis_for_change(src)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user