Files
Bubberstation/code/datums/components/ntnet_interface.dm
John Willard f00ca62d08 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.
/🆑
2022-12-06 00:29:31 -08:00

141 lines
5.4 KiB
Plaintext

/*
* Helper function that does 90% of the work in sending a packet
*
* This function gets the component and builds a packet so the sending
* person doesn't have to lift a finger. Just create a netdata datum or even
* just a list and it will send it on its merry way.
*
* Arguments:
* * packet_data - Either a list() or a /datum/netdata. If its netdata, the other args are ignored
* * target_id - Target hardware id or network_id for this packet. If we are a network id, then its
broadcasted to that network.
* * passkey - Authentication for the packet. If the target doesn't authenticate the packet is dropped
*/
/datum/proc/ntnet_send(packet_data, target_id = null, passkey = null)
var/datum/netdata/data = packet_data
if(!istype(data)) // construct netdata from list()
if(!islist(packet_data))
stack_trace("ntnet_send: Bad packet creation") // hard fail as its runtime fault
return
data = new(packet_data)
data.receiver_id = target_id
data.passkey = passkey
var/datum/component/ntnet_interface/NIC = GetComponent(/datum/component/ntnet_interface)
if(!NIC)
return NETWORK_ERROR_NOT_ON_NETWORK
data.sender_id = NIC.hardware_id
data.network_id = NIC.network.network_id
data.receiver_id ||= data.network_id
return SSnetworks.transmit(data)
/*
* # /datum/component/ntnet_interface
*
* This component connects a obj/datum to the station network.
*
* Anything can be connected to the station network. Any obj can auto connect as long as its network_id
* var is set before the parent new is called. This allows map objects to be connected. Technically the
* component only handles getting you on the network while SSnetwork and datum/ntnet does all the real work.
* There are quite a few stack_traces in here. This is because error checking should be done before this component is
* added. Also, there never should be a component that has no network. If it needs a network assign it to LIMBO
*
*/
/datum/component/ntnet_interface
var/hardware_id = null // text. this is the true ID. do not change this. stuff like ID forgery can be done manually.
var/id_tag = null // named tag, mainly used to look up mapping objects
var/datum/ntnet/network = null // network we are on, we MUST be on a network or there is no point in this component
var/list/registered_sockets = list()// list of ports opened up on devices
var/list/alias = list() // if we live in more than one network branch
/**
* Initialize for the interface
*
* Assigns a hardware id and gets your object onto the network
*
* Arguments:
* * network_name - Fully qualified network id of the network we are joining
* * network_tag - The objects id_tag. Used for finding the device at mapload time
*/
/datum/component/ntnet_interface/Initialize(network_name, network_tag = null)
if(network_name == null || !istext(network_name))
log_telecomms("ntnet_interface/Initialize: Bad network '[network_name]' for '[parent]', going to limbo it")
network_name = LIMBO_NETWORK_ROOT
// Tags cannot be numbers and must be unique over the world
if(network_tag != null && !istext(network_tag))
// numbers are not allowed as lookups for interfaces
log_telecomms("Tag cannot be a number? '[network_name]' for '[parent]', going to limbo it")
network_tag = "BADTAG_" + network_tag
hardware_id = SSnetworks.get_next_HID()
id_tag = network_tag
SSnetworks.interfaces_by_hardware_id[hardware_id] = src
network = SSnetworks.create_network_simple(network_name)
network.add_interface(src)
/**
* Create a port for this interface
*
* A port is basicity a shared associated list() with some values that
* indicated its been updated. (see _DEFINES/network.dm). By using a shared
* we don't have to worry about qdeling this object if it goes out of scope.
*
* Once a port is created any number of devices can use the port, however only
* the creating interface can disconnect it.
*
* Arguments:
* * port - text, Name of the port installed on this interface
* * data - list, shared list of data. Don't put objects in this
*/
/datum/component/ntnet_interface/proc/register_port(port, list/data)
if(!port || !length(data))
stack_trace("port is null or data is empty")
return
if(registered_sockets[port])
stack_trace("port already regestered")
return
data["_updated"] = FALSE
registered_sockets[port] = data
/**
* Disconnects an existing port in the interface
*
* Removes a port from this interface and marks it that its
* has been disconnected
*
* Arguments:
* * port - text, Name of the port installed on this interface
* * data - list, shared list of data. Don't put objects in this
*/
/datum/component/ntnet_interface/proc/deregister_port(port)
if(registered_sockets[port]) // should I runtime if this isn't in here?
var/list/datalink = registered_sockets[port]
NETWORK_PORT_DISCONNECT(datalink)
// this should remove all outstanding ports
registered_sockets.Remove(port)
/**
* Connect to a port on this interface
*
* Returns the shared list that this interface uses to send
* data though a port.
*
* Arguments:
* * port - text, Name of the port installed on this interface
*/
/datum/component/ntnet_interface/proc/connect_port(port)
return registered_sockets[port]
/datum/component/ntnet_interface/Destroy()
network.remove_interface(src, TRUE)
SSnetworks.interfaces_by_hardware_id.Remove(hardware_id)
for(var/port in registered_sockets)
var/list/datalink = registered_sockets[port]
NETWORK_PORT_DISCONNECT(datalink)
registered_sockets.Cut()
return ..()