Files
Bubberstation/code/modules/NTNet/network.dm
SkyratBot 86e811f782 [MIRROR] Adds a modular computer subsystem to shift modPCs away from radios [MDB IGNORE] (#17942)
* Adds a modular computer subsystem to shift modPCs away from radios (#71732)

## About The Pull Request

Adds the modular computer subsystem which is meant to replace mod PC's
reliance on networks and radios, specifically the network subsystem, the
ntnet interface, and /datum/ntnet. This PR removes station_root ntnets
entirely, but I tried to keep it small.

This PR also removes a ton of unused vars and defines, such as NTNet
channels that were unused (peer2peer and systemcontrol), atmos networks
(as they were removed a while ago) and NTNet var on relays (its stated
purpose is so admins can see it through varedits, but that's useless now
that it's a subsystem)

I also removed ``setting_disabled`` as a thing the RD can do, it turned
off ALL ntnet systems. However, this was when there were 4 different
ones, now that there's only 2 I thought it was redundant and he could
just click 2 buttons to close them.

## Why It's Good For The Game

``/datum/ntnet``, ``/datum/component/ntnet_interface``, and
``/datum/controller/subsystem/networks`` are all old-code messes that
depend on eachother and is hard for people to understand what exactly it
adds to the game. 90% of its features is allowing the Wirecarp app to
see all the ruins that spawned in-game, which I don't think is something
that we even WANT (why does the RD need to know that oldstation spawned?
Why should they know this anyway??)

This hopefully starts to simplify networks/ntnet to make it easier to
remove in the future, because surely there are better alternatives than
**this**

## Changelog

🆑
refactor: Modular computers NTnet and applications run on its own
subsystem, please report any new bugs you may find.
/🆑

* Adds a modular computer subsystem to shift modPCs away from radios

* Fixed contractor uplink

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: tastyfish <crazychris32@gmail.com>
2022-12-12 18:36:54 -05:00

212 lines
8.1 KiB
Plaintext

/*
* # /datum/ntnet
*
* This class defines each network of the world. Each root network is accessible by any device
* on the same network but NOT accessible to any other "root" networks. All normal devices only have
* one network and one network_id.
*
* This thing replaces radio. Think of wifi but better, bigger and bolder! The idea is that any device
* on a network can reach any other device on that same network if it knows the hardware_id. You can also
* search or broadcast to devices if you know what branch you wish. That is to say you can broadcast to all
* devices on "SS13.ATMOS.SCRUBBERS" to change the settings of all the scrubbers on the station or to
* "SS13.AREA.FRED_HOME.SCRUBBERS" to all the scrubbers at one area. However devices CANNOT communicate cross
* networks normality.
*
*/
/datum/ntnet
/// The full network name for this network ex. SS13.ATMOS.SCRUBBERS
var/network_id
/// The network name part of this leaf ex ATMOS
var/network_node_id
/// All devices on this network. ALL devices on this network, not just this branch.
/// This list is shared between all leaf networks so we don't have to keep going to the
/// parents on lookups. It is an associated list of hardware_id AND tag_id's
var/list/root_devices
/// This lists has all the networks in this node. Each name is fully qualified
/// ie. SS13.ATMOS.SCRUBBERS, SS13.ATMOS.VENTS, etc
var/list/networks
/// All the devices on this branch of the network
var/list/linked_devices
/// Network children. Associated list using the network_node_id of the child as the key
var/list/children
/// Parrnt of the network. If this is null, we are a oot network
var/datum/ntnet/parent
/*
* Creates a new network
*
* Used for /datum/controller/subsystem/networks/proc/create_network so do not
* call yourself as new doesn't do any checking itself
*
* Arguments:
* * net_id - Fully qualified network id for this network
* * net_part_id - sub part of a network if this is a child of P
* * P - Parent network, this will be attached to that network.
*/
/datum/ntnet/New(net_id, net_part_id, datum/ntnet/P = null)
linked_devices = list()
children = list()
network_id = net_id
if(P)
network_node_id = net_part_id
parent = P
parent.children[network_node_id] = src
root_devices = parent.root_devices
networks = parent.networks
networks[network_id] = src
else
network_node_id = net_id
parent = null
networks = list()
root_devices = linked_devices
SSnetworks.root_networks[network_id] = src
SSnetworks.networks[network_id] = src
SSnetworks.add_log("Network was created: [network_id]")
return ..()
/// A network should NEVER be deleted. If you don't want to show it exists just check if its
/// empty
/datum/ntnet/Destroy(force)
networks -= network_id
if(children.len > 0 || linked_devices.len > 0)
CRASH("Trying to delete a network with devices still in them")
if(parent)
parent.children.Remove(network_id)
parent = null
else
SSnetworks.root_networks.Remove(network_id)
SSnetworks.networks.Remove(network_id)
root_devices = null
networks = null
network_node_id = null
SSnetworks.add_log("Network was destroyed: [network_id]")
network_id = null
return ..()
/*
* Collects all the devices on this branch of the network and maybe its
* children
*
* Used for broadcasting, this will collect all the interfaces on this
* network and by default everything below this branch. Will return an
* empty list if no devices were found
*
* Arguments:
* * include_children - Include the children of all branches below this
*/
/datum/ntnet/proc/collect_interfaces(include_children=TRUE)
if(!include_children || children.len == 0)
return linked_devices.Copy()
else
/// Please no recursion. Byond hates recursion
var/list/devices = list()
var/list/queue = list(src) // add ourselves
while(queue.len)
var/datum/ntnet/net = queue[queue.len--]
if(net.children.len > 0)
for(var/net_id in net.children)
queue += networks[net_id]
devices += net.linked_devices
return devices
/**
* Add this interface to this branch of the network.
*
* This will add a network interface to this branch of the network.
* If the interface already exists on the network it will add it and
* give the alias list in the interface this branch name. If the interface
* has an id_tag it will add that name to the root_devices for map lookup
*
* Arguments:
* * interface - ntnet component of the device to add to the network
*/
/datum/ntnet/proc/add_interface(datum/component/ntnet_interface/interface)
if(interface.network)
/// If we are doing a hard jump to a new network, log it
log_telecomms("The device {[interface.hardware_id]} is jumping networks from '[interface.network.network_id]' to '[network_id]'")
interface.network.remove_interface(interface, TRUE)
interface.network ||= src
interface.alias[network_id] = src // add to the alias just to make removing easier.
linked_devices[interface.hardware_id] = interface
root_devices[interface.hardware_id] = interface
if(interface.id_tag != null) // could be a type, never know
root_devices[interface.id_tag] = interface
/*
* Remove this interface from the network
*
* This will remove an interface from this network and null the network field on the
* interface. Be sure that add_interface is run as soon as posable as an interface MUST
* have a network
*
* Arguments:
* * interface - ntnet component of the device to remove to the network
* * remove_all_alias - remove ALL references to this device on this network
*/
/datum/ntnet/proc/remove_interface(datum/component/ntnet_interface/interface, remove_all_alias=FALSE)
if(!interface.alias[network_id])
log_telecomms("The device {[interface.hardware_id]} is trying to leave a '[network_id]'' when its on '[interface.network.network_id]'")
return
// just cashing it
var/hardware_id = interface.hardware_id
// Handle the quick case
interface.alias.Remove(network_id)
linked_devices.Remove(hardware_id)
if(remove_all_alias)
var/datum/ntnet/net
for(var/id in interface.alias)
net = interface.alias[id]
net.linked_devices.Remove(hardware_id)
// Now check if there are more than meets the eye
if(interface.network == src || remove_all_alias)
// Ok, so we got to remove this network, but if we have an alias we are still "on" the network
// so we need to shift down to one of the other networks on the alias list. If the alias list
// is empty, fuck it and remove it from the network.
if(interface.alias.len > 0)
interface.network = interface.alias[1] // ... whatever is there.
else
// ok, hard remove from everything then
root_devices.Remove(interface.hardware_id)
if(interface.id_tag != null) // could be a type, never know
root_devices.Remove(interface.id_tag)
interface.network = null
/*
* Move interface to another branch of the network
*
* This function is a lightweight way of moving an interface from one branch to another like a gps
* device going from one area to another. Target network MUST be this network or it will fail
*
* Arguments:
* * interface - ntnet component of the device to move
* * target_network - qualified network id to move to
* * original_network - qualified network id from the original network if not this one
*/
/datum/ntnet/proc/move_interface(datum/component/ntnet_interface/interface, target_network, original_network = null)
var/datum/ntnet/net = original_network == null ? src : networks[original_network]
var/datum/ntnet/target = networks[target_network]
if(!target || !net)
log_telecomms("The device {[interface.hardware_id]} is trying to move to a network ([target_network]) that is not on ([network_id])")
return
if(target.linked_devices[interface.hardware_id])
log_telecomms("The device {[interface.hardware_id]} is trying to move to a network ([target_network]) it is already on.")
return
if(!net.linked_devices[interface.hardware_id])
log_telecomms("The device {[interface.hardware_id]} is trying to move to a network ([target_network]) but its not on ([net.network_id]) ")
return
net.linked_devices.Remove(interface.hardware_id)
target.linked_devices[interface.hardware_id] = interface
interface.alias.Remove(net.network_id)
interface.alias[target.network_id] = target