Files
CHOMPStation2/code/modules/modular_computers/file_system/programs/generic/nttransfer.dm
2024-12-01 18:31:19 +01:00

177 lines
6.4 KiB
Plaintext

var/global/nttransfer_uid = 0
/datum/computer_file/program/nttransfer
filename = "nttransfer"
filedesc = "NTNet P2P Transfer Client"
extended_desc = "This program allows for simple file transfer via direct peer to peer connection."
program_icon_state = "comm_logs"
program_key_state = "generic_key"
program_menu_icon = "transferthick-e-w"
size = 7
requires_ntnet = TRUE
requires_ntnet_feature = NTNET_PEERTOPEER
network_destination = "other device via P2P tunnel"
available_on_ntnet = TRUE
tgui_id = "NtosNetTransfer"
category = PROG_UTIL
var/error = "" // Error screen
var/server_password = "" // Optional password to download the file.
var/datum/computer_file/provided_file = null // File which is provided to clients.
var/datum/computer_file/downloaded_file = null // File which is being downloaded
var/list/connected_clients = list() // List of connected clients.
var/datum/computer_file/program/nttransfer/remote // Client var, specifies who are we downloading from.
var/download_completion = 0 // Download progress in GQ
var/actual_netspeed = 0 // Displayed in the UI, this is the actual transfer speed.
var/unique_token // UID of this program
var/upload_menu = FALSE // Whether we show the program list and upload menu
/datum/computer_file/program/nttransfer/New()
unique_token = nttransfer_uid
nttransfer_uid++
..()
/datum/computer_file/program/nttransfer/process_tick()
..()
// Server mode
if(provided_file)
for(var/datum/computer_file/program/nttransfer/C in connected_clients)
// Transfer speed is limited by device which uses slower connectivity.
// We can have multiple clients downloading at same time, but let's assume we use some sort of multicast transfer
// so they can all run on same speed.
C.actual_netspeed = min(C.ntnet_speed, ntnet_speed)
C.download_completion += C.actual_netspeed
if(C.download_completion >= provided_file.size)
C.finish_download()
else if(downloaded_file) // Client mode
if(!remote)
crash_download("Connection to remote server lost")
/datum/computer_file/program/nttransfer/kill_program(var/forced = 0)
if(downloaded_file) // Client mode, clean up variables for next use
finalize_download()
if(provided_file) // Server mode, disconnect all clients
for(var/datum/computer_file/program/nttransfer/P in connected_clients)
P.crash_download("Connection terminated by remote server")
downloaded_file = null
..(forced)
// Finishes download and attempts to store the file on HDD
/datum/computer_file/program/nttransfer/proc/finish_download()
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(downloaded_file))
error = "I/O Error: Unable to save file. Check your hard drive and try again."
finalize_download()
// Crashes the download and displays specific error message
/datum/computer_file/program/nttransfer/proc/crash_download(var/message)
error = message ? message : "An unknown error has occurred during download"
finalize_download()
// Cleans up variables for next use
/datum/computer_file/program/nttransfer/proc/finalize_download()
if(remote)
remote.connected_clients.Remove(src)
downloaded_file = null
remote = null
download_completion = 0
/datum/computer_file/program/nttransfer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = get_header_data()
data["error"] = error
data["downloading"] = !!downloaded_file
if(downloaded_file)
data["download_size"] = downloaded_file.size
data["download_progress"] = download_completion
data["download_netspeed"] = actual_netspeed
data["download_name"] = "[downloaded_file.filename].[downloaded_file.filetype]"
data["uploading"] = !!provided_file
if(provided_file)
data["upload_uid"] = unique_token
data["upload_clients"] = connected_clients.len
data["upload_haspassword"] = server_password ? 1 : 0
data["upload_filename"] = "[provided_file.filename].[provided_file.filetype]"
data["upload_filelist"] = list()
if(upload_menu)
var/list/all_files = list()
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
all_files.Add(list(list(
"uid" = F.uid,
"filename" = "[F.filename].[F.filetype]",
"size" = F.size
)))
data["upload_filelist"] = all_files
data["servers"] = list()
if(!(downloaded_file || provided_file || upload_menu))
var/list/all_servers = list()
for(var/datum/computer_file/program/nttransfer/P in ntnet_global.fileservers)
if(!P.provided_file)
continue
all_servers.Add(list(list(
"uid" = P.unique_token,
"filename" = "[P.provided_file.filename].[P.provided_file.filetype]",
"size" = P.provided_file.size,
"haspassword" = P.server_password ? 1 : 0
)))
data["servers"] = all_servers
return data
/datum/computer_file/program/nttransfer/tgui_act(action, list/params, datum/tgui/ui)
if(..())
return TRUE
switch(action)
if("PRG_downloadfile")
for(var/datum/computer_file/program/nttransfer/P in ntnet_global.fileservers)
if(P.unique_token == text2num(params["uid"]))
remote = P
break
if(!remote || !remote.provided_file)
return
if(remote.server_password)
var/pass = sanitize(tgui_input_text(ui.user, "Code 401 Unauthorized. Please enter password:", "Password required"))
if(pass != remote.server_password)
error = "Incorrect Password"
return
downloaded_file = remote.provided_file.clone()
remote.connected_clients.Add(src)
return TRUE
if("PRG_reset")
error = ""
upload_menu = 0
finalize_download()
if(src in ntnet_global.fileservers)
ntnet_global.fileservers.Remove(src)
for(var/datum/computer_file/program/nttransfer/T in connected_clients)
T.crash_download("Remote server has forcibly closed the connection")
provided_file = null
return TRUE
if("PRG_setpassword")
var/pass = sanitize(tgui_input_text(ui.user, "Enter new server password. Leave blank to cancel, input 'none' to disable password.", "Server security", "none"))
if(!pass)
return
if(pass == "none")
server_password = ""
return
server_password = pass
return TRUE
if("PRG_uploadfile")
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
if(F.uid == text2num(params["uid"]))
if(F.unsendable)
error = "I/O Error: File locked."
return
provided_file = F
ntnet_global.fileservers |= src
return
error = "I/O Error: Unable to locate file on hard drive."
return TRUE
if("PRG_uploadmenu")
upload_menu = 1
return TRUE