//A packet sniffer!!
/obj/item/device/net_sniffer
name = "Packet Sniffer"
desc = "An electronic device designed to intercept network transmissions."
icon_state = "sniffer0"
item_state = "electronic"
w_class = 4.0
rand_pos = 0
var/mode = 0
var/obj/machinery/power/data_terminal/link = null
var/filter_id = null
var/list/sniffFilters = list()
var/last_intercept = 0
var/list/packet_data = list()
var/max_logs = 8
attack_ai()
return
attack_hand(mob/user as mob)
if(mode)
src.interact(user)
return
else
..()
attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/screwdriver))
if(!mode)
var/turf/T = loc
if(isturf(T) && !T.intact)
var/obj/machinery/power/data_terminal/test_link = locate() in T
if(test_link && !test_link.is_valid_master(test_link.master))
src.link = test_link
src.link.master = src
anchored = 1
mode = 1
user.visible_message("[user] attaches the [src] to the data terminal.","You attach the [src] to the data terminal.")
icon_state = "sniffer1"
else
boutput(user, "The [src] couldn't be attached here!")
return
else
boutput(user, "Device must be placed over a free data terminal to attach to it.")
return
else
anchored = 0
mode = 0
user.visible_message("[user] detaches the [src] from the data terminal.","You detach the [src] from the data terminal.")
icon_state = "sniffer0"
if(src.link)
src.link.master = null
src.link = null
return
else
..()
attack_self(mob/user as mob)
return interact(user)
proc/interact(mob/user as mob)
var/dat = "
Packet Sniffer"
dat += "Current sender filter: [src.filter_id ? src.filter_id : "NONE"]
"
dat += "
Packet log:
"
if(packet_data.len)
for(var/a in packet_data)
dat += "[a]
"
else
dat += "NONE"
dat += "
"
user << browse(dat,"window=packets")
onclose(user,"packets")
return
Topic(href, href_list)
..()
if (usr.contents.Find(src) || usr.contents.Find(src.master) || (istype(src.loc, /turf) && get_dist(src, usr) <= 1))
if (usr.stat || usr.restrained())
return
src.add_fingerprint(usr)
usr.machine = src
if(href_list["filtid"])
var/t = input(usr, "Please enter new filter net id", src.name, src.filter_id) as text
if (!t)
src.filter_id = null
src.updateIntDialog()
return
if (!in_range(src, usr) || usr.stat || usr.restrained())
return
if(length(t) != 8 || !ishex(t))
src.filter_id = null
src.updateIntDialog()
return
src.filter_id = t
src.updateIntDialog()
return
return
proc/updateIntDialog()
if(mode)
src.updateUsrDialog()
else
src.updateSelfDialog()
return
receive_signal(datum/signal/signal)
if(!mode || !src.link)
return
if(!signal || signal.encryption)
return
if(signal.transmission_method != TRANSMISSION_WIRE) //No radio for us thanks
return
var/target = signal.data["address_1"]
if(src.filter_id && src.filter_id != target)
return
var/badcheck = 0
for(var/check in src.sniffFilters)
if(!(check in signal.data) || signal.data[check] != src.filters[check])
badcheck = 1
break
if(badcheck)
return
if(!src.last_intercept || src.last_intercept + 40 <= world.time)
playsound(src.loc, "sound/machines/twobeep.ogg", 25, 1)
//src.packet_data = signal.data:Copy()
var/newdat = "\[[time2text(world.timeofday,"mm:ss")]:[(world.timeofday%10)]\]:"
for (var/i in signal.data)
newdat += "[i][isnull(signal.data[i]) ? "; " : "=[signal.data[i]]; "]"
if (signal.data_file)
. = signal.data_file.asText()
newdat += "
Included file ([signal.data_file.name], [signal.data_file.extension]): [. ? . : "Not printable."]"
src.packet_data += newdat
if (src.packet_data.len > src.max_logs)
src.packet_data.Cut(1,2)
src.last_intercept = world.time
src.updateIntDialog()
return