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