View difference between Paste ID: D5phjuGj and rWp0GXDW
SHOW: | | - or go back to the newest paste.
1
---------------------------------------------------
2
-- Player Module for CraftNanny
3
-- 	by Demethan
4
-- 	www.breakfastcraft.com
5-
--	www.craftnanny.org
5+
--	www.mrjohndowe.com/craftnanny
6
--	2015-08-13	
7
--		- Fixed inventory compare.
8
--		- post inventory addition with quantities.
9
---------------------------------------------------
10
11
12
-- pastebin for installer
13-
local installer = "Q8ah3K9S"
13+
local installer = "PTGLduYm"
14
-- players ignored by senors
15
local allowedPlayerArray={}
16
-- inventory arrays to compare
17
local snapShot={}
18
local snapShot2={}
19
local itemString={}
20
-- players currently inside sensor range 
21
local flag={}
22
-- counter for scanning animation
23
local heart = 0
24
-- counter for phone_home() 
25
local time = 0
26
-- user token to send to server
27
local token = '0'
28
-- this scanners name
29
local scanner = ''
30
-- owenrs username on website
31
local username = ''
32
-- currently installed version
33
local version = 2
34
35
--Cleanup 
36
if fs.exists("log.txt") then	
37
	ok,msg = pcall (fs.delete,"log.txt")
38
		if msg~=nil then
39
			os.reboot()
40
		end
41
end
42
43
-- write text to the terminal screen
44
function draw_text_term(x, y, text, text_color, bg_color)
45
  term.setTextColor(text_color)
46
  term.setBackgroundColor(bg_color)
47
  term.setCursorPos(x,y)
48
  write(text)
49
end
50
51
-- draw a line on the terminal screen
52
function draw_line_term(x, y, length, color)
53
    term.setBackgroundColor(color)
54
    term.setCursorPos(x,y)
55
    term.write(string.rep(" ", length))
56
end
57
58
function bars()
59
	draw_line_term(1, 1, 51, colors.lime)
60
	draw_line_term(1, 19, 51, colors.lime)
61
	draw_text_term(20, 1, 'Base Scanner', colors.gray, colors.lime)
62-
	draw_text_term(13, 19, 'craftnanny.org', colors.gray, colors.lime)
62+
	draw_text_term(13, 19, 'mrjohndowe.com/craftnanny', colors.gray, colors.lime)
63
end
64
65
function scanner_screen()
66
	term.clear()
67
	
68
	-- scanner info
69
	bars()
70
	draw_text_term(1, 2, 'Scanner: ', colors.lime, colors.black)
71
	draw_text_term(10, 2, scanner, colors.white, colors.black)
72
	draw_text_term(1, 3, 'Owner: ', colors.lime, colors.black)
73
	draw_text_term(8, 3, username, colors.white, colors.black)
74
	draw_text_term(1, 4 , string.rep("-", 51), colors.lime, colors.black)
75
	
76
	-- scanning graphuc
77
	heart = heart + 1
78
	draw_text_term(3, 10, 'Scanning ', colors.red, colors.black)
79
	draw_text_term(12, 10 , string.rep(".", heart), colors.red, colors.black)
80
	if heart == 15 then
81
		heart = 1
82
	end
83
end
84
85
-- retrieves token from local text file
86
-- called at startup if config.txt exists
87
-- token is used to authorize the scanner to post to users log
88
function load_config()
89
  sr = fs.open("config.txt", "r")
90
    token = sr.readLine()
91
	scanner = sr.readLine()
92
	username = sr.readLine()
93
  sr.close()
94
end
95
96
-- called for new installations and when the scanner needs to be updated
97
function run_installer()
98
	if fs.exists("install") then
99
	    fs.delete("install")
100
	  end
101
	  shell.run("pastebin get "..installer.." install")
102
	  sleep(1)
103
	  shell.run("install")
