View difference between Paste ID: Ci2eajXM and 0uAaAcrW
SHOW: | | - or go back to the newest paste.
1
--[[
2
	
3
			--*--*--*--*--*--*--*--*--*--*--*--*--*--*--	
4
			--*			       GCAPI                 *--
5
			--*	    https://pastebin.com/0uAaAcrW    *--
6
			--*			   by: GravityCube           *--
7
			--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
8
9
			
10
	Changelog:
11
		1.0.0 First release
12
		1.1.0 Image displayer for monitors added and bugs in the economy fixed
13
		1.2.0 Tracker of players and chatSpy added, a custom http.get was added and global peripheral.find.
14
		1.3.0 New listener, chatEvents and local admins for selling programs!
15
		1.4.0 Various bugs fixed (repited chatEvents, and rgb api changed). Added version changelog and getVersion()
16
		1.5.0 table.contains added
17
			1.5.1 ChatEvent Listener little fix
18
			1.5.2 Split function modified (self) and getChar added
19
			1.5.3 getCenter added and centered of monitors fixed
20
			1.5.4 getCenter now supports number and string in the #2 argument
21
			1.5.5 Added some default "URLs" to the images
22
			1.5.6 URL Alias updated
23
			1.5.7 Added password for unfiltered tracker (akaElite request)
24
		1.6.0 New method for tracking and some minor modifications.
25
			1.6.1 Some minor changes and bugs fixed
26
		1.7.0 New method gcapi.customMonitorWrite()
27
			1.7.1 Added table.isEmpty
28
			1.7.2 New admin (Freecss).
29
		1.8.0 New method printAvatar()
30
			1.8.1 New function getTime added and seed for random numbers changed.
31
			1.8.2 Added deepCopy function from http://lua-users.org/wiki/CopyTable
32
			1.8.3 An issue with getCenter was solved.
33-
			1.8.4 The method getPlayersPos was deprecated but patched so the tracker could work
33+
34-
			1.8.5 Added getStaffList and filter_list for getPosPlayers
34+
35-
			1.8.6 Added toLower on filter_list
35+
36-
			1.8.7 Migrate jake endpoint to cc.emx.cl
36+
37
--------------------------------------------
38
local debugAPI = false
39
40
local version = "1.8.3"
41
42
print("GCAPI Version: " .. version)
43
44-
local version = "1.8.6"
44+
45
	return version
46
end
47
--------------------------------------------
48
-->              URL ALIAS               <--
49
--------------------------------------------
50
local urlAlias = {
51
	["emx"] = "http://jake.emx.cl/logo.jpg",
52
	["cl"] = "http://craftersland.net/images/logo.png",
53
	["deadpool"] = "http://pixelartmaker.com/art/de17950892c0026.png"
54
}
55
--------------------------------------------
56-
	["cl"] = "https://i.imgur.com/hslZg4j.png",
56+
57-
	["deadpool"] = "https://i.imgur.com/BXq9i6w.png"
57+
58
59
function getTime()
60
	local response = http.get("http://jake.emx.cl/time.php")
61
	if response then
62
		local millis = tonumber(response.readAll())
63
		if millis then
64-
	--local response = http.get("http://jake.emx.cl/time.php")
64+
			return millis, true
65-
	--if response then
65+
66-
	--	local millis = tonumber(response.readAll())
66+
67-
	--	if millis then
67+
68-
	--		return millis, true
68+
69-
	--	end
69+
70-
	--end
70+
71
function customMonitorWrite(mon, text)
72
	local xi, yi = mon.getCursorPos()
73
	local chars = {}
74
	for i = 1, string.len(text) do
75
		local c = text:sub(i,i)
76
		table.insert(chars, c)
77
	end
78
	
79
	--charToColor["g"] = mon.getBackgroundColor()
80
	local isNumber = false
81
	for i=1, #chars, 1 do
82
		local c = chars[i]
83
		if c == "&" and charToColor[chars[i+1]] then
84
			color = 2^chars[i+1]
85
			mon.setBackgroundColor(color)
86
			isNumber = true
87
		else
88
			if not isNumber then
89
				mon.write(c)
90
			end
91
			isNumber = false
92
		end
93
	end
94
end
95
96
97
function verifyVar(rawVar, varType)
98
	if type(rawVar) ~= varType then
99
		error( "bad argument (expected " .. varType .. ", got " .. type( rawVar ) .. ")", 2 )
100
	end
101
end
102
103
-- RANDOM STRING
104
local charset = {}
105
-- qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890
106
for i = 48,  57 do table.insert(charset, string.char(i)) end
107
for i = 65,  90 do table.insert(charset, string.char(i)) end
108
for i = 97, 122 do table.insert(charset, string.char(i)) end
109
110
math.randomseed(getTime())
111
function randomString(length)
112
	if length > 0 then
113
		return string.random(length - 1) .. charset[math.random(1, #charset)]
114-
--math.randomseed(getTime())
114+
115
		return ""
116
	end
117
end
118
string.random = randomString
119
--END RANDOM STRING
120
121
function getRandom(minValue, maxValue)
122
	return math.random(minValue, maxValue)
123
end
124
125
--peripheral.find() in Tekkit
126
function findPeripheral(pType)
127
	local pList = {}
128
	for _,pName in pairs(peripheral.getNames()) do
129
		if peripheral.getType(pName) == pType then
130
			table.insert(pList, peripheral.wrap(pName))
131
		end
132
	end
133
	return unpack(pList)
134
end
135
peripheral.find = findPeripheral
136
137
--Wipe table "t"
138
function wipeTable(t)
139
	local listForDeletion = {}
140
	for k,v in pairs(t) do
141
		table.insert(listForDeletion, k)
142
	end
143
	
144
	for _,i in pairs(listForDeletion) do
145
		t[i] = nil
146
	end
147
end
148
table.wipe = wipeTable
149
150
--Split string
151
function split(self, delimiter)
152
	result = {};
153
	for match in (self..delimiter):gmatch("(.-)"..delimiter) do
154
		table.insert(result, match);
155
	end
156
	return result;
157
end
158
string.split = split
159
160
string.getChar = function (self, nVar)
161
	if type(nVar) ~= "number" then
162
		error( "bad argument #2 (expected number, got " .. type( nVar ) .. ")") 
163
	else 
164
		return self:sub(nVar, nVar) 
165
	end 
166
end
167
168
table.isEmpty = function(self)
169
	for k,v in pairs(self) do
170
		return true
171
	end
172
	return false
173
end
174
175
table.contains = function (self, eVar)
176
	for k,v in pairs(self) do
177
		if v == eVar then
178
			return true
179
		end
180
	end	
181
	return false
182
end
183
184
--Print to a file and term (message, dir(optional) )
185
function printLog(line, dir)
186
	if line == nil then
187
		return nil
188
	end
189
	if dir == nil then
190
		dir = "/log"
191
	end
192
	line = line
193
	print(line)
194
	
195
	file = fs.open(dir,"a")
196
	file.writeLine(line)
197
	file.close()
198
end
199
200
--Are items equal? Ignoring quantity
201
function equalItems(item1, item2)
202
	if item1 == nil or item2 == nil then
203
		return false
204
	end
205
	for k,v in pairs(item1) do
206
		if k ~= qty then
207
			if item2[k] ~= v then
208
				return false
209
			end
210
		end
211
	end
212
	return true
213
end
214
215
--Get number of lines file
216
function getNumberOfLinesFile(filePath)
217
	if not fs.exists(filePath) then
218
		print("[GCAPI] File not found")
219
		return 0
220
	end
221
	file = fs.open(filePath, "r")
222
	if file then
223
		local i = 0
224
		while file.readLine() do
225
			i = i + 1
226
		end
227
		file.close()
228
		return i
229
	end
230
	return 0
231
end
232
233
function getListFromFile(filePath)
234
	local list = {}
235
	if not fs.exists(filePath) then
236
		saveListToFile(filePath, list)
237
		return list
238
	end
239
	local file = fs.open(filePath,"r")
240
	local data = file.readAll()
241
	file.close()
242
	list = textutils.unserialize(data)
243
	if textutils.unserialize(data) == nil then
244
		list = {}
245
	end
246
	return list
247
end
248
249
function saveListToFile(filePath, list)
250
	file = fs.open(filePath,"w")
251
	file.write(textutils.serialize(list))
252
	file.close()
253
end
254
255
string.starts = function (self,Start)
256
   return string.sub(self,1,string.len(Start))==Start
257
end
258
259
function getCenter(f, varP)
260
	if not varP then
261
		varP = 0
262
	end
263
	
264
	local lengthOfVar = 0
265
	if type(varP) == "number" then
266
		lengthOfVar = varP
267
	elseif type(varP) == "string" then
268
		lengthOfVar = string.len(varP)
269
	else
270
		error("For function gcapi.getCenter expected number or string in argument #2")
271
	end
272
	if ((f - string.len(varP)) % 2) == 0 then
273
		return math.floor((f - lengthOfVar)/2)
274
	end
275
	
276
	return math.floor((f - lengthOfVar)/2)+1
277
	
278
end
279
280
function deepCopy(orig)
281
    local orig_type = type(orig)
282
    local copy
283
    if orig_type == 'table' then
284
        copy = {}
285
        for orig_key, orig_value in next, orig, nil do
286
            copy[deepCopy(orig_key)] = deepCopy(orig_value)
287
        end
288
        setmetatable(copy, deepCopy(getmetatable(orig)))
289
    else -- number, string, boolean, etc
290
        copy = orig
291
    end
292
    return copy
293
end
294
295
function numberBetween(v1, v2, v3)
296
	if v1 >= v2 and v1 <= v3 then
297
		return true
298
	end
299
	return false
300
end
301
302
--------------------------------------------
303
-->          Custom Http Request         <--
304
-->    http.get with timeout variable    <--
305
--------------------------------------------
306
307
function http.getStringWithTimeout(url, headers, timeout)
308
	if timeout == nil then
309
		local response = http.get(url, headers)
310
		local responseString = response.readAll()
311
		response.close()
312
		return responseString
313
	end
314
	
315
	--seconds to ticks
316
	timeout = timeout*20
317
	
318
	http.request(url, nil, headers)
319
	
320
	local requesting = true
321
	
322
	local localReloj = 0
323
	local nextTimeEventID = os.startTimer(0.1)
324
	while requesting do
325
		
326
		--Wait for event.
327
		tEvent = {os.pullEvent()}
328
		
329
		if "timer" == tEvent[1] then
330
			if tEvent[2] == nextTimeEventID then
331
				if timeout < localReloj then
332
					return nil
333
				end
334
				localReloj = localReloj + 2
335
				nextTimeEventID = os.startTimer(0.1)
336
			end
337
		else
338
			--Success.
339
			if tEvent[1] == "http_success" and url == tEvent[2] then
340
				local response = tEvent[3]
341
				local responseString = response.readAll()
342
				response.close()
343
				return responseString
344
			end
345
			--Failure
346
			if tEvent[1] == "http_failure" and url == tEvent[2] then
347
				return nil
348
			end
349
			
350
			nextTimeEventID = os.startTimer(0.1)
351
		end
352
		
353
	end
354
end
355
356
357
--------------------------------------------
358
-->             ImageDisplay             <--
359
-->                                      <--
360
-->              IMPORTANT:              <--
361
-->  The API server get bugged sometimes <--
362
-->  so I had to make a timeout http.get <--
363
--------------------------------------------
364
365
-- ** Display Image from URL **
366
367
-- Example:
368
-- url = http://www.image.com/image.jpg 
369
-- glassesPeripheral = peripheral.wrap(glassesName) [Optional] 
370
-- maxSize = 10 (10 max of height and weight) [Optional]
371
372
-- NOTE: If you want the image to be send to only 1 player use
373
-- peripheral.wrap(glassesName).getUserSurface(playerName) 
374
-- instead of peripheral.wrap(glassesName)
375
376
function displayImageFromURL(url, glassesPeripheral, maxSize, xo, yo)
377
	
378
	local filePath, ok, err = getImagePathFromURL(url, maxSize)
379
	if not ok then
380
		return false, err
381
	end	
382
	
383
	displayImageFromFile(filePath, glassesPeripheral, xo, yo)
384
	fs.delete(filePath)
385
	
386
	return true
387
end
388
389
-- ** Display Image from Rule34 **
390
391
-- Example:
392
-- tag = random (just 1)
393
-- glassesPeripheral = peripheral.wrap(glassesName) [Optional] 
394
-- maxSize = 10 (10 max of height and weight) [Optional]
395
396
-- NOTE: If you want the image to be send to only 1 player use
397
-- peripheral.wrap(glassesName).getUserSurface(playerName) 
398
-- instead of peripheral.wrap(glassesName)
399
400
function displayImageFromRule34(tag, glassesPeripheral, maxSize, xo, yo)
401
	url, err = getURLfromRule34(tag)
402
	if url == nil then
403
		return false, err
404
	end
405
	return displayImageFromURL(url, glassesPeripheral, maxSize, xo, yo)
406
end
407
408
function getGlasses(glassesPeripheral)
409
	if glassesPeripheral == nil then
410
		return peripheral.find("openperipheral_glassesbridge")
411
	end
412
	return glassesPeripheral
413
end
414
415
-- file = fs.open("imagen","r") 
416
-- glassesPeripheral = peripheral.wrap(glassesName) [Optional]
417
function displayImageFromFile(filePath, glassesPeripheral, xo, yo)
418
	
419
	if xo == nil then
420
		xo = 1
421
	end
422
	if yo == nil then
423
		yo = 1
424
	end
425
	
426
	numberLines = getNumberOfLinesFile(filePath)
427
	file = fs.open(filePath, "r")
428
	
429
	gb = getGlasses(glassesPeripheral)	
430
	if gb == nil then
431
		error("[GCAPI] Glasses peripheral not found")
432
	end
433
	
434
	for i=1,numberLines,1 do
435
		linea = file.readLine(i)
436
		lineaQ = {}
437
		lineaQ = split(linea,",")
438
		for x,color in pairs(lineaQ) do
439
			hcolor = assert(loadstring("return "..color))()
440
			gb.addBox(x+xo,i+yo,1,1,hcolor,1)
441
		end
442
	end
443
	file.close()
444
end
445
446
function getImagePathFromURL(url, maxSize, max_x, max_y, forMonitor, filePath)
447
	
448
	if filePath == nil then
449
		filePath = 'gcAPIImage'
450
	end
451
452
	if url == nil then
453
		err = '[GCAPI] No URL for image'
454
		print(err)
455
		return nil, false, err
456
	end
457
	
458
	--DELETE SAVED IMAGE
459
	if url == "none" then
460
		fs.delete(filePath)
461
	end
462
	
463
	--URL ALIAS
464
	if urlAlias[url] then
465
		url = urlAlias[url]
466
	end
467
	
468
	extraParameters = ""
469
	if maxSize ~= nil and tonumber(maxSize) then
470
		extraParameters = extraParameters .. '&max_size=' .. maxSize
471
	end
472
	
473
	if max_x ~= nil and tonumber(max_x) then
474
		extraParameters = extraParameters .. '&max_x=' .. max_x
475
	end
476
	
477
	if max_y ~= nil and tonumber(max_y) then
478
		extraParameters = extraParameters .. '&max_y=' .. max_y
479
	end
480
	
481
	script = "imageCC"
482
	
483
	if forMonitor then
484
		script = "monitorImageCC"
485
	end
486
	
487
	local dataWeb = http.getStringWithTimeout("http://jake.emx.cl/cc/" .. script .. ".php?url=" .. url .. extraParameters, nil, 3)
488
	if not dataWeb then
489
		err = "[GCAPI] Server error or timeout"
490
		print(err)
491
		return nil, false, err
492
	end
493
	
494
	if #dataWeb < 30 then
495
		err = "[GCAPI] " .. dataWeb
496
		print(err)
497
		return nil, false, err
498
	end
499
	
500
	fs.delete(filePath)
501
	
502
	f = fs.open(filePath, "w")
503
	f.write(dataWeb)
504
    f.close()
505
	
506
	return filePath, true, nil
507
	
508
end
509
510
--------------------------------------------
511
-->             ImageDisplay for         <--
512
-->                 monitors             <--
513
--------------------------------------------
514
function getMonitor(monSelected)
515
	if monSelected == nil then
516
		return peripheral.find("monitor")
517
	end
518
	return monSelected
519
end
520
function printImageFromURL(url, monSelected, centered)
521
	
522
	mon = getMonitor(monSelected)
523
	
524
	if mon == nil then
525
		error("[GCAPI] Monitor not found")
526
	end
527
	
528
	mon.setTextScale(0.5)
529
	mon.clear()
530
	local max_x, max_y = mon.getSize()
531
532
	if url == nil then
533
		err = '[GCAPI] No URL for image'
534
		print(err)
535
		return nil, false, err
536
	end
537
	
538
	--URL ALIAS
539
	if urlAlias[url] then
540
		url = urlAlias[url]
541
	end
542
	
543
	extraParameters = ""
544
	if maxSize ~= nil and tonumber(maxSize) then
545
		extraParameters = extraParameters .. '&max_size=' .. maxSize
546
	end
547
	
548
	if max_x ~= nil and tonumber(max_x) then
549
		extraParameters = extraParameters .. '&max_x=' .. max_x
550
	end
551
	
552
	if max_y ~= nil and tonumber(max_y) then
553
		extraParameters = extraParameters .. '&max_y=' .. max_y
554
	end
555
	
556
	local dataWeb = http.getStringWithTimeout("http://jake.emx.cl/cc/monitorImageCC.php?url=" .. url .. extraParameters, nil, 3)
557
	if not dataWeb then
558
		err = "[GCAPI] Server error or timeout"
559
		print(err)
560-
	local dataWeb = http.getStringWithTimeout("https://cc.emx.cl/scripts/monitorImageCC.php?url=" .. url .. extraParameters, nil, 3)
560+
561
	end
562
	
563
	if #dataWeb < 30 then
564
		err = "[GCAPI] " .. dataWeb
565
		print(err)
566
		return nil, false, err
567
	end
568
	
569
	local image_lines = gcapi.split(dataWeb, '\n')
570
	
571
	mon.setTextScale(0.5)
572
	mon.clear()
573
	local max_x, max_y = mon.getSize()
574
575
	numberLines = #image_lines
576
	
577
	xo = 0
578
	yo = 0
579
	
580
	if centered and numberLines > 0 then
581
		local line = image_lines[1]
582
		local real_x = #(split(line, ","))
583
		xo = getCenter(max_x, real_x)
584
		yo = getCenter(max_y, numberLines)
585
	end
586
	
587
	
588
	for i=1,numberLines,1 do
589
		linea = image_lines[i]
590
		lineaQ = {}
591
		lineaQ = split(linea,",")
592
		for x,colorSet in pairs(lineaQ) do
593
			colors0 = split(colorSet,"-")
594
			r = tonumber(colors0[1])
595
			g = tonumber(colors0[2])
596
			b = tonumber(colors0[3])
597
			
598
			if r and g and b then
599
				hcolor = colors.fromRGB(r, g, b)
600
				mon.setBackgroundColour(hcolor)
601
				mon.setCursorPos(x+xo,i+yo)
602
				mon.write(" ")
603
			end
604
		end
605
	end
606
	
607
	return true
608
end
609
610
function printAvatar(mon, player_name, x, y, max_side)
611
	local xo = x
612
	local yo = y
613
	
614
	local filePath, ok, err = getImagePathFromURL("https://minotar.net/avatar/" .. player_name .. "/"..max_side, nil, max_side, max_side, true)
615
	if not ok then
616
		return false, err
617
	end	
618
	
619
	numberLines = getNumberOfLinesFile(filePath)
620
	local file = fs.open(filePath, "r")
621
	for i=1,numberLines,1 do
622
		linea = file.readLine(i)
623
		lineaQ = {}
624
		lineaQ = split(linea,",")
625
		for x,colorSet in pairs(lineaQ) do
626
			colors0 = split(colorSet,"-")
627
			r = tonumber(colors0[1])
628
			g = tonumber(colors0[2])
629
			b = tonumber(colors0[3])
630
			
631
			if r and g and b then
632
				hcolor = colors.fromRGB(r, g, b)
633
				mon.setBackgroundColour(hcolor)
634
				mon.setCursorPos(x+xo,i+yo)
635
				mon.write(" ")
636
			end
637
		end
638
	end
639
	file.close()
640
	
641
	return true
642
end
643
644
function printImageFromFile(filePath, monSelected, centered, monSetup)
645
	
646
	mon = monSelected
647
	
648
	if monSetup == nil or monSetup == false then
649
		mon = getMonitor(monSelected)
650
		if mon == nil then
651
			error("[GCAPI] Monitor not found")
652
		end
653
	end	
654
	
655
	mon.setTextScale(0.5)
656
	mon.clear()
657
	local max_x, max_y = mon.getSize()
658
659
	numberLines = getNumberOfLinesFile(filePath)
660
	
661
	xo = 0
662
	yo = 0
663
	
664
	if centered and numberLines > 0 then
665
		local file = fs.open(filePath, "r")
666
		local line = file.readLine()
667
		local real_x = #(split(line, ","))
668
		file.close()
669
		xo = getCenter(max_x, real_x)
670
		yo = getCenter(max_y, numberLines)
671
	end
672
	
673
	
674
	file = fs.open(filePath, "r")
675
	for i=1,numberLines,1 do
676
		linea = file.readLine()
677
		lineaQ = {}
678
		lineaQ = split(linea,",")
679
		for x,colorSet in pairs(lineaQ) do
680
			colors0 = split(colorSet,"-")
681
			r = tonumber(colors0[1])
682
			g = tonumber(colors0[2])
683
			b = tonumber(colors0[3])
684
			
685
			if r and g and b then
686
				hcolor = colors.fromRGB(r, g, b)
687
				mon.setBackgroundColour(hcolor)
688
				mon.setCursorPos(x+xo,i+yo)
689
				mon.write(" ")
690
			end
691
		end
692
	end
693
	file.close()
694
	
695
	return true
696
end
697
698
--------------------------------------------
699
-->             ImageDisplay for         <--
700
-->            chunks of monitors        <--
701
--------------------------------------------
702
function printPixel(x,y,color)
703
	
704
end
705
706
707
--------------------------------------------
708
-->            Tracker of players        <--
709
-->          Just for craftersland       <--
710
-->                  DYNMAP              <--
711
--------------------------------------------
712
function getPosPlayer(player, dataPlayers)
713
	if player == nil or player == "" then
714
		err = "User not found"
715
		print("[GCAPI] " .. err)
716
		return nil, false, err
717
	end
718
	
719
	player = string.lower(player)
720
	
721
	if not dataPlayers then
722
		dataPlayers, ok, err = getPosPlayers()
723
	end
724
	
725
	for i,dataPlayer in pairs(dataPlayers) do
726
		user = string.lower(dataPlayer["name"])
727
		if string.match(user, player) then
728
			return dataPlayer, true, nil
729
		end
730
	end
731
	
732
	err = "User not found"
733
	return nil, false, err
734
end
735
736
function getPosPlayers(password)
737
	local url = "http://jake.emx.cl/cc/dynmap.php"
738
	if password then
739-
function getForumData()
739+
		url = url .. "?password=" .. password
740-
	local dataWeb = http.get("https://forum.craftersland.net/staff/")
740+
741-
	if not dataWeb then return nil, false, "[GCAPI] Forum Error" end
741+
742-
	return dataWeb.readAll()
742+
	local dataPlayers = textutils.unserialize(dataWeb.readAll())
743
	dataWeb.close()
744
	
745-
function getStaffList() -- lower case
745+
746-
	local result = {}
746+
747
	end
748-
	local forum_data, ok, err = getForumData()
748+
749-
	if not ok then return nil, false, err end
749+
	if dataPlayers["error"] ~= nil then
750
		return nil, false, dataPlayers["error"]
751-
	for staff_player in string.gmatch(forum_data, "title=\"Go to (.-)'s profile") do
751+
752-
		if not table.contains(result, staff_player) then
752+
753-
			table.insert(result, string.lower(staff_player)) 
753+
754
end
755
756-
	return result, true, nil
756+
757
	local url = "http://jake.emx.cl/cc/closePlayers.php?user=" .. user .. "&range=" .. range
758
	
759-
function getDynmapData()
759+
760-
	local dataWeb = http.get("http://tekkit.craftersland.net:25800/up/world/world/")
760+
761-
	if not dataWeb then return nil, false, "[GCAPI] Dynmap Error" end
761+
762-
	return dataWeb.readAll(), true, nil
762+
763
	if not dataWeb then
764
		return nil, false, "[GCAPI] Server Error"
765-
function getOnlinePlayers()
765+
766-
	local result = {}
766+
767
	if closePlayers["error"] ~= nil then
768-
	local dm_data, ok, err = getDynmapData()
768+
769-
	if not ok then 
769+
770
	
771
	return closePlayers, true, nil
772
end
773-
	local list = string.split(dm_data,"\"name\":\"")
773+
774-
	for i=2, #list do
774+
775-
		local player_name = string.split(list[i],"\"")[1]
775+
776-
    	table.insert(result, player_name)
776+
777
778-
	return result, true, nil
778+
779
	dataWeb = http.get("http://jake.emx.cl/cc/chatSpy.php")
780
	dataChat = textutils.unserialize(dataWeb.readAll())
781-
-- @Deprecated - It will return fake data - "name","x","y","z","world"
781+
782-
function getPosPlayers(filter_list)
782+
783-
	local dataPlayers = {}
783+
784
		return nil, false, "[GCAPI] Server Error"
785-
	local online_players, ok, err = getOnlinePlayers()
785+
786-
	if not ok then 
786+
787-
		return nil, false, err 
787+
788
end
789
790-
	for _,player_name in pairs(online_players) do
790+
791-
		if not (filter_list and table.contains(filter_list, string.lower(player_name))) then
791+
792-
			table.insert(dataPlayers, {["name"] = player_name, ["x"] = 0, ["y"] = 0, ["z"] = 0, ["world"] = "Overworld"})	
792+
793
-->                                      <--
794
-->         This is saved every use      <--
795
-->           for safety purposes.       <--
796
--------------------------------------------
797
798
function getMoney(player)
799
	list = getListFromFile("/disk/economy")
800
	
801
	player = string.lower(player)
802
	
803
	for name,amount in pairs(list) do
804
		if name == player then
805
			return amount 
806
		end
807
	end
808
	setMoney(player, 0)
809
	return 0
810
end
811
812
function setMoney(player, amount)
813
	
814
	player = string.lower(player)
815
	
816
	list = getListFromFile("/disk/economy")
817
	
818
	fs.delete("/disk/economy")
819
	
820
	list[player]=amount
821
	
822
	saveListToFile("/disk/economy", list)
823
end
824
825
function withdraw(player, amount)	
826
	player = string.lower(player)
827
	
828
	if getMoney(player) < amount then
829
		return false
830
	end
831
	
832
	setMoney(player, (getMoney(player)-amount))
833
	return true
834
end
835
836
function addMoney(player, money)
837
	
838
	player = string.lower(player)
839
	
840
	setMoney(player,getMoney(player)+money)
841
end
842
--------------------------------------------
843
-->          Admins for selling          <--
844
--------------------------------------------
845
admins = {"GravityCube", "Archmaestro", "Lancellot", "Freecss"}
846
function hasPermissions(player, globalAdmins)
847
	if globalAdmins == nil then
848
		globalAdmins = true
849
	end
850
	for _,user in pairs(getAdmins(globalAdmins)) do
851
		if user == player then
852
			return true
853
		end
854
	end
855
	return false
856
end
857
858
function getAdmins(globalAdmins)
859
	localAdmins = {}
860
	if fs.exists("admins") then
861
		localAdmins = getListFromFile("admins")
862
	end
863
	
864
	if globalAdmins then
865
		for _,admin in pairs(admins) do
866
			table.insert(localAdmins, admin)
867
		end
868
	end
869
	
870
	return localAdmins
871
end
872
--------------------------------------------
873
-->              EventHanlder            <--
874
--------------------------------------------
875
if not lastID then
876
	lastID = 0
877
end
878
function startChatEventQueue()
879
	while true do
880
		chatData, ok, err = getChat()
881
		if ok then
882
			lastIDTemp = lastID
883
			for i=1, 10, 1 do
884
				data = chatData[i]
885
				if data ~= nil then
886
					id = data["id"]
887
					if id > lastID then
888
						if id > lastIDTemp then
889
							lastIDTemp = id
890
						end
891
						
892
						player = data["name"]
893
						command = data["message"]
894
						
895
						if command ~= nil and string.starts(command, "!") then
896
							command = string.sub(command, 2)
897
							lastID = lastIDTemp
898
							os.queueEvent("chatEvent", player, command)
899
						end
900
					end		
901
				end
902
			end
903
			lastID = lastIDTemp
904
		end
905
		sleep(1)
906
	end
907
end
908
909
910
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
911
--*             RBG TO COLOUR			 *--
912
--*          by CrazedProgrammer         *--
913
--*    (Used in the printImageFromURL)   *--
914
--*   https://pastebin.com/BCSWghjR/rgb  *--
915
--*--*--*--*--*--*--*--*--*--*--*--*--*--*--
916
local hex = {"F0F0F0", "F2B233", "E57FD8", "99B2F2", "DEDE6C", "7FCC19", "F2B2CC", "4C4C4C", "999999", "4C99B2", "B266E5", "3366CC", "7F664C", "57A64E", "CC4C4C", "191919"}
917
local rgb = {}
918
for i=1,16,1 do
919
  rgb[i] = {tonumber(string.sub(hex[i],1, 2), 16), tonumber(string.sub(hex[i],3, 4), 16), tonumber(string.sub(hex[i], 5, 6), 16)}
920
end
921
 
922
colors.fromRGB = function (r, g, b)
923
  local dist = 1e100
924
  local d = 1e100
925
  local color = -1
926
  for i=1,16,1 do
927
    d = math.sqrt((math.max(rgb[i][1], r) - math.min(rgb[i][1], r)) ^ 2 + (math.max(rgb[i][2], g) - math.min(rgb[i][2], g)) ^ 2 + (math.max(rgb[i][3], b) - math.min(rgb[i][3], b)) ^ 2)
928
    if d < dist then
929
      dist = d
930
      color = i - 1
931
    end
932
  end
933
  return 2 ^ color
934
end
935
936
colours.fromRGB = colors.fromRGB