This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Lyinginbedmon's profile picture

[Question] Using ccSensors for tracking players in SMP

Started by Lyinginbedmon, 03 September 2012 - 11:36 PM
Lyinginbedmon #1
Posted 04 September 2012 - 01:36 AM
For an SMP server, I'm trying to create a proximity sensor-based system to track specific players and display their names and locations on a monitor, however I'm having trouble drawing any useful information from the sensors. I've looked over several tutorials on the matter, each with different methodologies, but to no avail. I have at one time managed to retrieve a number of targets which even then only retreived my own username on rare occasion, seemingly dependent on my momentary position.

Previously, my experience has revolved largely around timers, bundled wires, and especially turtles, but I'm rather baffled by the API usage for this peripheral addon. I surmise that I'll need to loop through the available targets from all the sensors on the network for the different players to retrieve their details, and I'm fairly capable of doing the framework for that but for knowing how to actually work with the sensors themselves.

So basically, I need to know the following:
How do I retrieve specific information from sensors?
What information is available to Proximity sensors (and how do I retrieve detail X from the sensor data)
Is there any particular method I should be advised to use for this implementation?
evilguard #2
Posted 04 September 2012 - 02:20 AM
i'm not good with code but i'm a smart guy :D/>/> I wonder. Do the target need to don't know that you fellow him?

Cause if its for exemple for keeping a track of where mod/admin are on the map, or to track someone on a maze for exemple you should probably use that :

http://www.computercraft.info/forums2/index.php?/topic/3728-mc-125-cc-141-immibiss-peripherals/

Since Rfid can be detected from some distance you could write a card for a player and set multiple rfid reader with wifi. So you could have information on where the card was detected. But its impossible to do if the target need to not know that you fellow him :P/>/>
Lyinginbedmon #3
Posted 04 September 2012 - 11:13 AM
The intention is that the targets not be aware of the tracking system, so RFID is somewhat unfeasible
Lyinginbedmon #4
Posted 06 September 2012 - 01:15 AM
Okay, I've managed to make a little progress thanks to the 11lol video by Darkblade on tracking mobs with the proximity sensor. I've managed to repurpose the code for tracking players, but whilst this code works more or less fine in single player Tekkit it works less effectively in SMP, I presume because the type identifier for players is different. However, using either avq (which worked in SSP) or EntityPlayer (which seems to be what SMP defines it as) returns nothing regardless of actual player presence. I'm also having trouble extracting other variables, username in particular.
ctrl = sensors.getController()
sensor = "Sensor"
targ = "LivingEntities"

term.clear()
term.setCursorPos(1,1)
print("Player located at:")

while true do
   targets = sensors.getAvailableTargetsforProbe(ctrl,sensor,targ)
   for i,val in ipairs(targets) do
-- 	 print(val)
	  what,x,y,z = string.match(val,"([a-z]+),(-?[0-9]+),(-?[0-9]+), (-?[0-9]+)")
	  x,y,z=tonumber(x),tonumber(y),tonumber(z)
	  if what == "vq" or what == "EntityPlayer" then
		 term.setCursorPos(1,2)
		 term.clearLine()
		
		 print(x..", "..y..", "..z)
		 redstone.setOutput("left",true)
		 sleep(0.01)
   end
   redstone.setOutput("left",false)
   sleep(0.01)
end
Lyinginbedmon #5
Posted 14 September 2012 - 09:08 PM
Right, advancement! I've gotten a working one-player-only version that incorporates a separate function for updating a list of player locations. However, it seems to crash right as it tries to retrieve the reading from the sensor.
function checkTargets( Sensor )
   targets = sensors.getAvailableTargetsforProbe(ctrl, Sensor, probe)
   for i,val in ipairs(targets) do
	  what,x,y,z = string.match(val,"([a-z]+), (-?[0-9]+), (-?[0-9]+), (-?[0-9])")
	  if what == "vq" then
		 x,y,z = tonumber(x), tonumber(y), tonumber(z)
print("Position data recorded")
		 sensors.setTarget(ctrl,Sensor,i)
print("Sensor target set")
		 local reading = sensors.getReading(ctrl,Sensor)
print("Getting reading of player")
		
		 local Name = reading.name
		 if string.find("Lying") ~= null then
			LyingPos = vector.new(x,y,z)
		 end
	  end
   end
end
The function never prints "getting reading", which leads me to believe there's something majorly off with getReading here. I've used very similar code with a world sensormodule to determine the isRaining value, so I'm not sure what's going off here.
oberjarlerak9039 #6
Posted 15 September 2012 - 05:05 PM
Hi, in the past i've used getReading2(), which requires more parameters and it might work, but i have little experience with this mod

in the api it says