104
end
105
106
-- called every 30 seconds when scanner is running
107
-- tells the server that the scanner is online
108
-- checks version and automtically updates
109
function phone_home()
110-
    response = http.post("http://craftnanny.org/code/ping.php",
110+
    response = http.post("http://mrjohndowe.com/craftnanny/code/ping.php",
111
    			"token="..token.."&id="..os.getComputerID())
112
	current_version = response.readAll()
113
114
	if tonumber(current_version) > version then
115
			run_installer()
116
	end
117
end
118
119
function round(what, precision)
120
   if what==nil then return 0 end
121
   return math.floor(what*math.pow(10,precision)+0.5) / math.pow(10,precision)
122
end
123
124
function record() 
125
	term.setCursorPos(1,1)
126
	players=s.getPlayers()
127
	for num,player in pairs(players) do
128
		for p,ign in pairs(player) do
129
			if p=="name" then
130
				playerData = s.getPlayerByName(ign)
131
				data = playerData.all()
132
				inventory=data.player.inventory
133
				if not allowedPlayerArray[ign] then -- check the allow array
134
					draw_text_term(3, 7, ign.." is not on the allowed list        ", colors.red, colors.black)
135
					invArray={} -- fresh copy
136
					for a,b in pairs(inventory) do --getting player inventory
137
						slot=b.all()
138
						invArray[slot.name]=slot.qty
139
					end
140
					if flag[ign]==nil or not flag[ign] then --recording first inventory scan
141
						itemString=""
142
						snapShot[ign]= invArray
143
						draw_text_term(3, 7, ign..": Initial Snapshot             ", colors.green, colors.black)
144
						post(ign,1," has entered sensor range")
145
						flag[ign]=true -- set player flag for later processing
146
					else
147
						snapShot2[ign]= invArray
148
						draw_text_term(3, 7, ign..": Updated Snapshot             ", colors.green, colors.black)
149
						found,Items=compare(snapShot[ign],snapShot2[ign])
150
151
						if found then
152
							for i,v in pairs(Items) do --building string
153
								if v~="" or v~=nil then 
154
									itemString=" "..v..":"..i..itemString
155
									draw_text_term(6, 7, ign..itemString.." is extra since last snapshot of inventory", colors.orange, colors.black)
156
									post(ign,3,itemString)
157
								end
158
							end
159
							snapShot[ign]=snapShot2[ign]--inventory has been logged, can now reset the initial snapshot
160
							itemString=""
161
						else
162
							--print(ign," - No item found")
163
						end
164
						sleep(1)
165
						
166
						if snapShot2[ign]~= nil then --recoding newer inventory until player leaves.
167
						snapShot2[ign]= nil
168
					end
169
				end		
170
171
				end
172
173
174
			end
175
176
		end
177
	end
178
	--Cleanup
179
	playerData={}
180
	data={}
181
	inventory={}
182
	found=nil
183
184
end
185
186
-- iterate through all players with an active flag
187
-- see if they're still in range of the scanner
188
function leaveCheck()  
189
	for ign,v in pairs(flag) do
190
	--	print("Did ",ign," leave?")
191
		local ok,msg=pcall(function ()s.getPlayerByName(ign) end)
192
		--print(msg) --debug
193
		if not ok and flag[ign] then
194
			--print(ign," has left.")
195
			flag[ign]=false
196
			snapShot[ign]=nil
197
			snapShot2[ign]=nil
198
			post(ign,2," has left sensor range")
199
		end
200
	end
201
end
202
203
-- records a log entry on the server
204
-- passes to server:
205
	-- token and computer ID (used to verify source)
206
	-- event type: 1 = player entering, 2 = player leaving, 3 = inventory change
207
	-- ign, players name
208
	-- discription of event
209
	
210
	
211
function logging(ign, event, description)
212
	if peripheral.getType("right")== "monitor" then
213
		mon = peripheral.wrap("right")
214
	elseif peripheral.getType("left")~="monitor" then
215
		mon = peripheral.wrap("left")
216
	else
217
		return
218
	end
219
  if mon then
220
  	mon.clear()
221
  	mon.setTextScale(0.5)
222
  	monMaxX,monMaxY = mon.getSize()
223
  	print(monMaxX,monMaxY)
224
  	if monMaxX < 61 then
225
  		mon.write("monitor too small. Min 4 wide")
226
  		return
227
  	end
228
  	sw = fs.open("log.txt",fs.exists("log.txt") and "a" or "w")
229
  	line=ign.." "..description
230
  	sw.writeLine(os.day().."/"..os.time()..": "..ign.." "..description)
231
  	sw.close()
232
  	sr = fs.open("log.txt","r")
233
  	monY=1
234
  	msg="starting log..."
235
  	while msg~=nil do 
236
  		ok,msg = pcall(sr.readLine)
237
  		mon.setCursorPos(1,monY)
238
  		mon.write(msg)
239
  		monY=monY+1
240
  	end
241
  	sr.close()
242
end
243
244
end
245
	
246
	
247
	
248
-- e.g. post('tom', 2, ' has left sensor range')
249
function post(ign, event, description)  
250
251-
	        http.post("http://craftnanny.org/code/log.php",
251+
	        http.post("http://mrjohndowe.com/craftnanny/code/log.php",
252
	        "token="..token.."&ign="..ign.."&id="..os.getComputerID().."&event="..event.."&description="..description)
253
			logging(ign, event, description)
254
end
255
256
function tablelength(T) --get real count of table
257
  local count = 0
258
  for _ in pairs(T) do count = count + 1 end
259
  return count
260
end
261
262
function compare(t1,t2)
263
	local ai = {}
264
    local r = {}
265
	table.sort(t1) --sorting by name
266
	table.sort(t2) --sorting by name
267
	
268
	for k,v in pairs(t2) do 
269
		r[k] = v; ai[v]=true 
270
	end
271
	for k,v in pairs(t1) do 
272
		if ai[v]~=nil then   --if item match, remove it from temp table r
273
			r[k]=nil   
274
		end
275
	end
276
	
277
	if tablelength(r) > 0 then --if there are items left in r 
278
		 return true,r
279
	else
280
		return false,nil
281
	end
282
end
283
284
function start_recording()
285
	-- main loop
286
	while true do
287
		-- run scan
288
		ok,msg=pcall(record)
289
		if not ok then 
290
			print(msg)
291
			break
292
		end
293
		leaveCheck()
294
		
295
		-- animate screen and delay
296
		scanner_screen()	
297
		sleep(0.5)
298
		scanner_screen()	
299
		sleep(0.5)
300
		
301
		-- main active status with server
302
		time = time + 1
303
		if time > 30 then
304
			time=0
305
			phone_home()
306
		end
307
	end
308
end
309
310
function start()
311
	s=peripheral.wrap("top")
312
	heart=0
313
	term.clear()
314
	term.setCursorPos(1,1)
315
	
316
  if fs.exists("config.txt") then
317
      load_config()
318
	  start_recording()
319
  else
320
  	  run_installer()
321
  end
322
end
323
324
start()