Files
S.P.L.U.R.T-Station-13/code/modules/NTNet/network.dm
2020-01-22 20:17:42 +01:00

257 lines
8.8 KiB
Plaintext

/datum/ntnet
var/network_id = "Network"
var/list/connected_interfaces_by_id = list() //id = datum/component/ntnet_interface
var/list/services_by_path = list() //type = datum/ntnet_service
var/list/services_by_id = list() //id = datum/ntnet_service
var/list/autoinit_service_paths = list() //typepaths
var/list/relays = list()
var/list/logs = list()
var/list/available_station_software = list()
var/list/available_antag_software = list()
var/list/chat_channels = list()
var/list/fileservers = list()
// Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly.
// High values make displaying logs much laggier.
var/setting_maxlogcount = 100
// These only affect wireless. LAN (consoles) are unaffected since it would be possible to create scenario where someone turns off NTNet, and is unable to turn it back on since it refuses connections
var/setting_softwaredownload = TRUE
var/setting_peertopeer = TRUE
var/setting_communication = TRUE
var/setting_systemcontrol = TRUE
var/setting_disabled = FALSE // Setting to 1 will disable all wireless, independently on relays status.
var/intrusion_detection_enabled = TRUE // Whether the IDS warning system is enabled
var/intrusion_detection_alarm = FALSE // Set when there is an IDS warning due to malicious (antag) software.
// If new NTNet datum is spawned, it replaces the old one.
/datum/ntnet/New(_netid)
build_software_lists()
add_log("NTNet logging system activated.")
if(_netid)
network_id = _netid
if(!SSnetworks.register_network(src))
stack_trace("Network [type] with ID [network_id] failed to register and has been deleted.")
qdel(src)
/datum/ntnet/Destroy()
for(var/i in connected_interfaces_by_id)
var/datum/component/ntnet_interface/I = i
I.unregister_connection(src)
for(var/i in services_by_id)
var/datum/ntnet_service/S = i
S.disconnect(src, TRUE)
return ..()
/datum/ntnet/proc/interface_connect(datum/component/ntnet_interface/I)
if(connected_interfaces_by_id[I.hardware_id])
return FALSE
connected_interfaces_by_id[I.hardware_id] = I
return TRUE
/datum/ntnet/proc/interface_disconnect(datum/component/ntnet_interface/I)
connected_interfaces_by_id -= I.hardware_id
return TRUE
/datum/ntnet/proc/find_interface_id(id)
return connected_interfaces_by_id[id]
/datum/ntnet/proc/find_service_id(id)
return services_by_id[id]
/datum/ntnet/proc/find_service_path(path)
return services_by_path[path]
/datum/ntnet/proc/register_service(datum/ntnet_service/S)
if(!istype(S))
return FALSE
if(services_by_path[S.type] || services_by_id[S.id])
return FALSE
services_by_path[S.type] = S
services_by_id[S.id] = S
return TRUE
/datum/ntnet/proc/unregister_service(datum/ntnet_service/S)
if(!istype(S))
return FALSE
services_by_path -= S.type
services_by_id -= S.id
return TRUE
/datum/ntnet/proc/create_service(type)
var/datum/ntnet_service/S = new type
if(!istype(S))
return FALSE
. = S.connect(src)
if(!.)
qdel(S)
/datum/ntnet/proc/destroy_service(type)
var/datum/ntnet_service/S = find_service_path(type)
if(!istype(S))
return FALSE
. = S.disconnect(src)
if(.)
qdel(src)
/datum/ntnet/proc/process_data_transmit(datum/component/ntnet_interface/sender, datum/netdata/data)
if(!check_relay_operation())
return FALSE
data.network_id = src
log_data_transfer(data)
var/list/datum/component/ntnet_interface/receiving = list()
if((length(data.recipient_ids == 1) && data.recipient_ids[1] == NETWORK_BROADCAST_ID) || data.recipient_ids == NETWORK_BROADCAST_ID)
data.broadcast = TRUE
for(var/i in connected_interfaces_by_id)
receiving |= connected_interfaces_by_id[i]
else
for(var/i in data.recipient_ids)
var/datum/component/ntnet_interface/receiver = find_interface_id(i)
receiving |= receiver
for(var/i in receiving)
var/datum/component/ntnet_interface/receiver = i
if(receiver)
receiver.__network_receive(data)
for(var/i in services_by_id)
var/datum/ntnet_service/serv = services_by_id[i]
serv.ntnet_intercept(data, src, sender)
return TRUE
/datum/ntnet/proc/check_relay_operation(zlevel) //can be expanded later but right now it's true/false.
for(var/i in relays)
var/obj/machinery/ntnet_relay/n = i
if(zlevel && n.z != zlevel)
continue
if(n.is_operational())
return TRUE
return FALSE
/datum/ntnet/proc/log_data_transfer(datum/netdata/data)
logs += "[STATION_TIME_TIMESTAMP("hh:mm:ss")] - [data.generate_netlog()]"
if(logs.len > setting_maxlogcount)
logs = logs.Copy(logs.len - setting_maxlogcount, 0)
return
// Simplified logging: Adds a log. log_string is mandatory parameter, source is optional.
/datum/ntnet/proc/add_log(log_string, obj/item/computer_hardware/network_card/source = null)
var/log_text = "[STATION_TIME_TIMESTAMP("hh:mm:ss")] - "
if(source)
log_text += "[source.get_network_tag()] - "
else
log_text += "*SYSTEM* - "
log_text += log_string
logs.Add(log_text)
// We have too many logs, remove the oldest entries until we get into the limit
if(logs.len > setting_maxlogcount)
logs = logs.Copy(logs.len-setting_maxlogcount,0)
// Checks whether NTNet operates. If parameter is passed checks whether specific function is enabled.
/datum/ntnet/proc/check_function(specific_action = 0)
if(!relays || !relays.len) // No relays found. NTNet is down
return FALSE
// Check all relays. If we have at least one working relay, network is up.
if(!check_relay_operation())
return FALSE
if(setting_disabled)
return FALSE
switch(specific_action)
if(NTNET_SOFTWAREDOWNLOAD)
return setting_softwaredownload
if(NTNET_PEERTOPEER)
return setting_peertopeer
if(NTNET_COMMUNICATION)
return setting_communication
if(NTNET_SYSTEMCONTROL)
return setting_systemcontrol
return TRUE
// Builds lists that contain downloadable software.
/datum/ntnet/proc/build_software_lists()
available_station_software = list()
available_antag_software = list()
for(var/F in typesof(/datum/computer_file/program))
var/datum/computer_file/program/prog = new F
// Invalid type (shouldn't be possible but just in case), invalid filetype (not executable program) or invalid filename (unset program)
if(!prog || prog.filename == "UnknownProgram" || prog.filetype != "PRG")
continue
// Check whether the program should be available for station/antag download, if yes, add it to lists.
if(prog.available_on_ntnet)
available_station_software.Add(prog)
if(prog.available_on_syndinet)
available_antag_software.Add(prog)
// Attempts to find a downloadable file according to filename var
/datum/ntnet/proc/find_ntnet_file_by_name(filename)
for(var/N in available_station_software)
var/datum/computer_file/program/P = N
if(filename == P.filename)
return P
for(var/N in available_antag_software)
var/datum/computer_file/program/P = N
if(filename == P.filename)
return P
/datum/ntnet/proc/get_chat_channel_by_id(id)
for(var/datum/ntnet_conversation/chan in chat_channels)
if(chan.id == id)
return chan
// Resets the IDS alarm
/datum/ntnet/proc/resetIDS()
intrusion_detection_alarm = FALSE
/datum/ntnet/proc/toggleIDS()
resetIDS()
intrusion_detection_enabled = !intrusion_detection_enabled
// Removes all logs
/datum/ntnet/proc/purge_logs()
logs = list()
add_log("-!- LOGS DELETED BY SYSTEM OPERATOR -!-")
// Updates maximal amount of stored logs. Use this instead of setting the number, it performs required checks.
/datum/ntnet/proc/update_max_log_count(lognumber)
if(!lognumber)
return FALSE
// Trim the value if necessary
lognumber = max(MIN_NTNET_LOGS, min(lognumber, MAX_NTNET_LOGS))
setting_maxlogcount = lognumber
add_log("Configuration Updated. Now keeping [setting_maxlogcount] logs in system memory.")
/datum/ntnet/proc/toggle_function(function)
if(!function)
return
function = text2num(function)
switch(function)
if(NTNET_SOFTWAREDOWNLOAD)
setting_softwaredownload = !setting_softwaredownload
add_log("Configuration Updated. Wireless network firewall now [setting_softwaredownload ? "allows" : "disallows"] connection to software repositories.")
if(NTNET_PEERTOPEER)
setting_peertopeer = !setting_peertopeer
add_log("Configuration Updated. Wireless network firewall now [setting_peertopeer ? "allows" : "disallows"] peer to peer network traffic.")
if(NTNET_COMMUNICATION)
setting_communication = !setting_communication
add_log("Configuration Updated. Wireless network firewall now [setting_communication ? "allows" : "disallows"] instant messaging and similar communication services.")
if(NTNET_SYSTEMCONTROL)
setting_systemcontrol = !setting_systemcontrol
add_log("Configuration Updated. Wireless network firewall now [setting_systemcontrol ? "allows" : "disallows"] remote control of station's systems.")
/datum/ntnet/station
network_id = "SS13-NTNET"
/datum/ntnet/station/proc/register_map_supremecy() //called at map init to make this what station networks use.
for(var/obj/machinery/ntnet_relay/R in GLOB.machines)
relays.Add(R)
R.NTNet = src