function getReading2(side,sensor,probe,target,…)
result = {peripheral.call( side, "getSensorReading2",sensor,probe,target,…)}
return tabtodict(result)
end
oberjarlerak9039 #7
Posted 15 September 2012 - 07:25 PM
I have a SSP only version that also stops in SMP

for the computer with controller:

--load APIs
os.unloadAPI("sensors")
os.loadAPI("rom/apis/sensors")
-- wireless
rednet.open("top")
--declare constants
scontrol = sensors.getController()
print("Attaching Sensor Controller on "..scontrol.." side")
avSensors = sensors.getSensors(scontrol)
    --get sensors
sUseSensor = avSensors[1]
avProbes = sensors.getProbes(scontrol, sUseSensor)
    --get probes
sPlayer = avProbes[4]
-- end --
   
while true do
for i,val in ipairs(sensors.getAvailableTargetsforProbe(scontrol,sUseSensor,"LivingEntities")) do
what,x,y,z=string.match(val,"([a-z]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+)")
x,y,z=tonumber(x),tonumber(y),tonumber(z)
if (what=="vq") then
rednet.broadcast(""..x..","..y..","..z)
end
end
sleep(0.1)
end
the sleeping is neccesary or it will overload if in a loop

for console on right side of monitor(s):

rednet.open("top")
mon = peripheral.wrap("left")
while true do
a,b,c = rednet.receive()
x = 0
y = 0
z = 0
for d, e, f in string.gmatch(b, "(%w+),(%w+),(%w+)")do
x = d
y = e
z = f
end
mon.setCursorPos(1,1)
mon.clear()
mon.write("x: "..x)
mon.setCursorPos(1,2)
mon.write("y: "..y)
mon.setCursorPos(1,3)
mon.write("z: "..z)
end
i also used part of 11lol's code so thanks to him
Falesh #8
Posted 15 September 2012 - 10:56 PM
I wrote a program which may help as it got any players location and opened a door depending on if they were close enough. I had issues with ccSensors though but that may well be because I was using the Tekkit version and not the latest one.

http://www.computercraft.info/forums2/index.php?/topic/3791-ccsensors-target-identifierdoor-opener/page__p__29259
KaoS #9
Posted 16 September 2012 - 08:24 AM
I wrote a program to detect any entity if it was within the correct area(s), I have yet to use it in multiplayer so it may activate for any entity, if you want to filter it more just replace the 35th line with:

if (b=='Me' and info['name']==playername) or (b=='Them' and info['name']~=playername) then
  rednet.broadcast(info['name']..ref)
end

the code:
Spoiler

local tCDS={
Me={

tc={
x1=590;
x2=590;
y1=5;
y2=5;
z1=283;
z2=283}
};


Them={

trp1={
x1=5;
x2=10;
y1=5;
y2=5;
z1=15;
z2=20}
}}

local function check(info)
for b,a in pairs(tCDS) do
for ref,cds in pairs(a) do
lx=(cds['x1']>=cds['x2'] and cds['x1']) or cds['x2']
sx=(cds['x1']>=cds['x2'] and cds['x2']) or cds['x1']
ly=(cds['y1']>=cds['y2'] and cds['y1']) or cds['y2']
sy=(cds['y1']>=cds['y2'] and cds['y2']) or cds['y1']
lz=(cds['z1']>=cds['z2'] and cds['z1']) or cds['z2']
sz=(cds['z1']>=cds['z2'] and cds['z2']) or cds['z1']
if lx>=info['xCoord'] and sx<=info['xCoord'] and ly>=info['yCoord'] and sy<=info['yCoord'] and lz>=info['zCoord'] and sz<=info['zCoord'] then
rednet.broadcast(ref)
end
end
end
end

rednet.open('top')
local sSide='back'
local sProbe='TargetInfo'
while true do
for _,sSensor in pairs(sensors.getSensors(sSide)) do
for _,sTarget in pairs(sensors.getAvailableTargetsforProbe(sSide,sSensor,sProbe)) do
check(sensors.getSensorReadingAsDict(sSide,sSensor,sTarget,sProbe))
end
end
sleep(0.25)
end

at the top there is a table of co-ordinates to check in the format:
reference={
x1=1;
x2=1;
y1=5;
y2=6;
z1=7;
z2=10}

if a player is detected within those co-ordinates then the reference keyword is broadcasted, this can be used for secret escape routes and the ultimate traps (before I played MC modded I spent my time designing the most sneaky traps I could, it's one of my fascinations), you then have computers awaiting the keyword from the correct computer, ready to open your passage or kill the trespasser in the most imaginatively malicious way possible :)/>/>

EDIT: does anyone have any ideas on how I can improve this system, I have made an addon to output all entities' locations and properties to another PC where they can be monitored.
this system automatically uses all sensors linked to the controller so please only link proximity sensors or make it filter them by name etc

If you want to make it check additional details of the target turn sProbe into tProbe and make it loop through the table using each probe you enter and adding it to the info table