Merge pull request #6553 from Citadel-Station-13/upstream-merge-37165

[MIRROR] NTNet improvements!
This commit is contained in:
deathride58
2018-05-02 01:17:10 +00:00
committed by GitHub
10 changed files with 221 additions and 41 deletions
+3 -1
View File
@@ -1 +1,3 @@
#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation.
#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation.
#define NETWORK_BROADCAST_ID "ALL"
+12 -3
View File
@@ -2,6 +2,9 @@
/datum/proc/ntnet_recieve(datum/netdata/data)
return
/datum/proc/ntnet_recieve_broadcast(datum/netdata/data)
return
/datum/proc/ntnet_send(datum/netdata/data, netid)
GET_COMPONENT(NIC, /datum/component/ntnet_interface)
if(!NIC)
@@ -9,14 +12,17 @@
return NIC.__network_send(data, netid)
/datum/component/ntnet_interface
var/hardware_id //text
var/hardware_id //text. this is the true ID. do not change this. stuff like ID forgery can be done manually.
var/network_name = "" //text
var/list/networks_connected_by_id = list() //id = datum/ntnet
var/differentiate_broadcast = TRUE //If false, broadcasts go to ntnet_recieve. NOT RECOMMENDED.
/datum/component/ntnet_interface/Initialize(force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing!
hardware_id = "[SSnetworks.get_next_HID()]"
network_name = force_name
SSnetworks.register_interface(src)
if(!SSnetworks.register_interface(src))
. = COMPONENT_INCOMPATIBLE
CRASH("Unable to register NTNet interface. Interface deleted.")
if(autoconnect_station_network)
register_connection(SSnetworks.station_network)
@@ -27,7 +33,10 @@
/datum/component/ntnet_interface/proc/__network_recieve(datum/netdata/data) //Do not directly proccall!
parent.SendSignal(COMSIG_COMPONENT_NTNET_RECIEVE, data)
parent.ntnet_recieve(data)
if(differentiate_broadcast && data.broadcast)
parent.ntnet_recieve_broadcast(data)
else
parent.ntnet_recieve(data)
/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall!
// Process data before sending it
+2 -2
View File
@@ -202,8 +202,8 @@
return
// Handle recieved packet.
var/command = lowertext(data.plaintext_data)
var/command_value = lowertext(data.plaintext_data_secondary)
var/command = lowertext(data.data["data"])
var/command_value = lowertext(data.data["data_secondary"])
switch(command)
if("open")
if(command_value == "on" && !density)
+4 -4
View File
@@ -43,13 +43,13 @@
switch(mode)
if(WAND_OPEN)
data.plaintext_data = "open"
data.data["data"] = "open"
if(WAND_BOLT)
data.plaintext_data = "bolt"
data.data["data"] = "bolt"
if(WAND_EMERGENCY)
data.plaintext_data = "emergency"
data.data["data"] = "emergency"
data.plaintext_data_secondary = "toggle"
data.data["data_secondary"] = "toggle"
data.passkey = access_list
ntnet_send(data)
+26 -13
View File
@@ -1,31 +1,46 @@
/datum/netdata //this requires some thought later on but for now it's fine.
var/network_id
var/autopasskey = TRUE
var/list/recipient_ids = list()
var/sender_id
var/broadcast = FALSE //Whether this is a broadcast packet.
var/plaintext_data
var/plaintext_data_secondary
var/encrypted_passkey
var/list/data = list()
var/list/passkey
// Process data before sending it
/datum/netdata/proc/pre_send(datum/component/ntnet_interface/interface)
// Decrypt the passkey.
if(encrypted_passkey && !passkey)
var/result = XorEncrypt(hextostr(encrypted_passkey, TRUE), SScircuit.cipherkey)
if(length(result) > 1)
passkey = json_decode(XorEncrypt(hextostr(encrypted_passkey, TRUE), SScircuit.cipherkey))
if(autopasskey)
if(data["encrypted_passkey"] && !passkey)
var/result = XorEncrypt(hextostr(data["encrypted_passkey"], TRUE), SScircuit.cipherkey)
if(length(result) > 1)
passkey = json_decode(XorEncrypt(hextostr(data["encrypted_passkey"], TRUE), SScircuit.cipherkey))
// Encrypt the passkey.
if(!encrypted_passkey && passkey)
encrypted_passkey = strtohex(XorEncrypt(json_encode(passkey), SScircuit.cipherkey))
// Encrypt the passkey.
if(!data["encrypted_passkey"] && passkey)
data["encrypted_passkey"] = strtohex(XorEncrypt(json_encode(passkey), SScircuit.cipherkey))
// If there is no sender ID, set the default one.
if(!sender_id && interface)
sender_id = interface.hardware_id
/datum/netdata/proc/standard_format_data(primary, secondary, passkey)
data["data"] = primary
data["data_secondary"] = secondary
data["encrypted_passkey"] = passkey
/datum/netdata/proc/json_to_data(json)
data = json_decode(json)
/datum/netdata/proc/json_append_to_data(json)
data |= json_decode(json)
/datum/netdata/proc/data_to_json()
return json_encode(data)
/datum/netdata/proc/json_list_generation_admin() //for admin logs and such.
. = list()
@@ -40,9 +55,7 @@
. = list()
.["recipient_ids"] = recipient_ids
.["sender_id"] = sender_id
.["data"] = plaintext_data
.["data_secondary"] = plaintext_data_secondary
.["passkey"] = encrypted_passkey
.["data_list"] = data
/datum/netdata/proc/generate_netlog()
return "[json_encode(json_list_generation_netlog())]"
+74 -5
View File
@@ -1,6 +1,11 @@
/datum/ntnet
var/network_id = "Network"
var/connected_interfaces_by_id = list() //id = datum/component/ntnet_interface
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()
@@ -32,7 +37,18 @@
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
@@ -43,15 +59,68 @@
/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)
data.network_id = src
log_data_transfer(data)
if(!check_relay_operation())
return FALSE
for(var/i in data.recipient_ids)
var/datum/component/ntnet_interface/reciever = find_interface_id(i)
data.network_id = src
log_data_transfer(data)
var/list/datum/component/ntnet_interface/recieving = 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)
recieving |= connected_interfaces_by_id[i]
else
for(var/i in data.recipient_ids)
var/datum/component/ntnet_interface/reciever = find_interface_id(i)
recieving |= reciever
for(var/i in recieving)
var/datum/component/ntnet_interface/reciever = i
if(reciever)
reciever.__network_recieve(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.
+38
View File
@@ -0,0 +1,38 @@
/datum/ntnet_service
var/name = "Unidentified Network Service"
var/id
var/list/networks_by_id = list() //Yes we support multinetwork services!
/datum/ntnet_service/New()
var/datum/component/ntnet_interface/N = AddComponent(/datum/component/ntnet_interface, id, name, FALSE)
id = N.hardware_id
/datum/ntnet_service/Destroy()
for(var/i in networks_by_id)
var/datum/ntnet/N = i
disconnect(N, TRUE)
networks_by_id = null
return ..()
/datum/ntnet_service/proc/connect(datum/ntnet/net)
if(!istype(net))
return FALSE
GET_COMPONENT(interface, /datum/component/ntnet_interface)
if(!interface.register_connection(net))
return FALSE
if(!net.register_service(src))
interface.unregister_connection(net)
return FALSE
networks_by_id[net.network_id] = net
return TRUE
/datum/ntnet_service/proc/disconnect(datum/ntnet/net, force = FALSE)
if(!istype(net) || (!net.unregister_service(src) && !force))
return FALSE
GET_COMPONENT(interface, /datum/component/ntnet_interface)
interface.unregister_connection(net)
networks_by_id -= net.network_id
return TRUE
/datum/ntnet_service/proc/ntnet_intercept(datum/netdata/data, datum/ntnet/net, datum/component/ntnet_interface/sender)
return
@@ -150,7 +150,7 @@
/obj/item/integrated_circuit/input/slime_scanner
name = "slime_scanner"
desc = "A very small version of the xenobio analyser. This allows the machine to know every needed properties of slime."
desc = "A very small version of the xenobio analyser. This allows the machine to know every needed properties of slime. Output mutation list is non associative."
icon_state = "medscan_adv"
complexity = 12
inputs = list("target" = IC_PINTYPE_REF)
@@ -259,7 +259,7 @@
/obj/item/integrated_circuit/input/gene_scanner
name = "gene scanner"
desc = "This circuit will scan plant for traits and reagent genes."
desc = "This circuit will scan plant for traits and reagent genes. Output is non-associative."
extended_desc = "This allows the machine to scan plants in trays for reagent and trait genes. \
It cannot scan seeds nor fruits, only plants."
inputs = list(
@@ -501,7 +501,7 @@
complexity = 6
name = "list advanced locator"
desc = "This is needed for certain devices that demand list of names for a targets to act upon. This type locates something \
that is standing in given radius up to 8 meters"
that is standing in given radius up to 8 meters. Output is non-associative. Input will only consider keys if associative."
extended_desc = "The first pin requires a list of kinds of objects that you want the locator to acquire. It will locate nearby objects by name and description, \
and will then provide a list of all found objects which are similar. \
The second pin is a radius."
@@ -700,8 +700,8 @@
will pulse whatever's connected to it. Pulsing the first activation pin will send a message. Message \
can be send to multiple recepients. Addresses must be separated with ; symbol."
icon_state = "signal"
complexity = 4
cooldown_per_use = 5
complexity = 2
cooldown_per_use = 1
inputs = list(
"target NTNet addresses"= IC_PINTYPE_STRING,
"data to send" = IC_PINTYPE_STRING,
@@ -712,19 +712,20 @@
"address received" = IC_PINTYPE_STRING,
"data received" = IC_PINTYPE_STRING,
"secondary text received" = IC_PINTYPE_STRING,
"passkey" = IC_PINTYPE_STRING
"passkey" = IC_PINTYPE_STRING,
"is_broadcast" = IC_PINTYPE_BOOLEAN
)
activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
action_flags = IC_ACTION_LONG_RANGE
power_draw_per_use = 50
var/datum/ntnet_connection/exonet = null
var/address
/obj/item/integrated_circuit/input/ntnet_packet/Initialize()
. = ..()
var/datum/component/ntnet_interface/net = LoadComponent(/datum/component/ntnet_interface)
address = net.hardware_id
net.differentiate_broadcast = FALSE
desc += "<br>This circuit's NTNet hardware address is: [address]"
/obj/item/integrated_circuit/input/ntnet_packet/do_work()
@@ -735,20 +736,63 @@
var/datum/netdata/data = new
data.recipient_ids = splittext(target_address, ";")
data.plaintext_data = message
data.plaintext_data_secondary = text
data.encrypted_passkey = key
data.standard_format_data(message, text, key)
ntnet_send(data)
/obj/item/integrated_circuit/input/ntnet_recieve(datum/netdata/data)
set_pin_data(IC_OUTPUT, 1, data.sender_id)
set_pin_data(IC_OUTPUT, 2, data.plaintext_data)
set_pin_data(IC_OUTPUT, 3, data.plaintext_data_secondary)
set_pin_data(IC_OUTPUT, 4, data.encrypted_passkey)
set_pin_data(IC_OUTPUT, 2, data.data["data"])
set_pin_data(IC_OUTPUT, 3, data.data["data_secondary"])
set_pin_data(IC_OUTPUT, 4, data.data["encrypted_passkey"])
set_pin_data(IC_OUTPUT, 5, data.broadcast)
push_data()
activate_pin(2)
/obj/item/integrated_circuit/input/ntnet_advanced
name = "Low level NTNet transreciever"
desc = "Enables the sending and receiving of messages on NTNet via packet data protocol. Allows advanced control of message contents and signalling. Must use associative lists. Outputs associative list. Has a slower transmission rate than normal NTNet circuits, due to increased data processing complexity.."
extended_desc = "Data can be send or received using the second pin on each side, \
with additonal data reserved for the third pin. When a message is received, the second activation pin \
will pulse whatever's connected to it. Pulsing the first activation pin will send a message. Message \
can be send to multiple recepients. Addresses must be separated with ; symbol."
icon_state = "signal"
complexity = 4
cooldown_per_use = 10
inputs = list(
"target NTNet addresses"= IC_PINTYPE_STRING,
"data" = IC_PINTYPE_LIST,
)
outputs = list("recieved data" = IC_PINTYPE_LIST, "is_broadcast" = IC_PINTYPE_BOOLEAN)
activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT)
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
action_flags = IC_ACTION_LONG_RANGE
power_draw_per_use = 50
var/address
/obj/item/integrated_circuit/input/ntnet_advanced/Initialize()
. = ..()
var/datum/component/ntnet_interface/net = LoadComponent(/datum/component/ntnet_interface)
address = net.hardware_id
net.differentiate_broadcast = FALSE
desc += "<br>This circuit's NTNet hardware address is: [address]"
/obj/item/integrated_circuit/input/ntnet_advanced/do_work()
var/target_address = get_pin_data(IC_INPUT, 1)
var/list/message = get_pin_data(IC_INPUT, 2)
if(!islist(message))
message = list()
var/datum/netdata/data = new
data.recipient_ids = splittext(target_address, ";")
data.data = message
ntnet_send(data)
/obj/item/integrated_circuit/input/ntnet_advanced/ntnet_recieve(datum/netdata/data)
set_pin_data(IC_OUTPUT, 1, data.data)
set_pin_data(IC_OUTPUT, 2, data.broadcast)
push_data()
activate_pin(2)
//This circuit gives information on where the machine is.
/obj/item/integrated_circuit/input/gps
name = "global positioning system"
@@ -61,6 +61,10 @@
set_id(suffix || id || "#[mulebot_count]")
suffix = null
/mob/living/simple_animal/bot/mulebot/ComponentInitialize()
. = ..()
AddComponent(/datum/component/ntnet_interface)
/mob/living/simple_animal/bot/mulebot/Destroy()
unload(0)
qdel(wires)