· 7 years ago · Jan 13, 2019, 02:50 AM
1false
2{
3 [ "/pain.lua" ] = {
4 "--[[",
5 " PAIN image editor for ComputerCraft",
6 " Get it with",
7 " wget https://raw.githubusercontent.com/LDDestroier/CC/master/pain.lua pain",
8 " pastebin get wJQ7jav0 pain",
9 " std ld pain pain",
10 "--]]",
11 "local askToSerialize = false",
12 "local defaultSaveFormat = 4 -- will change if importing image, or making new file with extension in name",
13 "--[[",
14 " defaultSaveFormat possible parameters:",
15 " 1. NFP (paint)",
16 " 2. NFT (npaintpro)",
17 " 3. BLT (blittle)",
18 " 4. Native PAIN",
19 " 5. GIF",
20 " 6. UCG",
21 "--]]",
22 "",
23 "local progname = fs.getName(shell.getRunningProgram())",
24 "local apipath = \".painapi\"",
25 "",
26 "local painconfig = {",
27 " undoBufferSize = 8, -- amount of times undo will save your neck",
28 " readNonImageAsNFP = true, -- reads non-image files as NFP images",
29 " useFlattenGIF = true, -- will flatten compressed GIFs",
30 " gridBleedThrough = false, -- will draw grid instead of character value of dots",
31 " doFillDiagonal = false, -- checks for diagonal dots when using fill tool",
32 " doFillAnimation = false, -- whether or not to animate the fill tool",
33 "}",
34 "",
35 "local saveConfig = function()",
36 " local file = fs.open(fs.combine(apipath,\"painconfig\"), \"w\")",
37 " file.write(textutils.serialize(painconfig))",
38 " file.close()",
39 "end",
40 "",
41 "local loadConfig = function()",
42 " if fs.exists(fs.combine(apipath,\"painconfig\")) then",
43 " local file = fs.open(fs.combine(apipath,\"painconfig\"), \"r\")",
44 " painconfig = textutils.unserialize(file.readAll())",
45 " file.close()",
46 " end",
47 "end",
48 "",
49 "loadConfig()",
50 "saveConfig()",
51 "",
52 "local displayHelp = function()",
53 " print(progname)",
54 " print(progname..\" <filename>\")",
55 " print(progname..\" [-h/--help]\")",
56 " print(\"Press F1 in program for more.\")",
57 "end",
58 "",
59 "local tsv = term.current().setVisible",
60 "local undoBuffer",
61 "local undoPos = 1",
62 "local pMode = 0",
63 "local scr_x, scr_y = term.getSize()",
64 "screenEdges = {",
65 " scr_x,",
66 " scr_y,",
67 "}",
68 "",
69 "local tArg = {...}",
70 "if (tArg[1] == \"--help\" or tArg[1] == \"-h\") and shell then",
71 " return displayHelp()",
72 "end",
73 "",
74 "if tArg[2] == \"view\" then",
75 " pMode = 1",
76 "elseif (tArg[2] == \"moo\") and (not fs.exists(\"moo\")) then",
77 " return print(\"This PAIN does not have Super Cow Powers.\")",
78 "end",
79 "",
80 "local fileName",
81 "if (not term.isColor()) and (pMode ~= 1) then",
82 " error(\"PAIN only works with Advanced Computers at the moment.\")",
83 "end",
84 "local barmsg = \"Press F1 for help.\"",
85 "local tse = textutils.serialise",
86 "local tun = textutils.unserialise",
87 "local paintEncoded",
88 "local lastPaintEncoded",
89 "local frame = 1",
90 "local doRender = false",
91 "local metaHistory = {}",
92 "local bepimode = false -- this is a family-friendly program! now stand still while I murder you",
93 "local evenDrawGrid = true -- will you evenDraw(the)Grid ?",
94 "local renderBlittle = false -- whether or not to render all in blittle",
95 "local firstTerm, blittleTerm = term.current()",
96 "local firstBG = term.getBackgroundColor()",
97 "local firstTX = term.getTextColor()",
98 "local changedImage = false",
99 "local isCurrentlyFilling = false",
100 "local theClipboard = {}",
101 "",
102 "local _",
103 "local tableconcat = table.concat",
104 "",
105 "local rendback = {",
106 " b = colors.black,",
107 " t = colors.gray,",
108 "}",
109 "",
110 "local grid",
111 "",
112 "local yield = function()",
113 " os.queueEvent(\"yield\")",
114 " os.pullEvent(\"yield\")",
115 "end",
116 "",
117 "local paint = {",
118 " scrollX = 0,",
119 " scrollY = 0,",
120 " t = colors.gray,",
121 " b = colors.white,",
122 " m = 1, -- in case you want to use PAIN as a level editor or something",
123 " c = \" \",",
124 " doGray = false,",
125 "}",
126 "local boxchar = {topLeft = true, topRight = true, left = true, right = true, bottomLeft = true, bottomRight = true}",
127 "local swapColors = false -- swaps background and text colors, for use with those tricky box characters",
128 "local scrollX, scrollY = 0, 0",
129 "",
130 "local keysDown = {}",
131 "local miceDown = {}",
132 "",
133 "local doRenderBar = 1 -- Not true or false",
134 "",
135 "local fixstr = function(str)",
136 " return str:gsub(\"\\\\(%d%d%d)\",string.char)",
137 "end",
138 "",
139 "local choice = function(input,breakkeys,returnNumber)",
140 " local fpos = 0",
141 " repeat",
142 " event, key = os.pullEvent(\"key\")",
143 " if type(key) == \"number\" then key = keys.getName(key) end",
144 " if key == nil then key = \" \" end",
145 " if type(breakkeys) == \"table\" then",
146 " for a = 1, #breakkeys do",
147 " if key == breakkeys[a] then",
148 " return \"\"",
149 " end",
150 " end",
151 " end",
152 " fpos = string.find(input, key)",
153 " until fpos",
154 " return returnNumber and fpos or key",
155 "end",
156 "local explode = function(div,str)",
157 " if (div=='') then return false end",
158 " local pos,arr = 0,{}",
159 " for st,sp in function() return string.find(str,div,pos,true) end do",
160 " arr[#arr+1] = str:sub(pos,st-1)",
161 " pos = sp + 1",
162 " end",
163 " arr[#arr+1] = str:sub(pos)",
164 " return arr",
165 "end",
166 "",
167 "local cutString = function(max_line_length, str) -- from stack overflow",
168 " local lines = {}",
169 " local line",
170 " str:gsub('(%s*)(%S+)',",
171 " function(spc, word)",
172 " if not line or #line + #spc + #word > max_line_length then",
173 " lines[#lines+1] = line",
174 " line = word",
175 " else",
176 " line = line..spc..word",
177 " end",
178 " end",
179 " )",
180 " lines[#lines+1] = line",
181 " return lines",
182 "end",
183 "",
184 "local getDrawingCharacter = function(topLeft, topRight, left, right, bottomLeft, bottomRight) -- thank you oli414",
185 " local data = 128",
186 " if not bottomRight then",
187 " data = data + (topLeft and 1 or 0)",
188 " data = data + (topRight and 2 or 0)",
189 " data = data + (left and 4 or 0)",
190 " data = data + (right and 8 or 0)",
191 " data = data + (bottomLeft and 16 or 0)",
192 " else",
193 " data = data + (topLeft and 0 or 1)",
194 " data = data + (topRight and 0 or 2)",
195 " data = data + (left and 0 or 4)",
196 " data = data + (right and 0 or 8)",
197 " data = data + (bottomLeft and 0 or 16)",
198 " end",
199 " return {char = string.char(data), inverted = bottomRight}",
200 "end",
201 "",
202 "local cutUp = function(len,tbl)",
203 " local output = {}",
204 " local e = 0",
205 " local s",
206 " for a = 1, #tbl do",
207 " if #(tbl[a]:gsub(\" \",\"\")) == 0 then",
208 " s = {\"\"}",
209 " else",
210 " s = cutString(len,tbl[a])",
211 " end",
212 " for b = 1, #s do",
213 " output[#output+1] = s[b]",
214 " end",
215 " end",
216 " return output",
217 "end",
218 "",
219 "local getEvents = function(...)",
220 " local arg, output = table.pack(...)",
221 " while true do",
222 " output = {os.pullEvent()}",
223 " for a = 1, #arg do",
224 " if type(arg[a]) == \"boolean\" then",
225 " if doRender == arg[a] then",
226 " return {}",
227 " end",
228 " elseif output[1] == arg[a] then",
229 " return unpack(output)",
230 " end",
231 " end",
232 " end",
233 "end",
234 "",
235 "",
236 "",
237 "local sanitize = function(sani,tize)",
238 " local _,x = string.find(sani,tize)",
239 " if x then",
240 " return sani:sub(x+1)",
241 " else",
242 " return sani",
243 " end",
244 "end",
245 "local ro = function(input, max)",
246 " return math.floor(input % max)",
247 "end",
248 "",
249 "local guiHelp = function(inputText)",
250 " term.redirect(firstTerm)",
251 " scr_x, scr_y = term.current().getSize()",
252 " local _helpText = inputText or [[",
253 "",
254 "'PAIN' super-verbose help page",
255 " Programmed by LDDestroier",
256 "",
257 "(use UP/DOWN or scrollwheel, exit with Q)",
258 "If you wish to use PAIN to its fullest, read everything here.",
259 "You'll be image-editing like a pro in no time flat.",
260 "",
261 "Syntax:",
262 ">pain <filename> [view] [x] [y]",
263 ">pain [-n]",
264 ">pain [-h/--help]",
265 "",
266 "[view]: renders the image once (optionally scrolling with [x] and [y])",
267 "\"-n\" or no arguments: Create new document, declare name upon saving",
268 "\"-h\" or \"--help\": Display short syntax help",
269 "",
270 "You can see what colors are selected based on the word \"PAIN\" on the hotbar.",
271 "",
272 "Hotkeys:",
273 " left/right ctrl: Toggle the menu",
274 "",
275 " left click:",
276 " +left shift = Drag and let go to draw a line",
277 " -alone = Place a dot",
278 "",
279 " Right Click: delete pixel",
280 "",
281 " Middle Click, or \"T\": Place text down with current colors; cancel with X",
282 "",
283 " \"Z\":",
284 " +LeftAlt = Redo",
285 " -alone = Undo",
286 "",
287 " \"P\": Pick colors from position onscreen; cancel with X",
288 "",
289 " \"N\":",
290 " +LeftShift = Change character to that of a special character",
291 " -alone = Change box character for drawing",
292 " (cancel with CTRL, N, or by clicking outside)",
293 "",
294 " \"[\" or mouse scroll down:",
295 " +LeftShift = Change to previous text color",
296 " -alone = Change to previous background color",
297 "",
298 " \"]\" or mouse scroll up:",
299 " +LeftShift = Change to next text color",
300 " -alone = Change to next background color",
301 "",
302 " \"F1\":",
303 " -alone = Access help screen",
304 "",
305 " \"F3:\"",
306 " -alone = View all connected monitors",
307 "",
308 " Spacebar:",
309 " +LeftShift = Toggle background grid",
310 " -alone = Toggle bar visibility",
311 "",
312 " Arrow keys:",
313 " +LeftShift = Displaces the entire frame",
314 " +Tab = Moves canvas one pixel at a time",
315 " -alone = Looks around the canvas smoothly",
316 "",
317 " \"+\" (or equals):",
318 " +LeftAlt = Swap the current frame with the next frame",
319 " +LeftShift = Merge the current frame atop the next frame",
320 " +RightShift = If you are making a new frame, duplicates the last frame",
321 " -alone = Change to next frame",
322 "",
323 " \"-\":",
324 " +LeftAlt = Swap the current frame with the previous frame",
325 " +LeftShift = Merge the current frame atop the previous frame",
326 " -alone = Change to previous frame",
327 "",
328 " (oh good, you're actually reading this stuff)",
329 "",
330 " \"A\": Set the coordinates to 0,0",
331 "",
332 " \"N\": Open block character selection",
333 "",
334 " \"B\": Toggle redirect to blittle, to preview in teletext characters",
335 "",
336 " \"c\":",
337 " +LeftAlt = Select region to copy to specified clipboard",
338 " -alone = Input coordinates to scroll over to",
339 "",
340 " \"LeftAlt + X\": Select region to cut to specified clipboard",
341 "",
342 " \"LeftAlt + X\": Pastes from specified clipboard",
343 "",
344 " \"G\": toggle grayscale mode.",
345 " Everything is in shades of gray.",
346 " If you Save, it saves in grayscale.",
347 "",
348 " \"F\":",
349 " +LeftShift = fill all empty pixels with background color and selected box character",
350 " -alone = activate fill tool - click anywhere to fill with color",
351 "",
352 " \"M\": set metadata for pixels (for game makers, otherwise please ignore)",
353 "",
354 "==================================",
355 " Thy Menu (accessible with CTRL):",
356 "==================================",
357 "",
358 " Left click on a menu item to select it.",
359 " If you click on the menubar, release on an option to select it.",
360 "",
361 " \"File > Save\"",
362 " Saves all frames to a specially formatted PAIN paint file. The format PAIN uses is very inefficient despite my best efforts, so Export if you don't use text or multiple frame.",
363 "",
364 " \"File > Save As\"",
365 " Same as \"File > Save\", but you change the filename.",
366 "",
367 " \"File > Export\"",
368 " Exports current frame to NFP, NFT, BLT, or the horribly inefficient PAIN format.",
369 "",
370 " \"File > Open\"",
371 " Opens up a file picker for you to change the image currently being edited.",
372 "",
373 " \"Edit > Delete Frame\"",
374 " Deletes the current frame. Tells you off if you try to delete the only frame.",
375 "",
376 " \"Edit > Clear\"",
377 " Deletes all pixels on the current frame.",
378 "",
379 " \"Edit > Crop Frame\"",
380 " Deletes all pixels that are outside of the screen.",
381 "",
382 " \"Edit > Change Box Character\"",
383 " Opens the block character selection. Used for making those delicious subpixel pictures.",
384 "",
385 " \"Edit > Change Special Character\"",
386 " Opens the special character selector, which lets you change the paint character to that of byte 0 to 255.",
387 "",
388 " \"Edit > BLittle Shrink\"",
389 " Shrinks the current frame using the BLittle API. Very lossy, and unreversable without Undo.",
390 "",
391 " \"Edit > Copy\"",
392 " Drag to select a region of the screen, and save it in a clipboard of a specified name.",
393 "",
394 " \"Edit > Cut\"",
395 " Same as Copy, but deletes the selected region on the screen.",
396 "",
397 " \"Edit > Paste\"",
398 " Takes the contents of the specified clipboard, and plops it on the canvas where the mouse is.",
399 "(The mouse will indicate the top-left corner of the pasted selection)",
400 "",
401 " \"Set > ...\"",
402 " Each option will toggle a config option (or set it's value to something else).",
403 " Changing a value is saved automatically, and effective immediately.",
404 "",
405 " \"Window > Set Screen Size\"",
406 " Sets the sizes of the screen border references displayed on the canvas.",
407 "",
408 " \"Window > Set Grid Colors\"",
409 " Sets the backdrop colors to your currently selected color configuration.",
410 "",
411 " \"About > PAIN\"",
412 " Tells you about PAIN and its developer.",
413 "",
414 " \"About > File Formats\"",
415 " Tells you the ins and outs of the file formats, and a brief description of their creators.",
416 "",
417 " \"About > Help\"",
418 " Opens up this help page.",
419 "",
420 " \"Exit\"",
421 " Durr I dunno, I think it exits.",
422 "",
423 "",
424 "I hope my PAIN causes you joy.",
425 "]]",
426 " _helpText = explode(\"\\n\",_helpText)",
427 " helpText = cutUp(scr_x,_helpText)",
428 " local helpscroll = 0",
429 " term.setBackgroundColor(colors.gray)",
430 " term.setTextColor(colors.white)",
431 " term.clear()",
432 " local evt, key",
433 " while true do",
434 " term.clear()",
435 " for a = 1, scr_y do",
436 " term.setCursorPos(1,a)",
437 " term.clearLine()",
438 " write(helpText[a-helpscroll] or \"\")",
439 " end",
440 " repeat",
441 " evt,key = os.pullEvent()",
442 " until evt == \"key\" or evt == \"mouse_scroll\"",
443 " if evt == \"key\" then",
444 " if key == keys.up then",
445 " helpscroll = helpscroll + 1",
446 " elseif key == keys.down then",
447 " helpscroll = helpscroll - 1",
448 " elseif key == keys.pageUp then",
449 " helpscroll = helpscroll + scr_y",
450 " elseif key == keys.pageDown then",
451 " helpscroll = helpscroll - scr_y",
452 " elseif (key == keys.q) or (key == keys.space) then",
453 " doRender = true",
454 " if renderBlittle then term.redirect(blittleTerm) end",
455 " scr_x, scr_y = term.current().getSize()",
456 " return",
457 " end",
458 " elseif evt == \"mouse_scroll\" then",
459 " helpscroll = helpscroll - key",
460 " end",
461 " if helpscroll > 0 then",
462 " helpscroll = 0",
463 " elseif helpscroll < -(#helpText-(scr_y-3)) then",
464 " helpscroll = -(#helpText-(scr_y-3))",
465 " end",
466 " end",
467 "end",
468 "",
469 "local tableRemfind = function(tbl, str)",
470 " local out = tbl",
471 " for a = 1, #tbl do",
472 " if tbl[a] == str then",
473 " table.remove(out,a)",
474 " return out,a",
475 " end",
476 " end",
477 " return {}",
478 "end",
479 "",
480 "local stringShift = function(str,amt)",
481 " return str:sub(ro(amt-1,#str)+1)..str:sub(1,ro(amt-1,#str))",
482 "end",
483 "",
484 "local deepCopy",
485 "deepCopy = function(obj)",
486 " if type(obj) ~= 'table' then return obj end",
487 " local res = {}",
488 " for k, v in pairs(obj) do res[deepCopy(k)] = deepCopy(v) end",
489 " return res",
490 "end",
491 "",
492 "local clearLines = function(y1, y2)",
493 " local cx,cy = term.getCursorPos()",
494 " for y = y1, y2 do",
495 " term.setCursorPos(1,y)",
496 " term.clearLine()",
497 " end",
498 " term.setCursorPos(cx,cy)",
499 "end",
500 "",
501 "local renderBottomBar = function(txt,extraClearY)",
502 " term.setCursorPos(1,scr_y - math.floor(#txt/scr_x))",
503 " term.setBackgroundColor(colors.lightGray)",
504 " term.setTextColor(colors.black)",
505 " clearLines(scr_y - (math.floor(#txt/scr_x) - (extraClearY or 0)), scr_y)",
506 " return write(txt)",
507 "end",
508 "",
509 "local bottomPrompt = function(txt,history,cho,breakkeys,returnNumber,writeIndent)",
510 " local writeIndent = renderBottomBar(txt,writeIndent)",
511 " local out",
512 " sleep(0)",
513 " if cho then",
514 " out = choice(cho,breakkeys,returnNumber)",
515 " else",
516 " out = read(_,history)",
517 " end",
518 " return out, writeIndent",
519 "end",
520 "",
521 "local makeSubMenu = function(x,y,options)",
522 " local longestLen = 0",
523 " for a = 1, #options do",
524 " if #options[a] > longestLen then",
525 " longestLen = #options[a]",
526 " end",
527 " end",
528 " longestLen = longestLen + 1",
529 " term.setTextColor(colors.black)",
530 " local sel = 1",
531 " local rend = function()",
532 " for a = #options, 1, -1 do",
533 " term.setCursorPos(x or 1, ((y or (scr_y-1)) - (#options-1)) + (a - 1))",
534 " term.setBackgroundColor(a == sel and colors.white or colors.lightGray)",
535 " term.write(options[a])",
536 " term.setBackgroundColor(colors.lightGray)",
537 " term.write((\" \"):rep(longestLen-#options[a]))",
538 " end",
539 " end",
540 " local usingMouse = false",
541 " while true do",
542 " rend()",
543 " local evt, key, mx, my = os.pullEvent()",
544 " if evt == \"key\" then",
545 " if key == keys.up then",
546 " sel = sel - 1",
547 " elseif key == keys.down then",
548 " sel = sel + 1",
549 " elseif (key == keys.enter) or (key == keys.right) then",
550 " return sel, longestLen",
551 " elseif (key == keys.leftCtrl) or (key == keys.rightCtrl) or (key == keys.backspace) or (key == keys.left) then",
552 " return false, longestLen",
553 " end",
554 " elseif evt == \"mouse_drag\" or evt == \"mouse_click\" then",
555 " if (mx >= x) and (mx < x+longestLen) and (my <= y and my > y-#options) then",
556 " sel = math.min(#options,math.max(1,(my+#options) - y))",
557 " usingMouse = true",
558 " else",
559 " usingMouse = false",
560 " if evt == \"mouse_click\" then",
561 " return false, longestLen",
562 " end",
563 " end",
564 " elseif evt == \"mouse_up\" then",
565 " if usingMouse then",
566 " return sel, longestLen",
567 " end",
568 " end",
569 " if sel > #options then sel = 1 elseif sel < 1 then sel = #options end",
570 " end",
571 "end",
572 "",
573 "local getDotsInLine = function( startX, startY, endX, endY ) -- stolen from the paintutils API...nwehehehe",
574 " local out = {}",
575 " startX = math.floor(startX)",
576 " startY = math.floor(startY)",
577 " endX = math.floor(endX)",
578 " endY = math.floor(endY)",
579 " if startX == endX and startY == endY then",
580 " out = {{x=startX,y=startY}}",
581 " return out",
582 " end",
583 " local minX = math.min( startX, endX )",
584 " if minX == startX then",
585 " minY = startY",
586 " maxX = endX",
587 " maxY = endY",
588 " else",
589 " minY = endY",
590 " maxX = startX",
591 " maxY = startY",
592 " end",
593 " local xDiff = maxX - minX",
594 " local yDiff = maxY - minY",
595 " if xDiff > math.abs(yDiff) then",
596 " local y = minY",
597 " local dy = yDiff / xDiff",
598 " for x=minX,maxX do",
599 " out[#out+1] = {x=x,y=math.floor(y+0.5)}",
600 " y = y + dy",
601 " end",
602 " else",
603 " local x = minX",
604 " local dx = xDiff / yDiff",
605 " if maxY >= minY then",
606 " for y=minY,maxY do",
607 " out[#out+1] = {x=math.floor(x+0.5),y=y}",
608 " x = x + dx",
609 " end",
610 " else",
611 " for y=minY,maxY,-1 do",
612 " out[#out+1] = {x=math.floor(x+0.5),y=y}",
613 " x = x - dx",
614 " end",
615 " end",
616 " end",
617 " return out",
618 "end",
619 "",
620 "local movePaintEncoded = function(pe,xdiff,ydiff)",
621 " local outpootis = deepCopy(pe)",
622 " for a = 1, #outpootis do",
623 " outpootis[a].x = outpootis[a].x+xdiff",
624 " outpootis[a].y = outpootis[a].y+ydiff",
625 " end",
626 " return outpootis",
627 "end",
628 "",
629 "local clearRedundant = function(dots)",
630 " local input = {}",
631 " local pheight = 0",
632 " local pwidth = 0",
633 " local minX, minY = 0, 0",
634 " for a = 1, #dots do",
635 " pheight = math.max(pheight, dots[a].y)",
636 " pwidth = math.max(pwidth, dots[a].x)",
637 " minX = math.min(minX, dots[a].x)",
638 " minY = math.min(minY, dots[a].y)",
639 " end",
640 " for a = 1, #dots do",
641 " if not input[dots[a].y] then input[dots[a].y] = {} end",
642 " input[dots[a].y][dots[a].x] = dots[a]",
643 " end",
644 " local output = {}",
645 " local frame = 0",
646 " for y = minY, pheight do",
647 " for x = minX, pwidth do",
648 " if input[y] then",
649 " if input[y][x] then",
650 " output[#output+1] = input[y][x]",
651 " end",
652 " end",
653 " if frame >= 50 then",
654 " -- yield()",
655 " frame = 0",
656 " end",
657 " end",
658 " end",
659 " return output",
660 "end",
661 "",
662 "local grayOut = function(color)",
663 " local c = deepCopy(_G.colors)",
664 " local grays = {",
665 " [c.white] = c.white,",
666 " [c.orange] = c.lightGray,",
667 " [c.magenta] = c.lightGray,",
668 " [c.lightBlue] = c.lightGray,",
669 " [c.yellow] = c.white,",
670 " [c.lime] = c.lightGray,",
671 " [c.pink] = c.lightGray,",
672 " [c.gray] = c.gray,",
673 " [c.lightGray] = c.lightGray,",
674 " [c.cyan] = c.lightGray,",
675 " [c.purple] = c.gray,",
676 " [c.blue] = c.gray,",
677 " [c.brown] = c.gray,",
678 " [c.green] = c.lightGray,",
679 " [c.red] = c.gray,",
680 " [c.black] = c.black,",
681 " }",
682 " if (not color) or (color == \" \") then return color end",
683 " local newColor = grays[color] or 1",
684 " return newColor",
685 "end",
686 "",
687 "local getOnscreenCoords = function(tbl,_x,_y)",
688 " local screenTbl = {}",
689 " for a = 1, #tbl do",
690 " if tbl[a].x+paint.scrollX > 0 and tbl[a].x+paint.scrollX <= scr_x then",
691 " if tbl[a].y+paint.scrollY > 0 and tbl[a].y+paint.scrollY <= scr_y then",
692 " screenTbl[#screenTbl+1] = {tbl[a].x+paint.scrollX,tbl[a].y+paint.scrollY}",
693 " end",
694 " end",
695 " end",
696 " if not _x and _y then",
697 " return screenTbl",
698 " else",
699 " for a = 1, #screenTbl do",
700 " if screenTbl[a][1] == _x and screenTbl[a][2] == _y then",
701 " return true",
702 " end",
703 " end",
704 " return false",
705 " end",
706 "end",
707 "",
708 "local clearAllRedundant = function(info)",
709 " local output = {}",
710 " for a = 1, #info do",
711 " output[a] = clearRedundant(info[a])",
712 " if a % 4 == 0 then yield() end",
713 " end",
714 " return output",
715 "end",
716 "",
717 "local saveFile = function(path,info)",
718 " local output = clearAllRedundant(info)",
719 " local fileout = textutils.serialize(output):gsub(\" \",\"\"):gsub(\"\\n\",\"\"):gsub(\" = \",\"=\"):gsub(\",}\",\"}\"):gsub(\"}},{{\",\"}},\\n{{\")",
720 " if #fileout >= fs.getFreeSpace(fs.getDir(path)) then",
721 " barmsg = \"Not enough space.\"",
722 " return",
723 " end",
724 " local file = fs.open(path,\"w\")",
725 " file.write(fileout)",
726 " file.close()",
727 "end",
728 "local renderBar = function(msg,dontSetVisible)",
729 " if (doRenderBar == 0) or renderBlittle then return end",
730 " if tsv and (not dontSetVisible) then tsv(false) end",
731 " term.setCursorPos(1,scr_y)",
732 " term.setBackgroundColor(colors.lightGray)",
733 " term.setTextColor(colors.black)",
734 " term.clearLine()",
735 " term.setBackgroundColor(paint.b or rendback.b)",
736 " term.setTextColor(paint.t or rendback.t)",
737 " term.setCursorPos(2,scr_y)",
738 " term.write(\"PAIN\")",
739 " term.setBackgroundColor(colors.lightGray)",
740 " term.setTextColor(colors.black)",
741 " local fmsg = tableconcat({\"Fr:\",frame,\"/\",#paintEncoded,\" (\",paint.scrollX,\",\",paint.scrollY,\")\"})",
742 " term.setCursorPos(7,scr_y)",
743 " term.write(msg)",
744 " term.setCursorPos(scr_x-(#fmsg),scr_y)",
745 " term.write(fmsg)",
746 " if tsv and (not dontSetVisible) then tsv(true) end",
747 "end",
748 "",
749 "local tableFormatPE = function(input)",
750 " local doot = {}",
751 " local pwidths = {}",
752 " local pheight = 0",
753 " for k, dot in pairs(input) do",
754 " pwidths[dot.y] = math.max((pwidths[dot.y] or 0), dot.x)",
755 " pheight = math.max(pheight, dot.y)",
756 " doot[dot.y] = doot[dot.y] or {}",
757 " doot[dot.y][dot.x] = {",
758 " char = dot.c,",
759 " text = CTB(dot.t),",
760 " back = CTB(dot.b)",
761 " }",
762 " end",
763 " for y = 1, pheight do",
764 " pwidths[y] = pwidths[y] or 0",
765 " if doot[y] then",
766 " for x = 1, pwidths[y] do",
767 " doot[y][x] = doot[y][x] or {",
768 " text = \" \",",
769 " back = \" \",",
770 " char = \" \",",
771 " }",
772 " end",
773 " else",
774 " doot[y] = false",
775 " end",
776 " end",
777 " return doot, pheight, pwidths",
778 "end",
779 "",
780 "CTB = function(_color) --Color To Blit",
781 " local blitcolors = {",
782 " [0] = \" \",",
783 " [colors.white] = \"0\",",
784 " [colors.orange] = \"1\",",
785 " [colors.magenta] = \"2\",",
786 " [colors.lightBlue] = \"3\",",
787 " [colors.yellow] = \"4\",",
788 " [colors.lime] = \"5\",",
789 " [colors.pink] = \"6\",",
790 " [colors.gray] = \"7\",",
791 " [colors.lightGray] = \"8\",",
792 " [colors.cyan] = \"9\",",
793 " [colors.purple] = \"a\",",
794 " [colors.blue] = \"b\",",
795 " [colors.brown] = \"c\",",
796 " [colors.green] = \"d\",",
797 " [colors.red] = \"e\",",
798 " [colors.black] = \"f\",",
799 " }",
800 " if _color == nil then return nil end",
801 " return blitcolors[_color] or \"f\"",
802 "end",
803 "",
804 "BTC = function(_color,allowZero) --Blit To Color",
805 " local blitcolors = {",
806 " [\" \"] = allowZero and 0 or nil,",
807 " [\"0\"] = colors.white,",
808 " [\"1\"] = colors.orange,",
809 " [\"2\"] = colors.magenta,",
810 " [\"3\"] = colors.lightBlue,",
811 " [\"4\"] = colors.yellow,",
812 " [\"5\"] = colors.lime,",
813 " [\"6\"] = colors.pink,",
814 " [\"7\"] = colors.gray,",
815 " [\"8\"] = colors.lightGray,",
816 " [\"9\"] = colors.cyan,",
817 " [\"a\"] = colors.purple,",
818 " [\"b\"] = colors.blue,",
819 " [\"c\"] = colors.brown,",
820 " [\"d\"] = colors.green,",
821 " [\"e\"] = colors.red,",
822 " [\"f\"] = colors.black,",
823 " }",
824 " if _color == nil then return nil end",
825 " return blitcolors[_color]",
826 "end",
827 "",
828 "local renderPainyThings = function(xscroll,yscroll,doGrid)",
829 " local yadjust = (renderBlittle and 0 or doRenderBar)",
830 " if bepimode then",
831 " grid = {",
832 " \"Bepis\",",
833 " \"episB\",",
834 " \"pisBe\",",
835 " \"isBep\",",
836 " \"sBepi\",",
837 " }",
838 " else",
839 " grid = {",
840 " \"%%..\",",
841 " \"%%..\",",
842 " \"%%..\",",
843 " \"..%%\",",
844 " \"..%%\",",
845 " \"..%%\",",
846 " }",
847 " end",
848 " term.setBackgroundColor(rendback.b)",
849 " term.setTextColor(rendback.t)",
850 " local badchar = \"/\"",
851 " local blittlelabel = \"blittle max\"",
852 " local screenlabel = \"screen max\"",
853 "",
854 " local dotBuffChar, dotBuffBack = \"\", \"\" --only used if gridBleedThrough is true",
855 " local doot",
856 " if doGrid then",
857 " for y = 1, scr_y - yadjust do",
858 " term.setCursorPos(1,y)",
859 " -- the single most convoluted line I've ever written that works, and I love it",
860 " term.write(stringShift(grid[ro(y+(yscroll+2),#grid)+1],xscroll+1):rep(math.ceil(scr_x/#grid[ro(y+(yscroll+2),#grid)+1])):sub(1,scr_x))",
861 " term.setCursorPos((xscroll <= 0) and (1-xscroll) or 0,y)",
862 " if ((screenEdges[2]+1)-yscroll) == y then --regular limit",
863 " term.write( (string.rep(\"@\", math.max(0,( (screenEdges[1]) ) - (#screenlabel+1) )) ..screenlabel:gsub(\" \",\"@\"):upper()..\"@@\"):sub(xscroll>0 and xscroll or 0):sub(1,1+screenEdges[1]) )",
864 " elseif (((screenEdges[2]*3)+1)-yscroll) == y then --blittle limit",
865 " term.write( (string.rep(\"@\", math.max(0,( ((screenEdges[1]*2)) ) - (#blittlelabel+1) ))..blittlelabel:gsub(\" \",\"@\"):upper()..\"@@\"):sub(xscroll>0 and xscroll or 0):sub(1,1+screenEdges[1]*2) )",
866 " end",
867 " -- Stupid easter eggs, ho! --",
868 " if 1000-yscroll == y then",
869 " term.setCursorPos(1000-xscroll,y)",
870 " term.write(\" What ARE you doing? Stop messing around! \")",
871 " end",
872 " if 2016-yscroll == y then",
873 " term.setCursorPos(200-xscroll,y)",
874 " term.write(\" Lines don't like to be intersected, you know. \")",
875 " end",
876 " if 2017-yscroll == y then",
877 " term.setCursorPos(200-xscroll,y)",
878 " term.write(\" It makes them very crossed. \")",
879 " end",
880 " if 800-yscroll == y then",
881 " term.setCursorPos(1700-xscroll,y)",
882 " term.write(\" You stare deeply into the void. \")",
883 " end",
884 " if 801-yscroll == y then",
885 " term.setCursorPos(1704-xscroll,y)",
886 " term.write(\" And the void \")",
887 " end",
888 " if 802-yscroll == y then",
889 " term.setCursorPos(1704-xscroll,y)",
890 " term.write(\" stares back. \")",
891 " end",
892 " --Is this the end?--",
893 " if (xscroll > ((screenEdges[1]*2)-scr_x)) then",
894 " for y = 1, scr_y do",
895 " if y+yscroll <= (screenEdges[2]*3) then",
896 " if not (y == scr_y and doRenderBar == 1) then",
897 " term.setCursorPos((screenEdges[1]+1)-(xscroll-screenEdges[1]),y)",
898 " term.write(\"@\")",
899 " end",
900 " end",
901 " end",
902 " end",
903 " if (xscroll > (screenEdges[1]-scr_x)) then --regular limit",
904 " for y = 1, scr_y do",
905 " if y+yscroll <= screenEdges[2] then",
906 " if not (y == scr_y and doRenderBar == 1) then",
907 " term.setCursorPos((screenEdges[1]+1)-xscroll,y)",
908 " term.write(\"@\")",
909 " end",
910 " end",
911 " end",
912 " end",
913 " end",
914 " --render areas that won't save",
915 " if xscroll < 0 then",
916 " for y = 1, scr_y do",
917 " if not (y == scr_y and doRenderBar == 1) then",
918 " term.setCursorPos(1,y)",
919 " term.write(badchar:rep(-xscroll))",
920 " end",
921 " end",
922 " end",
923 " if yscroll < 0 then",
924 " for y = 1, -yscroll do",
925 " if not (y == scr_y and doRenderBar == 1) then",
926 " term.setCursorPos(1,y)",
927 " term.write(badchar:rep(scr_x))",
928 " end",
929 " end",
930 " end",
931 " else",
932 " for y = 1, scr_y - yadjust do",
933 " term.setCursorPos(1,y)",
934 " term.clearLine()",
935 " end",
936 " end",
937 "end",
938 "",
939 "importFromPaint = function(theInput)",
940 " local output = {}",
941 " local input",
942 " if type(theInput) == \"string\" then",
943 " input = explode(\"\\n\",theInput)",
944 " else",
945 " input = {}",
946 " for y = 1, #theInput do",
947 " input[y] = \"\"",
948 " for x = 1, #theInput[y] do",
949 " input[y] = input[y]..(CTB(theInput[y][x]) or \" \")",
950 " end",
951 " end",
952 " end",
953 " for a = 1, #input do",
954 " line = input[a]",
955 " for b = 1, #line do",
956 " if (line:sub(b,b) ~= \" \") and BTC(line:sub(b,b)) then",
957 " output[#output+1] = {",
958 " x = b,",
959 " y = a,",
960 " t = colors.white,",
961 " b = BTC(line:sub(b,b)) or colors.black,",
962 " c = \" \",",
963 " }",
964 " end",
965 " end",
966 " end",
967 " return output",
968 "end",
969 "",
970 "local lddfm = {",
971 " scroll = 0,",
972 " ypaths = {}",
973 "}",
974 "",
975 "lddfm.scr_x, lddfm.scr_y = term.getSize()",
976 "",
977 "lddfm.setPalate = function(_p)",
978 " if type(_p) ~= \"table\" then",
979 " _p = {}",
980 " end",
981 " lddfm.p = { --the DEFAULT color palate",
982 " bg = _p.bg or colors.gray, -- whole background color",
983 " d_txt = _p.d_txt or colors.yellow, -- directory text color",
984 " d_bg = _p.d_bg or colors.gray, -- directory bg color",
985 " f_txt = _p.f_txt or colors.white, -- file text color",
986 " f_bg = _p.f_bg or colors.gray, -- file bg color",
987 " p_txt = _p.p_txt or colors.black, -- path text color",
988 " p_bg = _p.p_bg or colors.lightGray, -- path bg color",
989 " close_txt = _p.close_txt or colors.gray, -- close button text color",
990 " close_bg = _p.close_bg or colors.lightGray,-- close button bg color",
991 " scr = _p.scr or colors.lightGray, -- scrollbar color",
992 " scrbar = _p.scrbar or colors.gray, -- scroll tab color",
993 " }",
994 "end",
995 "",
996 "lddfm.setPalate()",
997 "",
998 "lddfm.foldersOnTop = function(floop,path)",
999 " local output = {}",
1000 " for a = 1, #floop do",
1001 " if fs.isDir(fs.combine(path,floop[a])) then",
1002 " table.insert(output,1,floop[a])",
1003 " else",
1004 " table.insert(output,floop[a])",
1005 " end",
1006 " end",
1007 " return output",
1008 "end",
1009 "",
1010 "lddfm.filterFileFolders = function(list,path,_noFiles,_noFolders,_noCD,_doHidden)",
1011 " local output = {}",
1012 " for a = 1, #list do",
1013 " local entry = fs.combine(path,list[a])",
1014 " if fs.isDir(entry) then",
1015 " if entry == \"..\" then",
1016 " if not (_noCD or _noFolders) then table.insert(output,list[a]) end",
1017 " else",
1018 " if not ((not _doHidden) and list[a]:sub(1,1) == \".\") then",
1019 " if not _noFolders then table.insert(output,list[a]) end",
1020 " end",
1021 " end",
1022 " else",
1023 " if not ((not _doHidden) and list[a]:sub(1,1) == \".\") then",
1024 " if not _noFiles then table.insert(output,list[a]) end",
1025 " end",
1026 " end",
1027 " end",
1028 " return output",
1029 "end",
1030 "",
1031 "lddfm.isColor = function(col)",
1032 " for k,v in pairs(colors) do",
1033 " if v == col then",
1034 " return true, k",
1035 " end",
1036 " end",
1037 " return false",
1038 "end",
1039 "",
1040 "lddfm.clearLine = function(x1,x2,_y,_bg,_char)",
1041 " local cbg, bg = term.getBackgroundColor()",
1042 " local x,y = term.getCursorPos()",
1043 " local sx,sy = term.getSize()",
1044 " if type(_char) == \"string\" then char = _char else char = \" \" end",
1045 " if type(_bg) == \"number\" then",
1046 " if lddfm.isColor(_bg) then bg = _bg",
1047 " else bg = cbg end",
1048 " else bg = cbg end",
1049 " term.setCursorPos(x1 or 1, _y or y)",
1050 " term.setBackgroundColor(bg)",
1051 " if x2 then --it pains me to add an if statement to something as simple as this",
1052 " term.write((char or \" \"):rep(x2-x1))",
1053 " else",
1054 " term.write((char or \" \"):rep(sx-(x1 or 0)))",
1055 " end",
1056 " term.setBackgroundColor(cbg)",
1057 " term.setCursorPos(x,y)",
1058 "end",
1059 "",
1060 "lddfm.render = function(_x1,_y1,_x2,_y2,_rlist,_path,_rscroll,_canClose,_scrbarY)",
1061 " local tsv = term.current().setVisible",
1062 " local px,py = term.getCursorPos()",
1063 " if tsv then tsv(false) end",
1064 " local x1, x2, y1, y2 = _x1 or 1, _x2 or lddfm.scr_x, _y1 or 1, _y2 or lddfm.scr_y",
1065 " local rlist = _rlist or {\"Invalid directory.\"}",
1066 " local path = _path or \"And that's terrible.\"",
1067 " ypaths = {}",
1068 " local rscroll = _rscroll or 0",
1069 " for a = y1, y2 do",
1070 " lddfm.clearLine(x1,x2,a,lddfm.p.bg)",
1071 " end",
1072 " term.setCursorPos(x1,y1)",
1073 " term.setTextColor(lddfm.p.p_txt)",
1074 " lddfm.clearLine(x1,x2+1,y1,lddfm.p.p_bg)",
1075 " term.setBackgroundColor(lddfm.p.p_bg)",
1076 " term.write((\"/\"..path):sub(1,x2-x1))",
1077 " for a = 1,(y2-y1) do",
1078 " if rlist[a+rscroll] then",
1079 " term.setCursorPos(x1,a+(y1))",
1080 " if fs.isDir(fs.combine(path,rlist[a+rscroll])) then",
1081 " lddfm.clearLine(x1,x2,a+(y1),lddfm.p.d_bg)",
1082 " term.setTextColor(lddfm.p.d_txt)",
1083 " term.setBackgroundColor(lddfm.p.d_bg)",
1084 " else",
1085 " lddfm.clearLine(x1,x2,a+(y1),lddfm.p.f_bg)",
1086 " term.setTextColor(lddfm.p.f_txt)",
1087 " term.setBackgroundColor(lddfm.p.f_bg)",
1088 " end",
1089 " term.write(rlist[a+rscroll]:sub(1,x2-x1))",
1090 " ypaths[a+(y1)] = rlist[a+rscroll]",
1091 " else",
1092 " lddfm.clearLine(x1,x2,a+(y1),lddfm.p.bg)",
1093 " end",
1094 " end",
1095 " local scrbarY = _scrbarY or math.ceil( (y1+1)+( (_rscroll/(#_rlist-(y2-(y1+1))))*(y2-(y1+1)) ) )",
1096 " for a = y1+1, y2 do",
1097 " term.setCursorPos(x2,a)",
1098 " if a == scrbarY then",
1099 " term.setBackgroundColor(lddfm.p.scrbar)",
1100 " else",
1101 " term.setBackgroundColor(lddfm.p.scr)",
1102 " end",
1103 " term.write(\" \")",
1104 " end",
1105 " if _canClose then",
1106 " term.setCursorPos(x2-4,y1)",
1107 " term.setTextColor(lddfm.p.close_txt)",
1108 " term.setBackgroundColor(lddfm.p.close_bg)",
1109 " term.write(\"close\")",
1110 " end",
1111 " term.setCursorPos(px,py)",
1112 " if tsv then tsv(true) end",
1113 " return scrbarY",
1114 "end",
1115 "",
1116 "lddfm.coolOutro = function(x1,y1,x2,y2,_bg,_txt,char)",
1117 " local cx, cy = term.getCursorPos()",
1118 " local bg, txt = term.getBackgroundColor(), term.getTextColor()",
1119 " term.setTextColor(_txt or colors.white)",
1120 " term.setBackgroundColor(_bg or colors.black)",
1121 " local _uwah = 0",
1122 " for y = y1, y2 do",
1123 " for x = x1, x2 do",
1124 " _uwah = _uwah + 1",
1125 " term.setCursorPos(x,y)",
1126 " term.write(char or \" \")",
1127 " if _uwah >= math.ceil((x2-x1)*1.63) then sleep(0) _uwah = 0 end",
1128 " end",
1129 " end",
1130 " term.setTextColor(txt)",
1131 " term.setBackgroundColor(bg)",
1132 " term.setCursorPos(cx,cy)",
1133 "end",
1134 "",
1135 "lddfm.scrollMenu = function(amount,list,y1,y2)",
1136 " if #list >= y2-y1 then",
1137 " lddfm.scroll = lddfm.scroll + amount",
1138 " if lddfm.scroll < 0 then",
1139 " lddfm.scroll = 0",
1140 " end",
1141 " if lddfm.scroll > #list-(y2-y1) then",
1142 " lddfm.scroll = #list-(y2-y1)",
1143 " end",
1144 " end",
1145 "end",
1146 "",
1147 "lddfm.makeMenu = function(_x1,_y1,_x2,_y2,_path,_noFiles,_noFolders,_noCD,_noSelectFolders,_doHidden,_p,_canClose)",
1148 " if _noFiles and _noFolders then",
1149 " return false, \"C'mon, man...\"",
1150 " end",
1151 " if _x1 == true then",
1152 " return false, \"arguments: x1, y1, x2, y2, path, noFiles, noFolders, noCD, noSelectFolders, doHidden, palate, canClose\" -- a little help",
1153 " end",
1154 " lddfm.setPalate(_p)",
1155 " local path, list = _path or \"\"",
1156 " lddfm.scroll = 0",
1157 " local _pbg, _ptxt = term.getBackgroundColor(), term.getTextColor()",
1158 " local x1, x2, y1, y2 = _x1 or 1, _x2 or lddfm.scr_x, _y1 or 1, _y2 or lddfm.scr_y",
1159 " local keysDown = {}",
1160 " local _barrY",
1161 " while true do",
1162 " list = lddfm.foldersOnTop(lddfm.filterFileFolders(fs.list(path),path,_noFiles,_noFolders,_noCD,_doHidden),path)",
1163 " if (fs.getDir(path) ~= \"..\") and not (_noCD or _noFolders) then",
1164 " table.insert(list,1,\"..\")",
1165 " end",
1166 " _res, _barrY = pcall( function() return lddfm.render(x1,y1,x2,y2,list,path,lddfm.scroll,_canClose) end)",
1167 " if not _res then",
1168 " local tsv = term.current().setVisible",
1169 " if tsv then tsv(true) end",
1170 " error(_barrY)",
1171 " end",
1172 " local evt = {os.pullEvent()}",
1173 " if evt[1] == \"mouse_scroll\" then",
1174 " lddfm.scrollMenu(evt[2],list,y1,y2)",
1175 " elseif evt[1] == \"mouse_click\" then",
1176 " local butt,mx,my = evt[2],evt[3],evt[4]",
1177 " if (butt == 1 and my == y1 and mx <= x2 and mx >= x2-4) and _canClose then",
1178 " --lddfm.coolOutro(x1,y1,x2,y2)",
1179 " term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
1180 " return false",
1181 " elseif ypaths[my] and (mx >= x1 and mx < x2) then --x2 is reserved for the scrollbar, breh",
1182 " if fs.isDir(fs.combine(path,ypaths[my])) then",
1183 " if _noCD or butt == 3 then",
1184 " if not _noSelectFolders or _noFolders then",
1185 " --lddfm.coolOutro(x1,y1,x2,y2)",
1186 " term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
1187 " return fs.combine(path,ypaths[my])",
1188 " end",
1189 " else",
1190 " path = fs.combine(path,ypaths[my])",
1191 " lddfm.scroll = 0",
1192 " end",
1193 " else",
1194 " term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
1195 " return fs.combine(path,ypaths[my])",
1196 " end",
1197 " end",
1198 " elseif evt[1] == \"key\" then",
1199 " keysDown[evt[2]] = true",
1200 " if evt[2] == keys.enter and not (_noFolders or _noCD or _noSelectFolders) then --the logic for _noCD being you'd normally need to go back a directory to select the current directory.",
1201 " --lddfm.coolOutro(x1,y1,x2,y2)",
1202 " term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
1203 " return path",
1204 " end",
1205 " if evt[2] == keys.up then",
1206 " lddfm.scrollMenu(-1,list,y1,y2)",
1207 " elseif evt[2] == keys.down then",
1208 " lddfm.scrollMenu(1,list,y1,y2)",
1209 " end",
1210 " if evt[2] == keys.pageUp then",
1211 " lddfm.scrollMenu(y1-y2,list,y1,y2)",
1212 " elseif evt[2] == keys.pageDown then",
1213 " lddfm.scrollMenu(y2-y1,list,y1,y2)",
1214 " end",
1215 " if evt[2] == keys.home then",
1216 " lddfm.scroll = 0",
1217 " elseif evt[2] == keys[\"end\"] then",
1218 " if #list > (y2-y1) then",
1219 " lddfm.scroll = #list-(y2-y1)",
1220 " end",
1221 " end",
1222 " if evt[2] == keys.h then",
1223 " if keysDown[keys.leftCtrl] or keysDown[keys.rightCtrl] then",
1224 " _doHidden = not _doHidden",
1225 " end",
1226 " elseif _canClose and (evt[2] == keys.x or evt[2] == keys.q or evt[2] == keys.leftCtrl) then",
1227 " --lddfm.coolOutro(x1,y1,x2,y2)",
1228 " term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
1229 " return false",
1230 " end",
1231 " elseif evt[1] == \"key_up\" then",
1232 " keysDown[evt[2]] = false",
1233 " end",
1234 " end",
1235 "end",
1236 "",
1237 "local getBlittle = function()",
1238 " if not blittle then",
1239 " if fs.exists(fs.combine(apipath,\"blittle\")) then",
1240 " os.loadAPI(fs.combine(apipath,\"blittle\"))",
1241 " if not blittleTerm then",
1242 " blittleTerm = blittle.createWindow()",
1243 " end",
1244 " return blittleTerm, firstTerm",
1245 " else",
1246 " local geet = http.get(\"http://pastebin.com/raw/ujchRSnU\")",
1247 " if not geet then",
1248 " return false",
1249 " else",
1250 " geet = geet.readAll()",
1251 " local file = fs.open(fs.combine(apipath,\"blittle\"),\"w\")",
1252 " file.write(geet)",
1253 " file.close()",
1254 " os.loadAPI(fs.combine(apipath,\"blittle\"))",
1255 " --fs.delete(apipath)",
1256 " if not blittleTerm then",
1257 " blittleTerm = blittle.createWindow()",
1258 " end",
1259 " return blittleTerm, firstTerm",
1260 " end",
1261 " end",
1262 " else",
1263 " if not blittleTerm then",
1264 " blittleTerm = blittle.createWindow()",
1265 " end",
1266 " return blittleTerm, firstTerm",
1267 " end",
1268 "end",
1269 "",
1270 "local getUCG = function()",
1271 " if not ucg then",
1272 " if fs.exists(fs.combine(apipath,\"ucg\")) then",
1273 " os.loadAPI(fs.combine(apipath,\"ucg\"))",
1274 " return true",
1275 " else",
1276 " local geet = http.get(\"https://raw.githubusercontent.com/ardera/libucg/master/src/libucg\")",
1277 " if not geet then",
1278 " return false",
1279 " else",
1280 " geet = geet.readAll()",
1281 " local file = fs.open(fs.combine(apipath,\"ucg\"),\"w\")",
1282 " file.write(geet)",
1283 " file.close()",
1284 " os.loadAPI(fs.combine(apipath,\"ucg\"))",
1285 " end",
1286 " end",
1287 " end",
1288 "end",
1289 "",
1290 "local getBBPack = function()",
1291 " if not bbpack then",
1292 " if fs.exists(fs.combine(apipath,\"bbpack\")) then",
1293 " os.loadAPI(fs.combine(apipath,\"bbpack\"))",
1294 " return true",
1295 " else",
1296 " local geet = http.get(\"https://pastebin.com/raw/cUYTGbpb\")",
1297 " if not geet then",
1298 " return false",
1299 " else",
1300 " geet = geet.readAll()",
1301 " local file = fs.open(fs.combine(apipath,\"bbpack\"),\"w\")",
1302 " file.write(geet)",
1303 " file.close()",
1304 " os.loadAPI(fs.combine(apipath,\"bbpack\"))",
1305 " end",
1306 " end",
1307 " end",
1308 "end",
1309 "",
1310 "local getGIF = function()",
1311 " getBBPack()",
1312 " if not GIF then",
1313 " if fs.exists(fs.combine(apipath,\"GIF\")) then",
1314 " os.loadAPI(fs.combine(apipath,\"GIF\"))",
1315 " return true",
1316 " else",
1317 " local geet = http.get(\"https://pastebin.com/raw/5uk9uRjC\")",
1318 " if not geet then",
1319 " return false",
1320 " else",
1321 " geet = geet.readAll()",
1322 " local file = fs.open(fs.combine(apipath,\"GIF\"),\"w\")",
1323 " file.write(geet)",
1324 " file.close()",
1325 " os.loadAPI(fs.combine(apipath,\"GIF\"))",
1326 " end",
1327 " end",
1328 " end",
1329 "end",
1330 "",
1331 "local NFPserializeImage = function(str)",
1332 " local bepis = explode(\"\\n\",str)",
1333 " local output = {}",
1334 " for y = 1, #bepis do",
1335 " output[y] = {}",
1336 " for x = 1, #bepis[y] do",
1337 " output[y][x] = BTC(bepis[y]:sub(x,x),true)",
1338 " end",
1339 " end",
1340 " return textutils.unserialize(textutils.serialize(output):gsub(\"\\n\",\"\"):gsub(\" \",\"\"):gsub(\",}\",\"}\"))",
1341 "end",
1342 "",
1343 "local importFromGIF = function(filename,verbose)",
1344 " getGIF()",
1345 " local output = {}",
1346 " local image",
1347 " local rawGif = GIF.loadGIF(filename)",
1348 " if painconfig.useFlattenGIF then",
1349 " if verbose then",
1350 " print(\"Flattening...\")",
1351 " end",
1352 " rawGif = GIF.flattenGIF(rawGif)",
1353 " sleep(0)",
1354 " end",
1355 " local cx, cy = term.getCursorPos()",
1356 " for a = 1, #rawGif do",
1357 " output[a] = importFromPaint(GIF.toPaintutils(rawGif[a]))",
1358 " if verbose then",
1359 " term.setCursorPos(cx,cy)",
1360 " write(\"Did \"..a..\"/\"..#rawGif..\" \")",
1361 " end",
1362 " if a % 1 then sleep(0) end --used to be a % 2, might change later",
1363 " end",
1364 " return output",
1365 "end",
1366 "",
1367 "local exportToPaint",
1368 "",
1369 "local exportToGIF = function(input)",
1370 " getGIF()",
1371 " local outGIF = {}",
1372 " for a = 1, #paintEncoded do",
1373 " outGIF[a] = NFPserializeImage(exportToPaint(paintEncoded[a]))",
1374 " sleep(0)",
1375 " end",
1376 " if painconfig.useFlattenGIF then",
1377 " return GIF.flattenGIF(GIF.buildGIF(table.unpack(outGIF)),true)",
1378 " else",
1379 " return GIF.buildGIF(table.unpack(outGIF))",
1380 " end",
1381 "end",
1382 "",
1383 "local importFromUCG = function(filename)",
1384 " getUCG()",
1385 " return importFromPaint(ucg.readFile(filename))",
1386 "end",
1387 "",
1388 "local exportToUCG = function(filename, input)",
1389 " getUCG()",
1390 " ucg.writeFile(filename, NFPserializeImage(exportToPaint(input)))",
1391 "end",
1392 "",
1393 "renderPAIN = function(dots,xscroll,yscroll,doPain,dontRenderBar)",
1394 " if tsv then tsv(false) end",
1395 " local beforeTX,beforeBG = term.getTextColor(), term.getBackgroundColor()",
1396 " local cx,cy = term.getCursorPos()",
1397 " local FUCK, SHIT = pcall(function()",
1398 " if doPain then",
1399 " if (not renderBlittle) then",
1400 " if not dontRenderBar then",
1401 " renderBar(barmsg,true)",
1402 " end",
1403 " renderPainyThings(xscroll,yscroll,evenDrawGrid)",
1404 " else",
1405 " term.clear()",
1406 " end",
1407 " end",
1408 " for a = 1, #dots do",
1409 " local d = dots[a]",
1410 " if doPain then",
1411 " if not ((d.y-yscroll >= 1 and d.y-yscroll <= scr_y-(renderBlittle and 0 or doRenderBar)) and (d.x-xscroll >= 1 and d.x-xscroll <= scr_x)) then",
1412 " d = nil",
1413 " end",
1414 " end",
1415 " if d then",
1416 " term.setCursorPos(d.x-(xscroll or 0),d.y-(yscroll or 0))",
1417 " term.setBackgroundColor((paint.doGray and grayOut(d.b) or d.b) or rendback.b)",
1418 " if painconfig.gridBleedThrough then",
1419 " term.setTextColor(rendback.t)",
1420 " term.write((d.x >= 1 and d.y >= 1) and grid[ ro( d.y+2, #grid)+1]:sub(1+ro(d.x+-1,#grid[1]), 1+ro(d.x+-1,#grid[1])) or \"/\")",
1421 " else",
1422 " term.setTextColor( (paint.doGray and grayOut(d.t) or d.t) or rendback.t)",
1423 " term.write(d.c or \" \")",
1424 " end",
1425 " end",
1426 " end",
1427 " end)",
1428 " term.setBackgroundColor(beforeBG or rendback.b)",
1429 " term.setTextColor(beforeTX or rendback.t)",
1430 " term.setCursorPos(cx,cy)",
1431 " if tsv then tsv(true) end",
1432 " if not FUCK then error(SHIT) end --GOD DAMN IT",
1433 "end",
1434 "",
1435 "renderPAINFS = function(filename,xscroll,yscroll,frameNo,doPain)",
1436 " local tun, tse = textutils.unserialize, textutils.serialize",
1437 " local file = fs.open(filename,\"r\")",
1438 " local contents = file.readAll()",
1439 " local amntFrames",
1440 " file.close()",
1441 " local tcontents = tun(contents)",
1442 " if type(tcontents) ~= \"table\" then",
1443 " tcontents = importFromPaint(contents)",
1444 " else",
1445 " amntFrames = #tcontents",
1446 " tcontents = tcontents[frameNo or 1]",
1447 " end",
1448 " renderPAIN(tcontents,xscroll,yscroll,doPain)",
1449 " return amntFrames",
1450 "end",
1451 "",
1452 "local putDotDown = function(dot) -- only 'x' and 'y' are required arguments",
1453 " paintEncoded[frame][#paintEncoded[frame]+1] = {",
1454 " x = dot.x + paint.scrollX,",
1455 " y = dot.y + paint.scrollY,",
1456 " c = dot.c or paint.c,",
1457 " b = dot.b or (swapColors and paint.t or paint.b),",
1458 " t = dot.t or (swapColors and paint.b or paint.t),",
1459 " m = dot.m or paint.m,",
1460 " }",
1461 "end",
1462 "",
1463 "local saveToUndoBuffer = function()",
1464 " if undoPos < #undoBuffer then",
1465 " for a = #undoBuffer, undoPos+1, -1 do",
1466 " table.remove(undoBuffer,a)",
1467 " end",
1468 " end",
1469 " if undoPos >= painconfig.undoBufferSize then",
1470 " for a = 2, #undoBuffer do",
1471 " undoBuffer[a-1] = undoBuffer[a]",
1472 " end",
1473 " undoBuffer[#undoBuffer] = deepCopy(paintEncoded)",
1474 " else",
1475 " undoPos = undoPos + 1",
1476 " undoBuffer[undoPos] = deepCopy(paintEncoded)",
1477 " end",
1478 "end",
1479 "",
1480 "local doUndo = function()",
1481 " undoPos = math.max(1,undoPos-1)",
1482 " paintEncoded = deepCopy(undoBuffer[undoPos])",
1483 " if not paintEncoded[frame] then",
1484 " frame = #paintEncoded",
1485 " end",
1486 "end",
1487 "",
1488 "local doRedo = function()",
1489 " undoPos = math.min(#undoBuffer,undoPos+1)",
1490 " paintEncoded = deepCopy(undoBuffer[undoPos])",
1491 " if not paintEncoded[frame] then",
1492 " frame = #paintEncoded",
1493 " end",
1494 "end",
1495 "",
1496 "local putDownText = function(x,y)",
1497 " term.setCursorPos(x,y)",
1498 " term.setTextColor((paint.doGray and grayOut(paint.t or rendback.t)) or (paint.t or rendback.t))",
1499 " term.setBackgroundColor((paint.doGray and grayOut(paint.b or rendback.b)) or (paint.b or rendback.b))",
1500 " local msg = read()",
1501 " if #msg > 0 then",
1502 " for a = 1, #msg do",
1503 " putDotDown({x=(x+a)-1, y=y, c=msg:sub(a,a)})",
1504 " end",
1505 " end",
1506 " saveToUndoBuffer()",
1507 "end",
1508 "",
1509 "local deleteDot = function(x,y) --deletes all dots at point x,y",
1510 " local good = false",
1511 " for a = #paintEncoded[frame],1,-1 do",
1512 " local b = paintEncoded[frame][a]",
1513 " if (x == b.x) and (y == b.y) then",
1514 " table.remove(paintEncoded[frame],a)",
1515 " good = true",
1516 " end",
1517 " end",
1518 " return good",
1519 "end",
1520 "",
1521 "exportToPaint = function(input,noTransparent) --exports paintEncoded frame to regular paint format. input is expected to be paintEncoded[frame]",
1522 " local doopTXT, doopTXCOL, doopBGCOL = {}, {}, {}",
1523 " local p = input",
1524 " local pheight = 0",
1525 " local pwidth = 0",
1526 " for a = 1, #p do",
1527 " if p[a].y > pheight then",
1528 " pheight = p[a].y",
1529 " end",
1530 " if p[a].x > pwidth then",
1531 " pwidth = p[a].x",
1532 " end",
1533 " end",
1534 " for k,v in pairs(p) do",
1535 " if not doopBGCOL[v.y] then",
1536 " doopBGCOL[v.y] = {}",
1537 " doopTXCOL[v.y] = {}",
1538 " doopTXT[v.y] = {}",
1539 " end",
1540 " doopBGCOL[v.y][v.x] = CTB(v.b)",
1541 " doopTXCOL[v.y][v.x] = CTB(v.t)",
1542 " doopTXT[v.y][v.x] = v.c",
1543 " end",
1544 " local nfpoutputTXT, nfpoutputTXCOL, nfpoutputBGCOL = \"\", \"\", \"\"",
1545 " for y = 1, pheight do",
1546 " if doopBGCOL[y] then",
1547 " for x = 1, pwidth do",
1548 " if doopBGCOL[y][x] then",
1549 " nfpoutputBGCOL = nfpoutputBGCOL..doopBGCOL[y][x]",
1550 " nfpoutputTXCOL = nfpoutputTXCOL..doopTXCOL[y][x]",
1551 " nfpoutputTXT = nfpoutputTXT..(((doopTXT[y][x] == \" \" and noTransparent) and \"€\" or doopTXT[y][x]) or \" \")",
1552 " else",
1553 " nfpoutputBGCOL = nfpoutputBGCOL..(noTransparent and \"0\" or \" \")",
1554 " nfpoutputTXCOL = nfpoutputTXCOL..(noTransparent and \"0\" or \" \")",
1555 " nfpoutputTXT = nfpoutputTXT..\" \"",
1556 " end",
1557 " end",
1558 " end",
1559 " if y ~= pheight then",
1560 " nfpoutputBGCOL = nfpoutputBGCOL..\"\\n\"",
1561 " nfpoutputTXCOL = nfpoutputTXCOL..\"\\n\"",
1562 " nfpoutputTXT = nfpoutputTXT..\"\\n\"",
1563 " end",
1564 " end",
1565 " return nfpoutputBGCOL, pheight, pwidth",
1566 "end",
1567 "",
1568 "local exportToNFT = function(input)",
1569 "",
1570 " local bgcode, txcode = \"\\30\", \"\\31\"",
1571 " local output = \"\"",
1572 " local text, back",
1573 "",
1574 " local doot, pheight, pwidths = tableFormatPE(input)",
1575 "",
1576 " for y = 1, pheight do",
1577 "",
1578 " text, back = \"0\", \"f\"",
1579 " if doot[y] then",
1580 " for x = 1, pwidths[y] do",
1581 "",
1582 " if doot[y][x] then",
1583 " if doot[y][x].back ~= back then",
1584 " back = doot[y][x].back",
1585 " output = output .. bgcode .. back",
1586 " end",
1587 " if doot[y][x].text ~= text then",
1588 " text = doot[y][x].text",
1589 " output = output .. txcode .. text",
1590 " end",
1591 " output = output .. doot[y][x].char",
1592 " else",
1593 " output = output .. \" \"",
1594 " end",
1595 "",
1596 " end",
1597 " end",
1598 "",
1599 " if y < pheight then",
1600 " output = output .. \"\\n\"",
1601 " end",
1602 " end",
1603 " return output",
1604 "end",
1605 "",
1606 "local importFromNFT = function(input) --imports NFT formatted string image to paintEncoded[frame] formatted table image. please return a paintEncoded[frame] formatted table.",
1607 " local tinput = explode(\"\\n\",input)",
1608 " local tcol,bcol",
1609 " local cx --represents the x position in the picture",
1610 " local sx --represents the x position in the file",
1611 " local output = {}",
1612 " for y = 1, #tinput do",
1613 " tcol,bcol = colors.white,colors.black",
1614 " cx, sx = 1, 0",
1615 " while sx < #tinput[y] do",
1616 " sx = sx + 1",
1617 " if tinput[y]:sub(sx,sx) == \"\\30\" then",
1618 " bcol = BTC(tinput[y]:sub(sx+1,sx+1))",
1619 " sx = sx + 1",
1620 " elseif tinput[y]:sub(sx,sx) == \"\\31\" then",
1621 " tcol = BTC(tinput[y]:sub(sx+1,sx+1))",
1622 " sx = sx + 1",
1623 " else",
1624 " if tcol and bcol then",
1625 " output[#output+1] = {",
1626 " [\"x\"] = cx,",
1627 " [\"y\"] = y,",
1628 " [\"b\"] = bcol,",
1629 " [\"t\"] = tcol,",
1630 " [\"c\"] = tinput[y]:sub(sx,sx),",
1631 " [\"m\"] = 0,",
1632 " }",
1633 " end",
1634 " cx = cx + 1",
1635 " end",
1636 " end",
1637 " end",
1638 " return output",
1639 "end",
1640 "",
1641 "exportToBLT = function(input,filename,doAllFrames,noSave)",
1642 " local output = {}",
1643 " local thisImage,pheight,pwidth,nfpinput",
1644 " getBlittle()",
1645 " for a = doAllFrames and 1 or frame, doAllFrames and #input or frame do",
1646 " output[#output+1] = blittle.shrink(NFPserializeImage(exportToPaint(input[a]),true),colors.black)",
1647 " end",
1648 " if #output == 1 then output = output[1] end",
1649 " if not noSave then",
1650 " blittle.save(output,filename)",
1651 " end",
1652 " return output",
1653 "end",
1654 "",
1655 "importFromBLT = function(input) --takes in filename, not contents",
1656 " local output = {}",
1657 " getBlittle()",
1658 " local wholePic = blittle.load(input)",
1659 " if wholePic.height then wholePic = {wholePic} end",
1660 " local image",
1661 " for a = 1, #wholePic do",
1662 " image = wholePic[a]",
1663 " output[#output+1] = {}",
1664 " for y = 1, image.height*3 do",
1665 " for x = 1, math.max(#image[1][math.ceil(y/3)],#image[2][math.ceil(y/3)],#image[3][math.ceil(y/3)])*2 do",
1666 " output[#output][#output[#output]+1] = {",
1667 " m = 0,",
1668 " x = x,",
1669 " y = y,",
1670 " t = BTC((image[2][math.ceil(y/3)]:sub(math.ceil(x/2),math.ceil(x/2))..\"0\"):sub(1,1)),",
1671 " b = BTC((image[3][math.ceil(y/3)]:sub(math.ceil(x/2),math.ceil(x/2))..\"0\"):sub(1,1)),",
1672 " c = BTC((image[1][math.ceil(y/3)]:sub(math.ceil(x/2),math.ceil(x/2))..\" \"):sub(1,1)),",
1673 " }",
1674 " end",
1675 " end",
1676 " end",
1677 " return output",
1678 "end",
1679 "",
1680 "local getTheDoots = function(pe)",
1681 " local hasBadDots = false",
1682 " local baddestX,baddestY = 1,1",
1683 " for b = 1, #pe do",
1684 " local doot = pe[b]",
1685 " if doot.x <= 0 or doot.y <= 0 then",
1686 " hasBadDots = true",
1687 " if doot.x < baddestX then",
1688 " baddestX = doot.x",
1689 " end",
1690 " if doot.y < baddestY then",
1691 " baddestY = doot.y",
1692 " end",
1693 " end",
1694 " if b % 64 == 0 then yield() end",
1695 " end",
1696 " return baddestX, baddestY",
1697 "end",
1698 "",
1699 "local checkBadDots = function()",
1700 " local hasBadDots = false",
1701 " for a = 1, #paintEncoded do",
1702 " local radx,rady = getTheDoots(paintEncoded[a])",
1703 " if radx ~= 1 or rady ~= 1 then",
1704 " hasBadDots = true",
1705 " end",
1706 " end",
1707 " if hasBadDots then",
1708 " local ting = bottomPrompt(\"Dot(s) are OoB! Save or fix? (Y/N/F)\",_,\"ynf\",{keys.leftCtrl,keys.rightCtrl})",
1709 " if ting == \"f\" then",
1710 " for a = 1, #paintEncoded do",
1711 " local baddestX, baddestY = getTheDoots(paintEncoded[a])",
1712 " paintEncoded[a] = movePaintEncoded(paintEncoded[a],-(baddestX-1),-(baddestY-1))",
1713 " end",
1714 " elseif ting ~= \"y\" then",
1715 " barmsg = \"\"",
1716 " return false",
1717 " end",
1718 " end",
1719 "end",
1720 "",
1721 "local convertToGrayscale = function(pe)",
1722 " local output = pe",
1723 " for a = 1, #pe do",
1724 " for b = 1, #pe[a] do",
1725 " output[a][b].b = grayOut(pe[a][b].b)",
1726 " output[a][b].t = grayOut(pe[a][b].t)",
1727 " if not output[a][b].m then output[a][b].m = 1 end",
1728 " end",
1729 " if a % 2 == 0 then yield() end",
1730 " end",
1731 " return output",
1732 "end",
1733 "",
1734 "local reRenderPAIN = function(overrideRenderBar)",
1735 " local _reallyDoRenderBar = doRenderBar",
1736 "-- doRenderBar = 1",
1737 " renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true,overrideRenderBar)",
1738 " doRenderBar = _reallyDoRenderBar",
1739 "end",
1740 "",
1741 "local fillTool = function(_frame,cx,cy,dot,isDeleting) -- \"_frame\" is the frame NUMBER",
1742 " local maxX, maxY = 1, 1",
1743 " local minX, minY = 1, 1",
1744 " paintEncoded = clearAllRedundant(paintEncoded)",
1745 " local frame = paintEncoded[_frame]",
1746 " local scx, scy = cx+paint.scrollX, cy+paint.scrollY",
1747 " local output = {}",
1748 " for a = 1, #frame do",
1749 " maxX = math.max(maxX, frame[a].x)",
1750 " maxY = math.max(maxY, frame[a].y)",
1751 " minX = math.min(minX, frame[a].x)",
1752 " minY = math.min(minY, frame[a].y)",
1753 " end",
1754 "",
1755 " maxX = math.max(maxX, scx)",
1756 " maxY = math.max(maxY, scy)",
1757 " minX = math.min(minX, scx)",
1758 " minY = math.min(minY, scy)",
1759 "",
1760 " maxX = math.max(maxX, screenEdges[1])",
1761 " maxY = math.max(maxY, screenEdges[2])",
1762 "",
1763 " local doop = {}",
1764 " local touched = {}",
1765 " local check = {[scy] = {[scx] = true}}",
1766 " for y = minY, maxY do",
1767 " doop[y] = {}",
1768 " touched[y] = {}",
1769 " for x = minX, maxX do",
1770 " doop[y][x] = {",
1771 " c = \" \",",
1772 " b = 0,",
1773 " t = 0",
1774 " }",
1775 " touched[y][x] = false",
1776 " end",
1777 " end",
1778 " for a = 1, #frame do",
1779 " doop[frame[a].y][frame[a].x] = {",
1780 " c = frame[a].c,",
1781 " t = frame[a].t,",
1782 " b = frame[a].b",
1783 " }",
1784 " end",
1785 " local initDot = {",
1786 " c = doop[scy][scx].c,",
1787 " t = doop[scy][scx].t,",
1788 " b = doop[scy][scx].b",
1789 " }",
1790 " local chkpos = function(x, y, checkList)",
1791 " if (x < minX or x > maxX) or (y < minY or y > maxY) then",
1792 " return false",
1793 " else",
1794 " if (doop[y][x].b ~= initDot.b) or (doop[y][x].t ~= initDot.t) or (doop[y][x].c ~= initDot.c) then",
1795 " return false",
1796 " end",
1797 " if check[y] then",
1798 " if check[y][x] then",
1799 " return false",
1800 " end",
1801 " end",
1802 " if touched[y][x] then",
1803 " return false",
1804 " end",
1805 " return true",
1806 " end",
1807 " end",
1808 " local doBreak",
1809 " local step = 0",
1810 " local currentlyOnScreen",
1811 " while true do",
1812 " doBreak = true",
1813 " for chY, v in pairs(check) do",
1814 " for chX, isTrue in pairs(v) do",
1815 " currentlyOnScreen = (chX-paint.scrollX >= 1 and chX-paint.scrollX <= scr_x and chY-paint.scrollY >= 1 and chY-paint.scrollY <= scr_y)",
1816 " if isTrue and (not touched[chY][chX]) then",
1817 " step = step + 1",
1818 " if painconfig.doFillAnimation then",
1819 " if currentlyOnScreen then",
1820 " reRenderPAIN(true)",
1821 " end",
1822 " end",
1823 " if isDeleting then",
1824 " deleteDot(chX, chY)",
1825 " else",
1826 " frame[#frame+1] = {",
1827 " x = chX,",
1828 " y = chY,",
1829 " c = dot.c,",
1830 " t = dot.t,",
1831 " b = dot.b",
1832 " }",
1833 " end",
1834 " touched[chY][chX] = true",
1835 " -- check adjacent",
1836 " if chkpos(chX+1, chY) then",
1837 " check[chY][chX+1] = true",
1838 " doBreak = false",
1839 " end",
1840 " if chkpos(chX-1, chY) then",
1841 " check[chY][chX-1] = true",
1842 " doBreak = false",
1843 " end",
1844 " if chkpos(chX, chY+1) then",
1845 " check[chY+1] = check[chY+1] or {}",
1846 " check[chY+1][chX] = true",
1847 " doBreak = false",
1848 " end",
1849 " if chkpos(chX, chY-1) then",
1850 " check[chY-1] = check[chY-1] or {}",
1851 " check[chY-1][chX] = true",
1852 " doBreak = false",
1853 " end",
1854 " -- check diagonal",
1855 " if painconfig.doFillDiagonal then",
1856 " if chkpos(chX-1, chY-1) then",
1857 " check[chY-1] = check[chY-1] or {}",
1858 " check[chY-1][chX-1] = true",
1859 " doBreak = false",
1860 " end",
1861 " if chkpos(chX+1, chY-1) then",
1862 " check[chY-1] = check[chY-1] or {}",
1863 " check[chY-1][chX+1] = true",
1864 " doBreak = false",
1865 " end",
1866 " if chkpos(chX-1, chY+1) then",
1867 " check[chY+1] = check[chY+1] or {}",
1868 " check[chY+1][chX-1] = true",
1869 " doBreak = false",
1870 " end",
1871 " if chkpos(chX+1, chY+1) then",
1872 " check[chY+1] = check[chY+1] or {}",
1873 " check[chY+1][chX+1] = true",
1874 " doBreak = false",
1875 " end",
1876 " end",
1877 " if step % ((painconfig.doFillAnimation and currentlyOnScreen) and 4 or 1024) == 0 then -- tries to prevent crash",
1878 " sleep(0)",
1879 " end",
1880 " end",
1881 " end",
1882 " end",
1883 " if doBreak then",
1884 " break",
1885 " end",
1886 " end",
1887 " paintEncoded = clearAllRedundant(paintEncoded)",
1888 "end",
1889 "",
1890 "local boxCharSelector = function()",
1891 " local co = function(pos)",
1892 " if pos then",
1893 " term.setTextColor(colors.lime)",
1894 " term.setBackgroundColor(colors.green)",
1895 " else",
1896 " term.setTextColor(colors.lightGray)",
1897 " term.setBackgroundColor(colors.gray)",
1898 " end",
1899 " end",
1900 " local rend = function()",
1901 " term.setCursorPos(1,scr_y)",
1902 " term.setBackgroundColor(colors.lightGray)",
1903 " term.setTextColor(colors.black)",
1904 " term.clearLine()",
1905 " term.write(\"Press CTRL or 'N' when ready.\")",
1906 " term.setCursorPos(1,scr_y-3) co(boxchar.topLeft) write(\"Q\") co(boxchar.topRight) write(\"W\")",
1907 " term.setCursorPos(1,scr_y-2) co(boxchar.left) write(\"A\") co(boxchar.right) write(\"S\")",
1908 " term.setCursorPos(1,scr_y-1) co(boxchar.bottomLeft) write(\"Z\") co(boxchar.bottomRight) write(\"X\")",
1909 " end",
1910 " while true do",
1911 " rend()",
1912 " local evt = {os.pullEvent()}",
1913 " if evt[1] == \"key\" then",
1914 " local key = evt[2]",
1915 " if key == keys.leftCtrl or key == keys.rightCtrl or key == keys.n then",
1916 " break",
1917 " else",
1918 " if key == keys.q then boxchar.topLeft = not boxchar.topLeft end",
1919 " if key == keys.w then boxchar.topRight = not boxchar.topRight end",
1920 " if key == keys.a then boxchar.left = not boxchar.left end",
1921 " if key == keys.s then boxchar.right = not boxchar.right end",
1922 " if key == keys.z then boxchar.bottomLeft = not boxchar.bottomLeft end",
1923 " if key == keys.x then boxchar.bottomRight = not boxchar.bottomRight end",
1924 " end",
1925 " elseif evt[1] == \"mouse_click\" or evt[1] == \"mouse_drag\" then",
1926 " local button, mx, my = evt[2], evt[3], evt[4]",
1927 " if my >= scr_y-2 then",
1928 " if mx == 1 then",
1929 " if my == scr_y - 3 then boxchar.topLeft = not boxchar.topLeft end",
1930 " if my == scr_y - 2 then boxchar.left = not boxchar.left end",
1931 " if my == scr_y - 1 then boxchar.bottomLeft = not boxchar.bottomLeft end",
1932 " elseif mx == 2 then",
1933 " if my == scr_y - 3 then boxchar.topRight = not boxchar.topRight end",
1934 " if my == scr_y - 2 then boxchar.right = not boxchar.right end",
1935 " if my == scr_y - 1 then boxchar.bottomRight = not boxchar.bottomRight end",
1936 " elseif evt[1] == \"mouse_click\" then",
1937 " break",
1938 " end",
1939 " elseif evt[1] == \"mouse_click\" then",
1940 " break",
1941 " end",
1942 " end",
1943 " end",
1944 " if boxchar.topLeft and boxchar.topRight and boxchar.left and boxchar.right and boxchar.bottomLeft and boxchar.bottomRight then",
1945 " swapColors = false",
1946 " return \" \"",
1947 " else",
1948 " local output = getDrawingCharacter(boxchar.topLeft, boxchar.topRight, boxchar.left, boxchar.right, boxchar.bottomLeft, boxchar.bottomRight)",
1949 " swapColors = not output.inverted",
1950 " return output.char",
1951 " end",
1952 "end",
1953 "",
1954 "local specialCharSelector = function()",
1955 " local chars = {}",
1956 " local buff = 0",
1957 " for y = 1, 16 do",
1958 " for x = 1, 16 do",
1959 " chars[y] = chars[y] or {}",
1960 " chars[y][x] = string.char(buff)",
1961 " buff = buff + 1",
1962 " end",
1963 " end",
1964 " local sy = scr_y - (#chars + 1)",
1965 " local char = paint.c",
1966 " local render = function()",
1967 " for y = 1, #chars do",
1968 " for x = 1, #chars do",
1969 " term.setCursorPos(x,y+sy)",
1970 " if chars[y][x] == char then",
1971 " term.blit(chars[y][x], \"5\", \"d\")",
1972 " else",
1973 " term.blit(chars[y][x], \"8\", \"7\")",
1974 " end",
1975 " end",
1976 " end",
1977 " end",
1978 " local evt, butt, x, y",
1979 " render()",
1980 "",
1981 " term.setCursorPos(1,scr_y)",
1982 " term.setBackgroundColor(colors.lightGray)",
1983 " term.setTextColor(colors.black)",
1984 " term.clearLine()",
1985 " term.write(\"Press CTRL or 'N' when ready.\")",
1986 "",
1987 " while true do",
1988 " evt, butt, x, y = os.pullEvent()",
1989 " if (evt == \"mouse_click\" or evt == \"mouse_drag\") then",
1990 " if chars[y-sy] then",
1991 " if chars[y-sy][x] then",
1992 " if (chars[y-sy][x] ~= char) then",
1993 " char = chars[y-sy][x]",
1994 " render()",
1995 " end",
1996 " else",
1997 " return char",
1998 " end",
1999 " else",
2000 " return char",
2001 " end",
2002 " elseif evt == \"key\" then",
2003 " if (butt == keys.n) or (butt == keys.leftCtrl) then",
2004 " return char",
2005 " end",
2006 " end",
2007 " end",
2008 "end",
2009 "",
2010 "local dontDragThisTime = false",
2011 "local resetInputState = function()",
2012 " miceDown = {}",
2013 " keysDown = {}",
2014 " isDragging = false",
2015 " dontDragThisTime = true",
2016 "end",
2017 "",
2018 "local gotoCoords = function()",
2019 " local newX = bottomPrompt(\"Goto X:\")",
2020 " newX = tonumber(newX)",
2021 " local newY",
2022 " if newX then",
2023 " newY = bottomPrompt(\"Goto Y:\")",
2024 " newY = tonumber(newY)",
2025 " paint.scrollX = newX or paint.scrollX",
2026 " paint.scrollY = newY or paint.scrollY",
2027 " end",
2028 "end",
2029 "",
2030 "local renderAllPAIN = function()",
2031 " renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)",
2032 "end",
2033 "",
2034 "local checkIfNFP = function(str) --does not check table format, only string format",
2035 " local good = {",
2036 " ['0'] = true,",
2037 " ['1'] = true,",
2038 " ['2'] = true,",
2039 " ['3'] = true,",
2040 " ['4'] = true,",
2041 " ['5'] = true,",
2042 " ['6'] = true,",
2043 " ['7'] = true,",
2044 " ['8'] = true,",
2045 " ['9'] = true,",
2046 " a = true,",
2047 " b = true,",
2048 " c = true,",
2049 " d = true,",
2050 " e = true,",
2051 " f = true,",
2052 " [\" \"] = true,",
2053 " [\"\\n\"] = true",
2054 " }",
2055 " for a = 1, #str do",
2056 " if not good[str:sub(a,a):lower()] then",
2057 " return false",
2058 " end",
2059 " end",
2060 " return true",
2061 "end",
2062 "",
2063 "local selectRegion = function()",
2064 " local position = {}",
2065 " local mevt, id, x1, y1 = os.pullEvent(\"mouse_click\")",
2066 " local x2, y2, pos, redrawID",
2067 " local renderRectangle = true",
2068 " redrawID = os.startTimer(0.5)",
2069 " while true do",
2070 " mevt, id, x2, y2 = os.pullEvent()",
2071 " if mevt == \"mouse_up\" or mevt == \"mouse_drag\" or mevt == \"mouse_click\" then",
2072 " pos = {{",
2073 " x1 < x2 and x1 or x2,",
2074 " y1 < y2 and y1 or y2",
2075 " },{",
2076 " x1 < x2 and x2 or x1,",
2077 " y1 < y2 and y2 or y1",
2078 " }}",
2079 " end",
2080 " if mevt == \"mouse_up\" then",
2081 " break",
2082 " end",
2083 " if (mevt == \"mouse_drag\") or (mevt == \"timer\" and id == redrawID) then",
2084 " renderAllPAIN()",
2085 " if renderRectangle then",
2086 " term.setTextColor(rendback.t)",
2087 " term.setBackgroundColor(rendback.b)",
2088 " for y = pos[1][2], pos[2][2] do",
2089 " if y ~= scr_y then",
2090 " term.setCursorPos(pos[1][1], y)",
2091 " if (y == pos[1][2] or y == pos[2][2]) then",
2092 " term.write((\"#\"):rep(1 + pos[2][1] - pos[1][1]))",
2093 " else",
2094 " term.write(\"#\")",
2095 " term.setCursorPos(pos[2][1], y)",
2096 " term.write(\"#\")",
2097 " end",
2098 " end",
2099 " end",
2100 " end",
2101 " end",
2102 " if (mevt == \"timer\" and id == redrawID) then",
2103 " renderRectangle = not renderRectangle",
2104 " redrawID = os.startTimer(0.25)",
2105 " end",
2106 " end",
2107 " local output = {}",
2108 " pos[1][1] = pos[1][1] + paint.scrollX",
2109 " pos[2][1] = pos[2][1] + paint.scrollX",
2110 " pos[1][2] = pos[1][2] + paint.scrollY",
2111 " pos[2][2] = pos[2][2] + paint.scrollY",
2112 " for k,v in pairs(paintEncoded[frame]) do",
2113 " if v.x >= pos[1][1] and v.x <= pos[2][1] then",
2114 " if v.y >= pos[1][2] and v.y <= pos[2][2] then",
2115 " output[#output+1] = {",
2116 " x = v.x - pos[1][1],",
2117 " y = v.y - pos[1][2],",
2118 " t = v.t,",
2119 " c = v.c,",
2120 " b = v.b,",
2121 " m = v.m",
2122 " }",
2123 " end",
2124 " end",
2125 " end",
2126 " return output, pos[1][1], pos[1][2], pos[2][1], pos[2][2]",
2127 "end",
2128 "",
2129 "local openNewFile = function(fname, allowNonImageNFP)",
2130 " local file = fs.open(fname,\"r\")",
2131 " local contents = file.readAll()",
2132 " file.close()",
2133 " if type(tun(contents)) ~= \"table\" then",
2134 " term.setTextColor(colors.white)",
2135 " if contents:sub(1,3) == \"BLT\" then --thank you bomb bloke for this easy identifier",
2136 " if pMode ~= 1 then print(\"Importing from BLT...\") end",
2137 " return importFromBLT(fname), 3",
2138 " elseif contents:sub(1,3) == \"GIF\" then",
2139 " if pMode ~= 1 then print(\"Importing from GIF, this'll take a while...\") end",
2140 " return importFromGIF(fname,true), 5",
2141 " elseif contents:sub(1,4) == \"?!7\\2\" then",
2142 " if pMode ~= 1 then print(\"Importing from UCG...\") end",
2143 " return {importFromUCG(fname)}, 6",
2144 " elseif contents:find(string.char(30)) and contents:find(string.char(31)) then",
2145 " if pMode ~= 1 then print(\"Importing from NFT...\") end",
2146 " return {importFromNFT(contents)}, 2",
2147 " elseif (checkIfNFP(contents) or allowNonImageNFP) then",
2148 " print(\"Importing from NFP...\")",
2149 " return {importFromPaint(contents)}, 1",
2150 " else",
2151 " return false, \"That is not a valid image file.\"",
2152 " end",
2153 " else",
2154 " return tun(contents), 4",
2155 " end",
2156 "end",
2157 "",
2158 "local editCopy = function()",
2159 " local board = bottomPrompt(\"Copy to board: \")",
2160 " renderAllPAIN()",
2161 " renderBottomBar(\"Select region to copy.\")",
2162 " local selectedDots = selectRegion()",
2163 " theClipboard[board] = selectedDots",
2164 " barmsg = \"Copied to '\"..board..\"'\"",
2165 " doRender = true",
2166 " keysDown = {}",
2167 " miceDown = {}",
2168 "end",
2169 "local editCut = function()",
2170 " local board = bottomPrompt(\"Cut to board: \")",
2171 " renderAllPAIN()",
2172 " renderBottomBar(\"Select region to cut.\")",
2173 " local selectedDots, x1, y1, x2, y2 = selectRegion()",
2174 " theClipboard[board] = selectedDots",
2175 " local dot",
2176 " for i = #paintEncoded[frame], 1, -1 do",
2177 " dot = paintEncoded[frame][i]",
2178 " if dot.x >= x1 and dot.x <= x2 then",
2179 " if dot.y >= y1 and dot.y <= y2 then",
2180 " table.remove(paintEncoded[frame], i)",
2181 " end",
2182 " end",
2183 " end",
2184 " barmsg = \"Cut to '\"..board..\"'\"",
2185 " doRender = true",
2186 " saveToUndoBuffer()",
2187 " keysDown = {}",
2188 " miceDown = {}",
2189 "end",
2190 "",
2191 "local editPaste = function()",
2192 " local board = bottomPrompt(\"Paste from board: \")",
2193 " renderAllPAIN()",
2194 " renderBottomBar(\"Click to paste. (top left corner)\")",
2195 " if theClipboard[board] then",
2196 " local mevt",
2197 " repeat",
2198 " mevt = {os.pullEvent()}",
2199 " until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[1] == \"mouse_click\" and mevt[2] == 1 and (mevt[4] or scr_y) <= scr_y-1)",
2200 " for k,v in pairs(theClipboard[board]) do",
2201 " paintEncoded[frame][#paintEncoded[frame]+1] = {",
2202 " x = v.x + paint.scrollX + (mevt[3]),",
2203 " y = v.y + paint.scrollY + (mevt[4]),",
2204 " c = v.c,",
2205 " t = v.t,",
2206 " b = v.b,",
2207 " m = v.m",
2208 " }",
2209 " end",
2210 " paintEncoded[frame] = clearRedundant(paintEncoded[frame])",
2211 " barmsg = \"Pasted from '\"..board..\"'\"",
2212 " doRender = true",
2213 " saveToUndoBuffer()",
2214 " keysDown = {}",
2215 " miceDown = {}",
2216 " else",
2217 " barmsg = \"No such clipboard.\"",
2218 " doRender = true",
2219 " end",
2220 "end",
2221 "",
2222 "local displayMenu = function()",
2223 " menuOptions = {\"File\",\"Edit\",\"Window\",\"Set\",\"About\",\"Exit\"}",
2224 " local diss = \" \"..tableconcat(menuOptions,\" \")",
2225 " local cleary = scr_y-math.floor(#diss/scr_x)",
2226 "",
2227 " local fileSave = function()",
2228 " checkBadDots()",
2229 " local output = deepCopy(paintEncoded)",
2230 " if paint.doGray then",
2231 " output = convertToGrayscale(output)",
2232 " end",
2233 " doRender = true",
2234 " if not fileName then",
2235 " renderBottomBar(\"Save as: \")",
2236 " local fnguess = read()",
2237 " if fs.isReadOnly(fnguess) then",
2238 " barmsg = \"'\"..fnguess..\"' is read only.\"",
2239 " return false",
2240 " elseif fnguess:gsub(\" \",\"\") == \"\" then",
2241 " return false",
2242 " elseif fs.isDir(fnguess) then",
2243 " barmsg = \"'\"..fnguess..\"' is already a directory.\"",
2244 " return false",
2245 " elseif #fnguess > 255 then",
2246 " barmsg = \"Filename is too long.\"",
2247 " return false",
2248 " else",
2249 " fileName = fnguess",
2250 " end",
2251 " end",
2252 " saveFile(fileName,output)",
2253 " term.setCursorPos(9,scr_y)",
2254 " return fileName",
2255 " end",
2256 " local filePrint = function()",
2257 " local usedDots, dot = {}, {}",
2258 " for a = 1, #paintEncoded[frame] do",
2259 " dot = paintEncoded[frame][a]",
2260 " if dot.x > paint.scrollX and dot.x < (paint.scrollX + 25) and dot.y > paint.scrollX and dot.y < (paint.scrollY + 21) then",
2261 " if dot.c ~= \" \" then",
2262 " usedDots[dot.t] = usedDots[dot.t] or {}",
2263 " usedDots[dot.t][#usedDots[dot.t]+1] = {",
2264 " x = dot.x - paint.scrollX,",
2265 " y = dot.y - paint.scrollY,",
2266 " char = dot.c",
2267 " }",
2268 " end",
2269 " end",
2270 " end",
2271 " local dyes = {",
2272 " [1] = \"bonemeal\",",
2273 " [2] = \"orange dye\",",
2274 " [4] = \"magenta dye\",",
2275 " [8] = \"light blue dye\",",
2276 " [16] = \"dandelion yellow\",",
2277 " [32] = \"lime dye\",",
2278 " [64] = \"pink dye\",",
2279 " [128] = \"gray dye\",",
2280 " [256] = \"light gray dye\",",
2281 " [512] = \"cyan dye\",",
2282 " [1024] = \"purple dye\",",
2283 " [2048] = \"lapis lazuli\",",
2284 " [4096] = \"cocoa beans\",",
2285 " [8192] = \"cactus green\",",
2286 " [16384] = \"rose red\",",
2287 " [32768] = \"ink sac\",",
2288 " }",
2289 " local printer = peripheral.find(\"printer\")",
2290 " if not printer then",
2291 " barmsg = \"No printer found.\"",
2292 " return false",
2293 " end",
2294 " local page",
2295 " for color, dotList in pairs(usedDots) do",
2296 " term.setBackgroundColor(colors.black)",
2297 " term.setTextColor((color == colors.black) and colors.gray or color)",
2298 " term.clear()",
2299 " cwrite(\"Please insert \"..dyes[color]..\" into the printer.\", nil, math.floor(scr_y/2))",
2300 " term.setTextColor(colors.lightGray)",
2301 " cwrite(\"Then, press spacebar.\", nil, math.floor(scr_y/2) + 1)",
2302 " local evt",
2303 " sleep(0)",
2304 " repeat",
2305 " evt = {os.pullEvent(\"key\")}",
2306 " until evt[2] == keys.space",
2307 " page = page or printer.newPage()",
2308 " if not page then",
2309 " barmsg = \"Check ink/paper.\"",
2310 " return",
2311 " end",
2312 " for k,v in pairs(usedDots[color]) do",
2313 " printer.setCursorPos(v.x, v.y)",
2314 " printer.write(v.char)",
2315 " end",
2316 " end",
2317 " printer.endPage()",
2318 " barmsg = \"Printed.\"",
2319 " end",
2320 " local fileExport = function(menuX,getRightToIt,_fileName)",
2321 " local exportMode",
2322 " if not tonumber(getRightToIt) then",
2323 " exportMode = makeSubMenu(menuX or 8,scr_y-2,{\"Paint\",\"NFT\",\"BLT\",\"PAIN Native\",\"GIF\",\"UCG\"})",
2324 " else",
2325 " exportMode = getRightToIt",
2326 " end",
2327 " doRender = true",
2328 " if exportMode == false then return false end",
2329 " local pe, exportName, writeIndent, result",
2330 " if exportMode == 4 then",
2331 " local exNm = fileSave()",
2332 " if exNm then",
2333 " changedImage = false",
2334 " return exNm",
2335 " else",
2336 " return nil",
2337 " end",
2338 " else",
2339 " checkBadDots()",
2340 " if _fileName then",
2341 " exportName, writeIndent = _fileName, #_fileName",
2342 " else",
2343 " exportName, writeIndent = bottomPrompt(\"Export to: /\")",
2344 " end",
2345 " nfpoutput = \"\"",
2346 " if fs.combine(\"\",exportName) == \"\" then",
2347 " barmsg = \"Export cancelled.\"",
2348 " return",
2349 " end",
2350 " if fs.isReadOnly(exportName) then",
2351 " barmsg = \"That's read-only.\"",
2352 " return",
2353 " end",
2354 " if fs.exists(exportName) and (not _fileName) then",
2355 " local plea = (progname == fs.combine(\"\",exportName)) and \"Overwrite ORIGINAL file!?\" or \"Overwrite?\"",
2356 " result, _wIn = bottomPrompt(plea..\" (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
2357 " writeIndent = writeIndent + _wIn",
2358 " if result ~= \"y\" then return end",
2359 " end",
2360 " local output",
2361 " pe = deepCopy(paintEncoded)",
2362 " if paint.doGray then",
2363 " pe = convertToGrayscale(pe)",
2364 " end",
2365 " local doSerializeBLT = false",
2366 " end",
2367 " if exportMode == 1 then",
2368 " output = exportToPaint(pe[frame])",
2369 " if askToSerialize then",
2370 " result, _wIn = bottomPrompt(\"Save as serialized? (Y/N)\",_,\"yn\",{})",
2371 " writeIndent = writeIndent + _wIn",
2372 " else result, _wIn = \"n\", 0 end",
2373 " if result == \"y\" then",
2374 " output = textutils.serialize(NFPserializeImage(output)):gsub(\" \",\"\"):gsub(\"\\n\",\"\"):gsub(\",}\",\"}\")",
2375 " end",
2376 " elseif exportMode == 2 then",
2377 " output = exportToNFT(pe[frame])",
2378 " elseif exportMode == 3 then",
2379 " local doAllFrames, _wIn = bottomPrompt(\"Save all frames, or current? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl},writeIndent)",
2380 " writeIndent = writeIndent + _wIn",
2381 " if askToSerialize then",
2382 " doSerializeBLT = bottomPrompt(\"Save as serialized? (Y/N)\",_,\"yn\",{},writeIndent) == \"y\"",
2383 " end",
2384 " output = textutils.serialise(exportToBLT(pe,exportName,doAllFrames == \"y\",doSerializeBLT))",
2385 " elseif exportMode == 5 then",
2386 " getGIF()",
2387 " GIF.saveGIF(exportToGIF(pe),exportName)",
2388 " elseif exportMode == 6 then",
2389 " exportToUCG(exportName,pe[frame])",
2390 " end",
2391 " if ((exportMode ~= 3) and (exportMode ~= 4) and (exportMode ~= 5) and (exportMode ~= 6)) or doSerializeBLT then",
2392 " local file = fs.open(exportName,\"w\")",
2393 " file.write(output)",
2394 " file.close()",
2395 " end",
2396 " return exportName",
2397 " end",
2398 "",
2399 " local editClear = function(ignorePrompt)",
2400 " local outcum = ignorePrompt and \"y\" or bottomPrompt(\"Clear the frame? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
2401 " if outcum == \"y\" then",
2402 " paintEncoded[frame] = {}",
2403 " saveToUndoBuffer()",
2404 " barmsg = \"Cleared frame \"..frame..\".\"",
2405 " end",
2406 " doRender = true",
2407 " end",
2408 "",
2409 " local editDelFrame = function()",
2410 " local outcum = bottomPrompt(\"Thou art sure? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
2411 " doRender = true",
2412 " if outcum == \"y\" then",
2413 " if #paintEncoded == 1 then",
2414 " return editClear(true)",
2415 " end",
2416 " table.remove(paintEncoded,frame)",
2417 " barmsg = \"Deleted frame \"..frame..\".\"",
2418 " if paintEncoded[frame-1] then",
2419 " frame = frame - 1",
2420 " else",
2421 " frame = frame + 1",
2422 " end",
2423 " if #paintEncoded < frame then",
2424 " repeat",
2425 " frame = frame - 1",
2426 " until #paintEncoded >= frame",
2427 " end",
2428 " saveToUndoBuffer()",
2429 " end",
2430 " end",
2431 " local editCrop = function()",
2432 " local outcum = bottomPrompt(\"Crop all but visible? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
2433 " if outcum == \"y\" then",
2434 " local ppos = 1",
2435 " local deletedAmnt = 0",
2436 " for a = #paintEncoded[frame], 1, -1 do",
2437 " local x, y = paintEncoded[frame][a].x, paintEncoded[frame][a].y",
2438 " if (x <= paint.scrollX) or (x > paint.scrollX + scr_x) or (y <= paint.scrollY) or (y > paint.scrollY + scr_y) then",
2439 " table.remove(paintEncoded[frame],a)",
2440 " deletedAmnt = deletedAmnt + 1",
2441 " else",
2442 " ppos = ppos + 1",
2443 " end",
2444 " if ppos > #paintEncoded[frame] then break end",
2445 " end",
2446 " saveToUndoBuffer()",
2447 " barmsg = \"Cropped frame.\"",
2448 " end",
2449 " doRender = true",
2450 " end",
2451 " local editBoxCharSelector = function()",
2452 " paint.c = boxCharSelector()",
2453 " end",
2454 " local editSpecialCharSelector = function()",
2455 " paint.c = boxCharSelector()",
2456 " end",
2457 "",
2458 " local windowSetScrSize = function()",
2459 " local x,y",
2460 " x = bottomPrompt(\"Scr.X OR monitor name:\",{},nil,{keys.leftCtrl,keys.rightCtrl})",
2461 " if x == \"\" then",
2462 " return",
2463 " elseif x == \"pocket\" then",
2464 " screenEdges = {26,20}",
2465 " elseif x == \"turtle\" then",
2466 " screenEdges = {39,13}",
2467 " elseif x == \"computer\" then",
2468 " screenEdges = {51,19}",
2469 " elseif tonumber(x) then",
2470 " if tonumber(x) <= 0 then",
2471 " barmsg = \"Screen X must be greater than 0.\"",
2472 " return",
2473 " end",
2474 " screenEdges[1] = math.abs(tonumber(x))",
2475 " y = bottomPrompt(\"Scr.Y:\",{},nil,{keys.leftCtrl,keys.rightCtrl})",
2476 " if tonumber(y) then",
2477 " if tonumber(y) <= 0 then",
2478 " barmsg = \"Screen Y must be greater than 0.\"",
2479 " return",
2480 " end",
2481 " screenEdges[2] = math.abs(tonumber(y))",
2482 " end",
2483 " barmsg = \"Screen size changed.\"",
2484 " else",
2485 " local mon = peripheral.wrap(x)",
2486 " if not mon then",
2487 " barmsg = \"No such monitor.\"",
2488 " return",
2489 " else",
2490 " if peripheral.getType(x) ~= \"monitor\" then",
2491 " barmsg = \"That's not a monitor.\"",
2492 " return",
2493 " else",
2494 " screenEdges[1], screenEdges[2] = mon.getSize()",
2495 " barmsg = \"Screen size changed.\"",
2496 " return",
2497 " end",
2498 " end",
2499 " end",
2500 " end",
2501 " local aboutPAIN = function()",
2502 " local helpText = [[",
2503 "",
2504 " ",
2505 " ",
2506 " ",
2507 " ",
2508 " ",
2509 "",
2510 "Advanced Paint Program",
2511 " by LDDestroier",
2512 " or EldidiStroyrr",
2513 " if you please!",
2514 "",
2515 "PAIN is a multi-frame paint program with the intention of becoming a stable, well-used, and mondo-useful CC drawing utility.",
2516 "",
2517 "The main focus during development is to add more functions that you might see in MSPAINT such as lines or a proper fill tool (which I don't have, grr hiss boo), as well as to export/import to and from as many image formats as possible.",
2518 "",
2519 "My ultimate goal is to have PAIN be the default paint program for most every operating system on the forums. In order to do this, I'll need to make sure that PAIN is stable, easy to use, and can be easily limited by an OS to work with more menial tasks like making a single icon or what have you.",
2520 "]]",
2521 " guiHelp(helpText)",
2522 " end",
2523 " local aboutFileFormats = function()",
2524 " local helpText = [[",
2525 "Here's info on the file formats.",
2526 "",
2527 " \"NFP\":",
2528 "Used in rom/programs/paint, and the format for paintutils. It's a handy format, but the default rendering function is inefficient as hell, and it does not store text data, only background.",
2529 "Cannot save multiple frames.",
2530 "",
2531 " \"NFT\":",
2532 "Used in npaintpro and most everything else, it's my favorite of the file formats because it does what NFP does, but allows for text in the pictures. Useful for storing screenshots or small icons where an added level of detail is handy. Created by nitrogenfingers, thank him.",
2533 "Cannot save multiple frames.",
2534 "",
2535 " \"BLT\":",
2536 "Used exclusively with Bomb Bloke's BLittle API, and as such is handy with making pictures with block characters. Just keep in mind that those 2*3 grid squares in PAIN represent individual characters in BLT.",
2537 "BLT can save multiple frames!",
2538 "",
2539 " \"PAIN Native\":",
2540 "The basic, tabular, and wholly inefficient format that PAIN uses. Useful for doing math within the program, not so much for long term file storage. It stores text, but just use NFT if you don't need multiple frames.",
2541 "Obviously, this can save multiple frames.",
2542 "",
2543 " \"GIF\":",
2544 "The API was made by Bomb Bloke, huge thanks for that, but GIF is a universal file format used in real paint programs. Very useful for converting files on your computer to something like NFP, but doesn't store text. Be careful when opening up big GIF files, they can take a long time to load.",
2545 "Being GIF, this saves multiple frames!",
2546 "",
2547 " \"UCG\":",
2548 "Stands for Universal Compressed Graphics. This format was made by ardera, and uses Huffman Code and run-length encoding in order to reduce file sizes tremendously. However, it only saves backgrounds and not text data.",
2549 "Cannot save multiple frames.",
2550 "",
2551 "",
2552 "I recommend using NFT if you don't need multiple frames, NFP if you don't need text, UCG if the picture is really big, Native PAIN if you need both text and multiframe support, and GIF if you want to use something like MS Paint or Pinta or GIMP or whatever.",
2553 "]]",
2554 " guiHelp(helpText)",
2555 " end",
2556 " local menuPoses = {}",
2557 " local menuFunctions = {",
2558 " [1] = function() --File",
2559 " while true do",
2560 " --renderAllPAIN()",
2561 " local output, longestLen = makeSubMenu(1,cleary-1,{",
2562 " \"Save\",",
2563 " \"Save As\",",
2564 " \"Export\",",
2565 " \"Open\",",
2566 " ((peripheral.find(\"printer\")) and \"Print\" or nil)",
2567 " })",
2568 " doRender = true",
2569 " if output == 1 then -- Save",
2570 " local _fname = fileExport(_,defaultSaveFormat,fileName)",
2571 " if _fname then",
2572 " barmsg = \"Saved as '\".._fname..\"'\"",
2573 " lastPaintEncoded = deepCopy(paintEncoded)",
2574 " changedImage = false",
2575 " end",
2576 " break",
2577 " elseif output == 2 then -- Save As",
2578 " local oldfilename = fileName",
2579 " fileName = nil",
2580 " local res = fileExport(_,defaultSaveFormat)",
2581 " if not res then",
2582 " fileName = oldfilename",
2583 " end",
2584 " barmsg = \"Saved as '\"..fileName..\"'\"",
2585 " elseif output == 3 then --Export",
2586 " local res = fileExport(longestLen+1)",
2587 " if res then",
2588 " barmsg = \"Exported as '\"..res..\"'\"",
2589 " break",
2590 " end",
2591 " elseif output == 4 then -- Open",
2592 " renderBottomBar(\"Pick an image file.\")",
2593 " local newPath = lddfm.makeMenu(2, 2, scr_x-1, scr_y-2, fs.getDir(fileName or progname), false, false, false, true, false, nil, true)",
2594 " if newPath then",
2595 " local pen, form = openNewFile(newPath, painconfig.readNonImageAsNFP)",
2596 " if not pen then",
2597 " barmsg = form",
2598 " else",
2599 " fileName = newPath",
2600 " paintEncoded, lastPaintEncoded = pen, deepCopy(pen)",
2601 " defaultSaveFormat = form",
2602 " undoPos = 1",
2603 " undoBuffer = {deepCopy(paintEncoded)}",
2604 " barmsg = \"Opened '\" .. fs.getName(newPath) .. \"'\"",
2605 " paint.scrollX, paint.scrollY, paint.doGray = 1, 1, false",
2606 " doRender = true",
2607 " end",
2608 " end",
2609 " break",
2610 " elseif output == 5 then -- Print",
2611 " filePrint()",
2612 " break",
2613 " elseif output == false then",
2614 " return \"nobreak\"",
2615 " end",
2616 " reRenderPAIN(true)",
2617 " end",
2618 " end,",
2619 " [2] = function() --Edit",
2620 " local output = makeSubMenu(6,cleary-1,{",
2621 " \"Delete Frame\",",
2622 " \"Clear Frame\",",
2623 " \"Crop Frame\",",
2624 " \"Choose Box Character\",",
2625 " \"Choose Special Character\",",
2626 " \"BLittle Shrink\",",
2627 " \"Copy Region\",",
2628 " \"Cut Region\",",
2629 " \"Paste Region\"",
2630 " })",
2631 " doRender = true",
2632 " if output == 1 then",
2633 " editDelFrame()",
2634 " elseif output == 2 then",
2635 " editClear()",
2636 " elseif output == 3 then",
2637 " editCrop()",
2638 " elseif output == 4 then",
2639 " editBoxCharSelector()",
2640 " elseif output == 5 then",
2641 " editSpecialCharSelector()",
2642 " elseif output == 6 then",
2643 " local res = bottomPrompt(\"You sure? It's unreversable! (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
2644 " if res == \"y\" then",
2645 " getBlittle()",
2646 " local bltPE = blittle.shrink(NFPserializeImage(exportToPaint(paintEncoded[frame])))",
2647 " _G.SHRINKOUT = bltPE",
2648 " paintEncoded[frame] = {}",
2649 " for y = 1, bltPE.height do",
2650 " for x = 1, bltPE.width do",
2651 " paintEncoded[frame][#paintEncoded[frame]+1] = {",
2652 " c = bltPE[1][y]:sub(x,x),",
2653 " t = BTC(bltPE[2][y]:sub(x,x),true),",
2654 " b = BTC(bltPE[3][y]:sub(x,x),true),",
2655 " x = x,",
2656 " y = y,",
2657 " }",
2658 " end",
2659 " end",
2660 " saveToUndoBuffer()",
2661 " doRender = true",
2662 " barmsg = \"Shrunk image.\"",
2663 " end",
2664 " elseif output == 7 then",
2665 " editCopy()",
2666 " elseif output == 8 then",
2667 " editCut()",
2668 " elseif output == 9 then",
2669 " editPaste()",
2670 " elseif output == false then",
2671 " return \"nobreak\"",
2672 " end",
2673 " end,",
2674 " [3] = function() --Window",
2675 " local output = makeSubMenu(11,cleary-1,{",
2676 " \"Set Screen Size\",",
2677 " \"Set Scroll XY\",",
2678 " \"Set Grid Colors\"",
2679 " })",
2680 " doRender = true",
2681 " if output == 1 then",
2682 " windowSetScrSize()",
2683 " elseif output == 2 then",
2684 " gotoCoords()",
2685 " elseif output == 3 then",
2686 " rendback.b = paint.b",
2687 " rendback.t = paint.t",
2688 " doRender = true",
2689 " elseif output == false then",
2690 " return \"nobreak\"",
2691 " end",
2692 " end,",
2693 " [4] = function() --Set",
2694 " local output = makeSubMenu(17,cleary-1,{",
2695 " (painconfig.readNonImageAsNFP and \"(T)\" or \"(F)\") .. \" Load Non-images\",",
2696 " (painconfig.useFlattenGIF and \"(T)\" or \"(F)\") .. \" Flatten GIFs\",",
2697 " (painconfig.gridBleedThrough and \"(T)\" or \"(F)\") .. \" Always Render Grid\",",
2698 " (painconfig.doFillDiagonal and \"(T)\" or \"(F)\") .. \" Fill Diagonally\",",
2699 " (painconfig.doFillAnimation and \"(T)\" or \"(F)\") .. \" Do Fill Animation\",",
2700 " \"(\" .. painconfig.undoBufferSize .. \") Set Undo Buffer Size\",",
2701 " })",
2702 " if output == 1 then",
2703 " painconfig.readNonImageAsNFP = not painconfig.readNonImageAsNFP",
2704 " elseif output == 2 then",
2705 " painconfig.useFlattenGIF = not painconfig.useFlattenGIF",
2706 " elseif output == 3 then",
2707 " painconfig.gridBleedThrough = not painconfig.gridBleedThrough",
2708 " elseif output == 4 then",
2709 " painconfig.doFillDiagonal = not painconfig.doFillDiagonal",
2710 " elseif output == 5 then",
2711 " painconfig.doFillAnimation = not painconfig.doFillAnimation",
2712 " elseif output == 6 then",
2713 " local newUndoBufferSize = bottomPrompt(\"New undo buffer size: \")",
2714 " if tonumber(newUndoBufferSize) then",
2715 " painconfig.undoBufferSize = math.abs(tonumber(newUndoBufferSize))",
2716 " undoBuffer = {deepCopy(paintEncoded)}",
2717 " undoPos = 1",
2718 " else",
2719 " return",
2720 " end",
2721 " end",
2722 " saveConfig()",
2723 " end,",
2724 " [5] = function() --About",
2725 " local output = makeSubMenu(17,cleary-1,{",
2726 " \"PAIN\",",
2727 " \"File Formats\",",
2728 " \"Help!\"",
2729 " })",
2730 " doRender = true",
2731 " if output == 1 then",
2732 " aboutPAIN()",
2733 " elseif output == 2 then",
2734 " aboutFileFormats()",
2735 " elseif output == 3 then",
2736 " guiHelp()",
2737 " doRender = true",
2738 " end",
2739 " end,",
2740 " [6] = function() --Exit",
2741 " if changedImage then",
2742 " local outcum = bottomPrompt(\"Abandon unsaved work? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
2743 " sleep(0)",
2744 " if outcum == \"y\" then",
2745 " return \"exit\"",
2746 " else",
2747 " doRender = true",
2748 " return nil",
2749 " end",
2750 " else",
2751 " return \"exit\"",
2752 " end",
2753 " end,",
2754 " }",
2755 " local cursor = 1",
2756 " local redrawmenu = true",
2757 " local initial = os.time()",
2758 " local clickdelay = 0.003",
2759 "",
2760 " local redrawTheMenu = function()",
2761 " for a = cleary,scr_y do",
2762 " term.setCursorPos(1,a)",
2763 " term.setBackgroundColor(colors.lightGray)",
2764 " term.clearLine()",
2765 " end",
2766 " term.setCursorPos(2,cleary)",
2767 " for a = 1, #menuOptions do",
2768 " if a == cursor then",
2769 " term.setTextColor(colors.black)",
2770 " term.setBackgroundColor(colors.white)",
2771 " else",
2772 " term.setTextColor(colors.black)",
2773 " term.setBackgroundColor(colors.lightGray)",
2774 " end",
2775 " menuPoses[a] = {term.getCursorPos()}",
2776 " write(menuOptions[a])",
2777 " term.setBackgroundColor(colors.lightGray)",
2778 " if a ~= #menuOptions then",
2779 " write(\" \")",
2780 " end",
2781 " end",
2782 " redrawmenu = false",
2783 " end",
2784 "",
2785 " while true do",
2786 " if redrawmenu then",
2787 " redrawTheMenu()",
2788 " redrawmenu = false",
2789 " end",
2790 " local event,key,x,y = getEvents(\"key\",\"char\",\"mouse_click\",\"mouse_up\",\"mouse_drag\")",
2791 " if event == \"key\" then",
2792 " if key == keys.left then",
2793 " redrawmenu = true",
2794 " cursor = cursor - 1",
2795 " elseif key == keys.right then",
2796 " redrawmenu = true",
2797 " cursor = cursor + 1",
2798 " elseif key == keys.enter then",
2799 " redrawmenu = true",
2800 " local res = menuFunctions[cursor]()",
2801 " resetInputState()",
2802 " if res == \"exit\" then",
2803 " return \"exit\"",
2804 " elseif res == \"nobreak\" then",
2805 " reRenderPAIN(true)",
2806 " else",
2807 " return",
2808 " end",
2809 " elseif key == keys.leftCtrl or key == keys.rightCtrl then",
2810 " doRender = true",
2811 " return",
2812 " end",
2813 " elseif event == \"char\" then",
2814 " for a = 1, #menuOptions do",
2815 " if key:lower() == menuOptions[a]:sub(1,1):lower() and a ~= cursor then",
2816 " cursor = a",
2817 " redrawmenu = true",
2818 " break",
2819 " end",
2820 " end",
2821 " elseif event == \"mouse_click\" or event == \"mouse_up\" then",
2822 " if y < cleary then",
2823 " doRender = true",
2824 " resetInputState()",
2825 " return",
2826 " elseif key == 1 and initial+clickdelay < os.time() then --key? more like button",
2827 " for a = 1, #menuPoses do",
2828 " if y == menuPoses[a][2] then",
2829 " if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then",
2830 " cursor = a",
2831 " redrawTheMenu()",
2832 " local res = menuFunctions[a]()",
2833 " os.queueEvent(\"queue\")",
2834 " os.pullEvent(\"queue\")",
2835 " resetInputState()",
2836 " if res == \"exit\" then",
2837 " return \"exit\"",
2838 " else",
2839 " return",
2840 " end",
2841 " end",
2842 " end",
2843 " end",
2844 " end",
2845 " end",
2846 " if (initial+clickdelay < os.time()) and string.find(event,\"mouse\") then",
2847 " if key == 1 then --key? key? what key? all I see is button!",
2848 " for a = 1, #menuPoses do",
2849 " if y == menuPoses[a][2] then",
2850 " if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then",
2851 " cursor = a",
2852 " redrawmenu = true",
2853 " break",
2854 " end",
2855 " end",
2856 " end",
2857 " end",
2858 " end",
2859 " if cursor < 1 then",
2860 " cursor = #menuOptions",
2861 " elseif cursor > #menuOptions then",
2862 " cursor = 1",
2863 " end",
2864 " end",
2865 "end",
2866 "",
2867 "local lastMX,lastMY,isDragging",
2868 "",
2869 "local doNonEventDrivenMovement = function() --what a STUPID function name, dude",
2870 " local didMove",
2871 " while true do",
2872 " didMove = false",
2873 " if (not keysDown[keys.leftShift]) and (not isDragging) and (not keysDown[keys.tab]) then",
2874 " if keysDown[keys.right] then",
2875 " paint.scrollX = paint.scrollX + 1",
2876 " didMove = true",
2877 " elseif keysDown[keys.left] then",
2878 " paint.scrollX = paint.scrollX - 1",
2879 " didMove = true",
2880 " end",
2881 " if keysDown[keys.down] then",
2882 " paint.scrollY = paint.scrollY + 1",
2883 " didMove = true",
2884 " elseif keysDown[keys.up] then",
2885 " paint.scrollY = paint.scrollY - 1",
2886 " didMove = true",
2887 " end",
2888 " if didMove then",
2889 " if lastMX and lastMY then",
2890 " if miceDown[1] then",
2891 " os.queueEvent(\"mouse_click\",1,lastMX,lastMY)",
2892 " end",
2893 " if miceDown[2] then",
2894 " os.queueEvent(\"mouse_click\",2,lastMX,lastMY)",
2895 " end",
2896 " end",
2897 " doRender = true",
2898 " end",
2899 " end",
2900 " sleep(0)",
2901 " end",
2902 "end",
2903 "",
2904 "local linePoses = {}",
2905 "local dragPoses = {}",
2906 "",
2907 "local listAllMonitors = function()",
2908 " term.setBackgroundColor(colors.gray)",
2909 " term.setTextColor(colors.white)",
2910 " local periphs = peripheral.getNames()",
2911 " local mons = {}",
2912 " for a = 1, #periphs do",
2913 " if peripheral.getType(periphs[a]) == \"monitor\" then",
2914 " mons[#mons+1] = periphs[a]",
2915 " end",
2916 " end",
2917 " if #mons == 0 then",
2918 " mons[1] = \"No monitors found.\"",
2919 " end",
2920 " term.setCursorPos(3,1)",
2921 " term.clearLine()",
2922 " term.setTextColor(colors.yellow)",
2923 " term.write(\"All monitors:\")",
2924 " term.setTextColor(colors.white)",
2925 " for y = 1, #mons do",
2926 " term.setCursorPos(2,y+1)",
2927 " term.clearLine()",
2928 " term.write(mons[y])",
2929 " end",
2930 " sleep(0)",
2931 " getEvents(\"char\",\"mouse_click\")",
2932 " doRender = true",
2933 "end",
2934 "",
2935 "local getInput = function() --gotta catch them all",
2936 " local button, x, y, oldmx, oldmy, origx, origy",
2937 " local isDragging = false",
2938 " local proceed = false",
2939 " renderBar(barmsg)",
2940 " while true do",
2941 " doRender = false",
2942 " local oldx,oldy = paint.scrollX,paint.scrollY",
2943 " local evt = {getEvents(\"mouse_scroll\",\"mouse_click\", \"mouse_drag\",\"mouse_up\",\"key\",\"key_up\",true)}",
2944 " if (evt[1] == \"mouse_scroll\") and (not viewing) then",
2945 " local dir = evt[2]",
2946 " if dir == 1 then",
2947 " if keysDown[keys.leftShift] or keysDown[keys.rightShift] then",
2948 " paint.t = paint.t * 2",
2949 " if paint.t > 32768 then",
2950 " paint.t = 32768",
2951 " end",
2952 " else",
2953 " paint.b = paint.b * 2",
2954 " if paint.b > 32768 then",
2955 " paint.b = 32768",
2956 " end",
2957 " end",
2958 " else",
2959 " if keysDown[keys.leftShift] or keysDown[keys.rightShift] then",
2960 " paint.t = math.ceil(paint.t / 2)",
2961 " if paint.t < 1 then",
2962 " paint.t = 1",
2963 " end",
2964 " else",
2965 " paint.b = math.ceil(paint.b / 2)",
2966 " if paint.b < 1 then",
2967 " paint.b = 1",
2968 " end",
2969 " end",
2970 " end",
2971 " renderBar(barmsg)",
2972 " elseif ((evt[1] == \"mouse_click\") or (evt[1] == \"mouse_drag\")) and (not viewing) then",
2973 " if evt[1] == \"mouse_click\" then",
2974 " origx, origy = evt[3], evt[4]",
2975 " end",
2976 " oldmx,oldmy = x or evt[3], y or evt[4]",
2977 " lastMX,lastMY = evt[3],evt[4]",
2978 " button,x,y = evt[2],evt[3],evt[4]",
2979 " if renderBlittle then",
2980 " x = 2*x",
2981 " y = 3*y",
2982 " lastMX = 2*lastMX",
2983 " lastMY = 3*lastMY",
2984 " end",
2985 " linePoses = {{x=oldmx,y=oldmy},{x=x,y=y}}",
2986 " miceDown[button] = true",
2987 " if y <= scr_y-(renderBlittle and 0 or doRenderBar) then",
2988 " if (button == 3) then",
2989 " putDownText(x,y)",
2990 " miceDown = {}",
2991 " keysDown = {}",
2992 " doRender = true",
2993 " elseif button == 1 then",
2994 " if keysDown[keys.leftShift] and evt[1] == \"mouse_click\" then",
2995 " isDragging = true",
2996 " end",
2997 " if isDragging then",
2998 " if evt[1] == \"mouse_click\" or dontDragThisTime then",
2999 " dragPoses[1] = {x=x,y=y}",
3000 " end",
3001 " dragPoses[2] = {x=x,y=y}",
3002 " local points = getDotsInLine(dragPoses[1].x,dragPoses[1].y,dragPoses[2].x,dragPoses[2].y)",
3003 " renderAllPAIN()",
3004 " for a = 1, #points do",
3005 " term.setCursorPos(points[a].x, points[a].y)",
3006 " term.blit(paint.c, CTB(paint.t), CTB(paint.b))",
3007 " end",
3008 " elseif (not dontDragThisTime) then",
3009 " if evt[1] == \"mouse_drag\" then",
3010 " local points = getDotsInLine(linePoses[1].x,linePoses[1].y,linePoses[2].x,linePoses[2].y)",
3011 " for a = 1, #points do",
3012 " putDotDown({x=points[a].x, y=points[a].y})",
3013 " end",
3014 " else",
3015 " putDotDown({x=x, y=y})",
3016 " end",
3017 " changedImage = true",
3018 " doRender = true",
3019 " end",
3020 " dontDragThisTime = false",
3021 " elseif button == 2 and y <= scr_y-(renderBlittle and 0 or doRenderBar) then",
3022 " deleteDot(x+paint.scrollX,y+paint.scrollY)",
3023 " changedImage = true",
3024 " doRender = true",
3025 " end",
3026 " elseif origy >= scr_y-(renderBlittle and 0 or doRenderBar) then",
3027 " miceDown = {}",
3028 " keysDown = {}",
3029 " isDragging = false",
3030 " local res = displayMenu()",
3031 " if res == \"exit\" then break end",
3032 " doRender = true",
3033 " end",
3034 " elseif (evt[1] == \"mouse_up\") and (not viewing) and (not isCurrentlyFilling) then",
3035 " origx,origy = 0,0",
3036 " local button = evt[2]",
3037 " miceDown[button] = false",
3038 " oldmx,oldmy = nil,nil",
3039 " lastMX, lastMY = nil,nil",
3040 " if isDragging then",
3041 " local points = getDotsInLine(dragPoses[1].x,dragPoses[1].y,dragPoses[2].x,dragPoses[2].y)",
3042 " for a = 1, #points do",
3043 " putDotDown({x=points[a].x, y=points[a].y})",
3044 " end",
3045 " changedImage = true",
3046 " doRender = true",
3047 " end",
3048 " saveToUndoBuffer()",
3049 " isDragging = false",
3050 " elseif evt[1] == \"key\" then",
3051 " local key = evt[2]",
3052 " if (isDragging or not keysDown[keys.leftShift]) and (keysDown[keys.tab]) then",
3053 " if key == keys.right and (not keysDown[keys.right]) then",
3054 " paint.scrollX = paint.scrollX + 1",
3055 " doRender = true",
3056 " elseif key == keys.left and (not keysDown[keys.left]) then",
3057 " paint.scrollX = paint.scrollX - 1",
3058 " doRender = true",
3059 " end",
3060 " if key == keys.down and (not keysDown[keys.down]) then",
3061 " paint.scrollY = paint.scrollY + 1",
3062 " doRender = true",
3063 " elseif key == keys.up and (not keysDown[keys.up]) then",
3064 " paint.scrollY = paint.scrollY - 1",
3065 " doRender = true",
3066 " end",
3067 " end",
3068 " keysDown[key] = true",
3069 " if key == keys.space then",
3070 " if keysDown[keys.leftShift] then",
3071 " evenDrawGrid = not evenDrawGrid",
3072 " else",
3073 " doRenderBar = math.abs(doRenderBar-1)",
3074 " end",
3075 " doRender = true",
3076 " end",
3077 " if key == keys.b then",
3078 " local blTerm, oldTerm = getBlittle()",
3079 " renderBlittle = not renderBlittle",
3080 " isDragging = false",
3081 " term.setBackgroundColor(rendback.b)",
3082 " term.clear()",
3083 " if renderBlittle then",
3084 " term.redirect(blTerm)",
3085 " blTerm.setVisible(true)",
3086 " else",
3087 " term.redirect(oldTerm)",
3088 " blTerm.setVisible(false)",
3089 " end",
3090 " doRender = true",
3091 " scr_x, scr_y = term.current().getSize()",
3092 " end",
3093 " if keysDown[keys.leftAlt] then",
3094 " if (not renderBlittle) then",
3095 " if (key == keys.c) then",
3096 " editCopy()",
3097 " elseif (key == keys.x) then",
3098 " editCut()",
3099 " elseif (key == keys.v) then",
3100 " editPaste()",
3101 " end",
3102 " end",
3103 " else",
3104 " if (key == keys.c) and (not renderBlittle) then",
3105 " gotoCoords()",
3106 " resetInputState()",
3107 " doRender = true",
3108 " end",
3109 " end",
3110 " if (keysDown[keys.leftShift]) and (not isDragging) then",
3111 " if key == keys.left then",
3112 " paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],-1,0)",
3113 " saveToUndoBuffer()",
3114 " doRender = true",
3115 " changedImage = true",
3116 " elseif key == keys.right then",
3117 " paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],1,0)",
3118 " saveToUndoBuffer()",
3119 " doRender = true",
3120 " changedImage = true",
3121 " elseif key == keys.up then",
3122 " paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,-1)",
3123 " saveToUndoBuffer()",
3124 " doRender = true",
3125 " changedImage = true",
3126 " elseif key == keys.down then",
3127 " paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,1)",
3128 " saveToUndoBuffer()",
3129 " doRender = true",
3130 " changedImage = true",
3131 " end",
3132 " end",
3133 " if keysDown[keys.leftAlt] then",
3134 " if #paintEncoded > 1 then",
3135 " if key == keys.equals and paintEncoded[frame+1] then --basically plus",
3136 " local first = deepCopy(paintEncoded[frame])",
3137 " local next = deepCopy(paintEncoded[frame+1])",
3138 " paintEncoded[frame] = next",
3139 " paintEncoded[frame+1] = first",
3140 " frame = frame + 1",
3141 " barmsg = \"Swapped prev frame.\"",
3142 " doRender = true",
3143 " changedImage = true",
3144 " saveToUndoBuffer()",
3145 " end",
3146 " if key == keys.minus and paintEncoded[frame-1] then",
3147 " local first = deepCopy(paintEncoded[frame])",
3148 " local next = deepCopy(paintEncoded[frame-1])",
3149 " paintEncoded[frame] = next",
3150 " paintEncoded[frame-1] = first",
3151 " frame = frame - 1",
3152 " barmsg = \"Swapped next frame.\"",
3153 " doRender = true",
3154 " changedImage = true",
3155 " saveToUndoBuffer()",
3156 " end",
3157 " end",
3158 " elseif keysDown[keys.leftShift] then",
3159 " if #paintEncoded > 1 then",
3160 " if key == keys.equals and paintEncoded[frame+1] then --basically plus",
3161 " for a = 1, #paintEncoded[frame] do",
3162 " paintEncoded[frame+1][#paintEncoded[frame+1] + 1] = paintEncoded[frame][a]",
3163 " end",
3164 " table.remove(paintEncoded, frame)",
3165 " paintEncoded = clearAllRedundant(paintEncoded)",
3166 " barmsg = \"Merged next frame.\"",
3167 " doRender = true",
3168 " changedImage = true",
3169 " saveToUndoBuffer()",
3170 " end",
3171 " if key == keys.minus and paintEncoded[frame-1] then",
3172 " for a = 1, #paintEncoded[frame] do",
3173 " paintEncoded[frame-1][#paintEncoded[frame-1] + 1] = paintEncoded[frame][a]",
3174 " end",
3175 " table.remove(paintEncoded, frame)",
3176 " frame = frame - 1",
3177 " paintEncoded = clearAllRedundant(paintEncoded)",
3178 " barmsg = \"Merged previous frame.\"",
3179 " doRender = true",
3180 " changedImage = true",
3181 " saveToUndoBuffer()",
3182 " end",
3183 " end",
3184 " else",
3185 " if key == keys.equals then --basically 'plus'",
3186 " if renderBlittle then",
3187 " frame = frame + 1",
3188 " if frame > #paintEncoded then frame = 1 end",
3189 " else",
3190 " if not paintEncoded[frame+1] then",
3191 " paintEncoded[frame+1] = {}",
3192 " local sheet = paintEncoded[frame]",
3193 " if keysDown[keys.rightShift] then",
3194 " paintEncoded[frame+1] = deepCopy(sheet)",
3195 " end",
3196 " end",
3197 " frame = frame + 1",
3198 " end",
3199 " saveToUndoBuffer()",
3200 " doRender = true",
3201 " changedImage = true",
3202 " elseif key == keys.minus then",
3203 " if renderBlittle then",
3204 " frame = frame - 1",
3205 " if frame < 1 then frame = #paintEncoded end",
3206 " else",
3207 " if frame > 1 then",
3208 " frame = frame - 1",
3209 " end",
3210 " end",
3211 " saveToUndoBuffer()",
3212 " doRender = true",
3213 " changedImage = true",
3214 " end",
3215 " end",
3216 " if not renderBlittle then",
3217 " if key == keys.m then",
3218 " local incum = bottomPrompt(\"Set meta: \",metaHistory)",
3219 " paint.m = incum:gsub(\" \",\"\") ~= \"\" and incum or paint.m",
3220 " if paint.m ~= metaHistory[#metaHistory] then",
3221 " metaHistory[#metaHistory+1] = paint.m",
3222 " end",
3223 " doRender = true",
3224 " isDragging = false",
3225 " end",
3226 " if key == keys.f7 then",
3227 " bepimode = not bepimode",
3228 " doRender = true",
3229 " end",
3230 " if key == keys.t then",
3231 " renderBottomBar(\"Click to place text.\")",
3232 " local mevt",
3233 " repeat",
3234 " mevt = {os.pullEvent()}",
3235 " until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[1] == \"mouse_click\" and mevt[2] == 1 and (mevt[4] or scr_y) <= scr_y-(renderBlittle and 0 or doRenderBar))",
3236 " if not (mevt[1] == \"key\" and mevt[2] == keys.x) then",
3237 " local x,y = mevt[3],mevt[4]",
3238 " if renderBlittle then",
3239 " x = 2*x",
3240 " y = 3*y",
3241 " end",
3242 " putDownText(x,y)",
3243 " miceDown = {}",
3244 " keysDown = {}",
3245 " end",
3246 " doRender = true",
3247 " changedImage = true",
3248 " isDragging = false",
3249 " end",
3250 " if key == keys.f and not (keysDown[keys.leftShift] or keysDown[keys.rightShift]) and (not isCurrentlyFilling) then",
3251 " renderBottomBar(\"Click to fill area.\")",
3252 " local mevt",
3253 " repeat",
3254 " mevt = {os.pullEvent()}",
3255 " until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[1] == \"mouse_click\" and mevt[2] <= 2 and (mevt[4] or scr_y) <= scr_y-(renderBlittle and 0 or doRenderBar))",
3256 " if not (mevt[1] == \"key\" and mevt[2] == keys.x) then",
3257 " local x,y = mevt[3],mevt[4]",
3258 " if renderBlittle then",
3259 " x = 2*x",
3260 " y = 3*y",
3261 " end",
3262 " miceDown = {}",
3263 " keysDown = {}",
3264 " os.queueEvent(\"filltool_async\", frame, x, y, paint, mevt[2] == 2)",
3265 " end",
3266 " doRender = true",
3267 " changedImage = true",
3268 " isDragging = false",
3269 " end",
3270 " if key == keys.p then",
3271 " renderBottomBar(\"Pick color with cursor:\")",
3272 " paintEncoded = clearAllRedundant(paintEncoded)",
3273 " local mevt",
3274 " repeat",
3275 " mevt = {os.pullEvent()}",
3276 " until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[2] == 1 and mevt[4] <= scr_y)",
3277 " if not (mevt[1] == \"key\" and mevt[2] == keys.x) then",
3278 " local x, y = mevt[3]+paint.scrollX, mevt[4]+paint.scrollY",
3279 " if renderBlittle then",
3280 " x = 2*x",
3281 " y = 3*y",
3282 " end",
3283 " local p",
3284 " for a = 1, #paintEncoded[frame] do",
3285 " p = paintEncoded[frame][a]",
3286 " if (p.x == x) and (p.y == y) then",
3287 " paint.t = p.t or paint.t",
3288 " paint.b = p.b or paint.b",
3289 " paint.c = p.c or paint.c",
3290 " paint.m = p.m or paint.m",
3291 " miceDown = {}",
3292 " keysDown = {}",
3293 " doRender = true",
3294 " isDragging = false",
3295 " break",
3296 " end",
3297 " end",
3298 " resetInputState()",
3299 " end",
3300 " doRender = true",
3301 " isDragging = false",
3302 " end",
3303 " if (key == keys.leftCtrl or key == keys.rightCtrl) then",
3304 " keysDown = {[207] = keysDown[207]}",
3305 " isDragging = false",
3306 " local res = displayMenu()",
3307 " paintEncoded = clearAllRedundant(paintEncoded)",
3308 " if res == \"exit\" then break end",
3309 " doRender = true",
3310 " end",
3311 " end",
3312 " if (key == keys.f and keysDown[keys.leftShift]) then",
3313 " local deredots = {}",
3314 " changedImage = true",
3315 " for a = 1, #paintEncoded[frame] do",
3316 " local dot = paintEncoded[frame][a]",
3317 " if dot.x-paint.scrollX > 0 and dot.x-paint.scrollX <= scr_x then",
3318 " if dot.y-paint.scrollY > 0 and dot.y-paint.scrollY <= scr_y then",
3319 " deredots[#deredots+1] = {dot.x-paint.scrollX, dot.y-paint.scrollY}",
3320 " end",
3321 " end",
3322 " end",
3323 " for y = 1, scr_y do",
3324 " for x = 1, scr_x do",
3325 " local good = true",
3326 " for a = 1, #deredots do",
3327 " if (deredots[a][1] == x) and (deredots[a][2] == y) then",
3328 " good = bad",
3329 " break",
3330 " end",
3331 " end",
3332 " if good then",
3333 " putDotDown({x=x, y=y})",
3334 " end",
3335 " end",
3336 " end",
3337 " saveToUndoBuffer()",
3338 " doRender = true",
3339 " end",
3340 " if key == keys.g then",
3341 " paint.doGray = not paint.doGray",
3342 " changedImage = true",
3343 " saveToUndoBuffer()",
3344 " doRender = true",
3345 " end",
3346 " if key == keys.a then",
3347 " paint.scrollX = 0",
3348 " paint.scrollY = 0",
3349 " doRender = true",
3350 " end",
3351 " if key == keys.n then",
3352 " if keysDown[keys.leftShift] then",
3353 " paint.c = specialCharSelector()",
3354 " else",
3355 " paint.c = boxCharSelector()",
3356 " end",
3357 " resetInputState()",
3358 " doRender = true",
3359 " end",
3360 " if key == keys.f1 then",
3361 " guiHelp()",
3362 " resetInputState()",
3363 " isDragging = false",
3364 " end",
3365 " if key == keys.f3 then",
3366 " listAllMonitors()",
3367 " resetInputState()",
3368 " isDragging = false",
3369 " end",
3370 " if key == keys.leftBracket then",
3371 " os.queueEvent(\"mouse_scroll\",2,1,1)",
3372 " elseif key == keys.rightBracket then",
3373 " os.queueEvent(\"mouse_scroll\",1,1,1)",
3374 " end",
3375 " if key == keys.z then",
3376 " if keysDown[keys.leftAlt] and undoPos < #undoBuffer then",
3377 " doRedo()",
3378 " barmsg = \"Redood.\"",
3379 " doRender = true",
3380 " elseif undoPos > 1 then",
3381 " doUndo()",
3382 " barmsg = \"Undood.\"",
3383 " doRender = true",
3384 " end",
3385 " end",
3386 " elseif evt[1] == \"key_up\" then",
3387 " local key = evt[2]",
3388 " keysDown[key] = false",
3389 " end",
3390 " if (oldx~=paint.scrollX) or (oldy~=paint.scrollY) then",
3391 " doRender = true",
3392 " end",
3393 " if doRender then",
3394 " renderAllPAIN()",
3395 " doRender = false",
3396 " end",
3397 " end",
3398 "end",
3399 "",
3400 "runPainEditor = function(...) --needs to be cleaned up",
3401 " local tArg = table.pack(...)",
3402 " if not (tArg[1] == \"-n\" or (not tArg[1])) then",
3403 " fileName = shell.resolve(tostring(tArg[1]))",
3404 " end",
3405 "",
3406 " if not fileName then",
3407 " paintEncoded = {{}}",
3408 " elseif not fs.exists(fileName) then",
3409 " local ex = fileName:sub(-4):lower()",
3410 " if ex == \".nfp\" then",
3411 " defaultSaveFormat = 1",
3412 " elseif ex == \".nft\" then",
3413 " defaultSaveFormat = 2",
3414 " elseif ex == \".blt\" then",
3415 " defaultSaveFormat = 3",
3416 " elseif ex == \".gif\" then",
3417 " defaultSaveFormat = 5",
3418 " elseif ex == \".ucg\" then",
3419 " defaultSaveFormat = 6",
3420 " else",
3421 " defaultSaveFormat = 4",
3422 " end",
3423 " paintEncoded = {{}}",
3424 " elseif fs.isDir(fileName) then",
3425 " if math.random(1,32) == 1 then",
3426 " write(\"Oh\") sleep(0.2)",
3427 " write(\" My\") sleep(0.2)",
3428 " print(\" God\") sleep(0.3)",
3429 " write(\"That is a\") sleep(0.1) term.setTextColor(colors.red)",
3430 " write(\" FLIPPING\") sleep(0.4)",
3431 " print(\" FOLDER.\") sleep(0.2) term.setTextColor(colors.white)",
3432 " print(\"You crazy person.\") sleep(0.2)",
3433 " else",
3434 " print(\"That's a folder.\")",
3435 " end",
3436 " return",
3437 " else",
3438 " paintEncoded, defaultSaveFormat = openNewFile(fileName, readNonImageAsNFP)",
3439 " if not paintEncoded then",
3440 " return print(defaultSaveFormat)",
3441 " end",
3442 " end",
3443 "",
3444 " local asyncFillTool = function()",
3445 " local event, frameNo, x, y, dot",
3446 " isCurrentlyFilling = false",
3447 " while true do",
3448 " event, frameNo, x, y, dot, isDeleting = os.pullEvent(\"filltool_async\")",
3449 " isCurrentlyFilling = true",
3450 " renderBottomBar(\"Filling area...\")",
3451 " fillTool(frameNo, x, y, dot, isDeleting)",
3452 " saveToUndoBuffer()",
3453 " isCurrentlyFilling = false",
3454 " reRenderPAIN(doRenderBar == 0)",
3455 " end",
3456 " end",
3457 "",
3458 " if not paintEncoded[frame] then paintEncoded = {paintEncoded} end",
3459 " if pMode == 1 then",
3460 " doRenderBar = 0",
3461 " renderPAIN(paintEncoded[tonumber(tArg[5]) or 1],-(tonumber(tArg[3]) or 0),-(tonumber(tArg[4]) or 0)) -- 'pain filename view X Y frame'",
3462 " sleep(0)",
3463 " return",
3464 " else",
3465 " renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)",
3466 " end",
3467 " lastPaintEncoded = deepCopy(paintEncoded)",
3468 " undoBuffer = {deepCopy(paintEncoded)}",
3469 " parallel.waitForAny(getInput, doNonEventDrivenMovement, asyncFillTool)",
3470 "",
3471 " term.setCursorPos(1,scr_y)",
3472 " term.setBackgroundColor(colors.black)",
3473 " term.clearLine()",
3474 "end",
3475 "",
3476 "if not shell then error(\"shell API is required, sorry\") end",
3477 "",
3478 "runPainEditor(...)",
3479 },
3480 [ "/fakechat.lua" ] = {
3481 "-- ...use with responsibility.",
3482 "--",
3483 "-- Get with",
3484 "-- pastebin get n3K9Nt3D fakechat",
3485 "-- std PB n3K9Nt3D fakechat",
3486 "",
3487 "local names = { --Add names to quickly switch between using PageUP and PageDOWN",
3488 " {",
3489 " name = \"&o&6Jesus\",",
3490 " prefix = \"<\",",
3491 " suffix = \"> \",",
3492 " },",
3493 " {",
3494 " name = \"&dServer\",",
3495 " prefix = \"&d[\",",
3496 " suffix = \"&d] \",",
3497 " msgprefix = \"&d\",",
3498 " realname = \"But nobody\"",
3499 " },",
3500 " {",
3501 " name = \"&eBagel&6Bot\",",
3502 " prefix = \"<\",",
3503 " suffix = \"> \",",
3504 " },",
3505 " {",
3506 " name = \"Lr_\",",
3507 " prefix = \"<\",",
3508 " suffix = \"> \",",
3509 " },",
3510 " {",
3511 " name = \"dan200\",",
3512 " prefix = \"<\",",
3513 " suffix = \"> \",",
3514 " },",
3515 "}",
3516 "",
3517 "local sHistories = {}",
3518 "",
3519 "local cname = 1",
3520 "",
3521 "local tArg = {...}",
3522 "",
3523 "local channel = 1251 --default 1251",
3524 "",
3525 "local sHistory = {}",
3526 "local scr_x, scr_y = term.getSize()",
3527 "local modems",
3528 "local setModems = function()",
3529 " modems = {peripheral.find(\"modem\")}",
3530 " for a = 1, #modems do",
3531 " if modems[a].isWireless() then",
3532 " modem = modems[a]",
3533 " modem.open(channel)",
3534 " return",
3535 " end",
3536 " end",
3537 " modem = nil",
3538 "end",
3539 "",
3540 "setModems()",
3541 "if (not commands) and (not modem) then",
3542 " return printError(\"You need a modem! Or a command computer!\")",
3543 "end",
3544 "if commands then isServer = true else isServer = false end",
3545 "",
3546 "if (not commands) and (not modem) then",
3547 " error(\"This requires a command computer.\")",
3548 "end",
3549 "",
3550 "local prefix = \"\"",
3551 "local suffix = \"\"",
3552 "",
3553 "local dnb = function(phunk, ...)",
3554 " local t,b = term.getTextColor(), term.getBackgroundColor()",
3555 " local x,y = term.getCursorPos()",
3556 " local output = {phunk(...)}",
3557 " term.setCursorPos(x,y)",
3558 " term.setTextColor(t)",
3559 " term.setBackgroundColor(b)",
3560 " return unpack(output)",
3561 "end",
3562 "",
3563 "local prevnames = {}",
3564 "",
3565 "local colnames = {",
3566 " [\"0\"] = \"black\",",
3567 " [\"1\"] = \"dark_blue\",",
3568 " [\"2\"] = \"dark_green\",",
3569 " [\"3\"] = \"dark_aqua\",",
3570 " [\"4\"] = \"dark_red\",",
3571 " [\"5\"] = \"dark_purple\",",
3572 " [\"6\"] = \"gold\",",
3573 " [\"7\"] = \"gray\",",
3574 " [\"8\"] = \"dark_gray\",",
3575 " [\"9\"] = \"blue\",",
3576 " [\"a\"] = \"green\",",
3577 " [\"b\"] = \"aqua\",",
3578 " [\"c\"] = \"red\",",
3579 " [\"d\"] = \"light_purple\",",
3580 " [\"e\"] = \"yellow\",",
3581 " [\"f\"] = \"white\",",
3582 "}",
3583 "",
3584 "local colors_names = { --for use with colors api, you see",
3585 " [\"0\"] = colors.black,",
3586 " [\"1\"] = colors.blue,",
3587 " [\"2\"] = colors.green,",
3588 " [\"3\"] = colors.cyan,",
3589 " [\"4\"] = colors.red,",
3590 " [\"5\"] = colors.purple,",
3591 " [\"6\"] = colors.orange,",
3592 " [\"7\"] = colors.lightGray,",
3593 " [\"8\"] = colors.gray,",
3594 " [\"9\"] = colors.blue, --they don't translate perfectly, okay??",
3595 " [\"a\"] = colors.lime,",
3596 " [\"b\"] = colors.lightBlue,",
3597 " [\"c\"] = colors.red,",
3598 " [\"d\"] = colors.magenta,",
3599 " [\"e\"] = colors.yellow,",
3600 " [\"f\"] = colors.white,",
3601 "}",
3602 "local codeNames = { --just for checking",
3603 " [\"k\"] = \"obfuscate\",",
3604 " [\"o\"] = \"italic\",",
3605 " [\"l\"] = \"bold\",",
3606 " [\"m\"] = \"strikethrough\",",
3607 " [\"n\"] = \"underline\",",
3608 " [\"r\"] = \"reset\",",
3609 "}",
3610 "",
3611 "local filterColors = function(str,doprint)",
3612 " local p = 1",
3613 " local output = \"\"",
3614 " local code = \"&\"",
3615 " local col = \"f\"",
3616 " local prevT,prevB = term.getTextColor(), term.getBackgroundColor()",
3617 " while p <= #str do",
3618 " if str:sub(p,p) == code then",
3619 " if colors_names[str:sub(p+1,p+1)] then",
3620 " col = str:sub(p+1,p+1)",
3621 " p = p + 1",
3622 " elseif codeNames[str:sub(p+1,p+1)] then",
3623 " if str:sub(p+1,p+1) == \"r\" then",
3624 " col = \"f\"",
3625 " end",
3626 " p = p + 1",
3627 " else",
3628 " if doprint then",
3629 " if term.isColor() then",
3630 " term.setTextColor(colors_names[col])",
3631 " end",
3632 " write(str:sub(p,p))",
3633 " end",
3634 " end",
3635 " p = p + 1",
3636 " else",
3637 " output = output..str:sub(p,p)",
3638 " if doprint then",
3639 " if term.isColor() then",
3640 " term.setTextColor(colors_names[col])",
3641 " end",
3642 " write(str:sub(p,p))",
3643 " end",
3644 " p = p + 1",
3645 " end",
3646 " end",
3647 " term.setTextColor(prevT)",
3648 " term.setBackgroundColor(prevB)",
3649 " return output",
3650 "end",
3651 "",
3652 "local renderReadBar = function(doReturn)",
3653 " local cx,cy = term.getCursorPos()",
3654 " local cb,ct = term.getBackgroundColor(), term.getTextColor()",
3655 " term.setCursorPos(1,scr_y)",
3656 " term.setBackgroundColor(colors.black)",
3657 " term.clearLine()",
3658 " filterColors(prefix..\"&r\"..names[cname].prefix..\"&r\"..names[cname].name..\"&r\"..names[cname].suffix..\"&r\"..suffix,true)",
3659 " term.setCursorPos(1,scr_y-1)",
3660 " if not doReturn then",
3661 " term.setBackgroundColor(colors.gray)",
3662 " term.clearLine()",
3663 " term.setTextColor(colors.white)",
3664 " else",
3665 " term.setCursorPos(cx,cy)",
3666 " term.setBackgroundColor(cb)",
3667 " term.setTextColor(ct)",
3668 " end",
3669 "end",
3670 "",
3671 "local colorFormat = function(str)",
3672 " local color = \"f\"",
3673 " local obfuscated = false",
3674 " local bold = false",
3675 " local strikethrough = false",
3676 " local underline = false",
3677 " local italic = false",
3678 " ",
3679 " local code = \"&\" --ONE CHARACTER",
3680 " local pos = 1",
3681 " local opos = 1",
3682 " local output = {}",
3683 " ",
3684 " while pos <= #str do",
3685 " output[opos] = {}",
3686 " if str:sub(pos,pos) == code and pos < #str then",
3687 " local changed = false",
3688 " if colnames[str:sub(pos+1,pos+1)] then",
3689 " color = str:sub(pos+1,pos+1)",
3690 " changed = true",
3691 " else",
3692 " if str:sub(pos+1,pos+1) == \"r\" then",
3693 " color = \"f\"",
3694 " obfuscated = false",
3695 " bold = false",
3696 " strikethrough = false",
3697 " underline = false",
3698 " italic = false",
3699 " changed = true",
3700 " end",
3701 " if str:sub(pos+1,pos+1) == \"k\" then",
3702 " obfuscated = true",
3703 " changed = true",
3704 " end",
3705 " if str:sub(pos+1,pos+1) == \"l\" then",
3706 " bold = true",
3707 " changed = true",
3708 " end",
3709 " if str:sub(pos+1,pos+1) == \"m\" then",
3710 " strikethrough = true",
3711 " changed = true",
3712 " end",
3713 " if str:sub(pos+1,pos+1) == \"n\" then",
3714 " underline = true",
3715 " changed = true",
3716 " end",
3717 " if str:sub(pos+1,pos+1) == \"o\" then",
3718 " italic = true",
3719 " changed = true",
3720 " end",
3721 " end",
3722 " if changed then",
3723 " output[opos].text = \"\"",
3724 " pos = pos + 2",
3725 " else",
3726 " output[opos].text = str:sub(pos,pos)",
3727 " pos = pos + 1",
3728 " end",
3729 " else",
3730 " output[opos].text = str:sub(pos,pos)",
3731 " pos = pos + 1",
3732 " end",
3733 " output[opos].color = colnames[color]",
3734 " output[opos].obfuscated = obfuscated",
3735 " output[opos].bold = bold",
3736 " output[opos].strikethrough = strikethrough",
3737 " output[opos].underline = underline",
3738 " output[opos].italic = italic",
3739 " opos = opos + 1",
3740 " end",
3741 " return textutils.serialiseJSON(output)",
3742 "end",
3743 "",
3744 "local players = { --Add playernames here if you want to filter who receives messages",
3745 " \"dan200\",",
3746 " \"EldidiStroyrr\",",
3747 "}",
3748 "",
3749 "local doFilter = false --If true, filters according to 'players' table",
3750 "",
3751 "local send = function(name,msg,np,ns,realname,doprint)",
3752 " local compiled --compiled message, not compiled program",
3753 " local filtmsg = filterColors(msg)",
3754 " if filtmsg:sub(1,3) == \"___\" then --should this be a client option? hmm...",
3755 " if filtmsg == \"___join\" then",
3756 " compiled = \"&e\"..filterColors(realname)..\" joined the game.\"",
3757 " elseif filtmsg == \"___notjoin\" then",
3758 " compiled = \"&e\"..filterColors(realname)..\" hasn't joined the game.\"",
3759 " elseif filtmsg == \"___leave\" then",
3760 " compiled = \"&e\"..filterColors(realname)..\" left the game.\"",
3761 " elseif filtmsg == \"___notleave\" then",
3762 " compiled = \"&e\"..filterColors(realname)..\" hasn't left the game.\"",
3763 " elseif filtmsg:sub(1,8) == \"___medal\" then",
3764 " compiled = realname..\"&r has made the achievement &a[\"..msg:sub(10)..\"&a]\"",
3765 " else",
3766 " compiled = msg:sub(4)",
3767 " end",
3768 " else",
3769 " compiled = prefix..\"&r\"..np..\"&r\"..name..\"&r\"..ns..\"&r\"..suffix..\"&r\"..msg",
3770 " end",
3771 " compiled = colorFormat(compiled)",
3772 " if doFilter then",
3773 " for a = 1, #players do",
3774 " commands.tellraw(players[a],compiled)",
3775 " end",
3776 " else",
3777 " commands.tellraw(\"@a\",compiled)",
3778 " end",
3779 "end",
3780 "",
3781 "local netsend = function(n,m,p,s,mp,rn) --name, message, prefix, suffix",
3782 " local data = {",
3783 " name = n,",
3784 " realname = rn or n,",
3785 " msg = mp..m,",
3786 " prefix = p or \"<\",",
3787 " suffix = s or \"> \",",
3788 " }",
3789 " if modem then modem.transmit(channel,channel,data) end",
3790 "end",
3791 "",
3792 "term.setBackgroundColor(colors.black)",
3793 "term.clear()",
3794 "term.setCursorPos(1,1)",
3795 "local name",
3796 "if tArg[1] then",
3797 " name = tArg[1]",
3798 " if name:gsub(\" \",\"\") ~= \"\" and prevnames[#prevnames] ~= name then",
3799 " table.insert(prevnames,name)",
3800 " end",
3801 "else",
3802 " print(\"Enter a name:\")",
3803 " write(\">\")",
3804 " dnb(function() write(\"\\n\\nUse PageUP and PageDOWN to switch names.\\nDo '/exit' to exit.\\nDo '___join' or '___leave' to simulate doing either.\\nPrefix any other message with '___' to do raw chat.\\n\\nUse responsibly\") if term.isColor() then print(\".\") else print(\", and it'd be preferable to use a golden computer. Not required, but...\") end end)",
3805 " name = read(nil,prevnames)",
3806 " if name:gsub(\" \",\"\") ~= \"\" and prevnames[#prevnames] ~= name then",
3807 " table.insert(prevnames,name)",
3808 " end",
3809 "end",
3810 "if name:gsub(\" \",\"\") == \"\" then name = \"Scabby cunt\" end --enter in a fucking name",
3811 "table.insert(names,1,{",
3812 " name = name,",
3813 " prefix = \"<\",",
3814 " suffix = \"> \",",
3815 " realname = name",
3816 "})",
3817 "",
3818 "local insend = function(n,m,p,s,mp,rn) --name, message, prefix, suffix. Sends a message inwards to simulate receiving a message from a client",
3819 " local data = {",
3820 " name = n,",
3821 " realname = rn or n,",
3822 " msg = mp..m,",
3823 " prefix = p or \"<\",",
3824 " suffix = s or \"> \",",
3825 " }",
3826 " os.queueEvent(\"modem_message\",\"top\",channel,channel,data,0)",
3827 "end",
3828 "",
3829 "local client = function() --this is where you enter in your awesome messages! it also happens to be where *you* enter in your shitty messages",
3830 " while true do",
3831 " term.setBackgroundColor(colors.black) --dats rasist",
3832 " term.clear()",
3833 " renderReadBar()",
3834 " write(\">\")",
3835 " local msg = read(nil,sHistories[cname] or {\"I like to eat pubes I find in urinals.\",\"One of my hobbies is to kick small dogs and see how far they go.\",\"Have you reddit\",\"My child-sized skin suit it starting to smell.\"})",
3836 " if msg:gsub(\" \",\"\") == \"/exit\" then",
3837 " return",
3838 " end",
3839 " if msg:gsub(\" \",\"\") ~= \"\" then",
3840 " if not sHistories[cname] then",
3841 " sHistories[cname] = {msg}",
3842 " else",
3843 " if sHistories[cname][#sHistories[cname]] ~= msg then",
3844 " sHistories[cname][#sHistories[cname]+1] = msg",
3845 " end",
3846 " end",
3847 " end",
3848 " if isServer then --if you are a command computer, fuck that netsend() function!!! that's for pussies!!",
3849 " if msg:gsub(\" \",\"\") ~= \"\" then",
3850 " local sdata = {",
3851 " names[cname].name,",
3852 " msg,",
3853 " prefix..names[cname].prefix or \"<\",",
3854 " suffix..names[cname].suffix or \"> \",",
3855 " names[cname].msgprefix or \"\",",
3856 " }",
3857 " if type(names[cname].realname) == \"string\" then",
3858 " table.insert(sdata,names[cname].realname)",
3859 " end",
3860 " insend(unpack(sdata))",
3861 " end",
3862 " else --if you're a client, studies have shown that you're the type of fuck who makes positive acronyms out of insults that are thrown your way",
3863 " local sdata = {",
3864 " names[cname].name,",
3865 " msg,",
3866 " prefix..names[cname].prefix or \"<\",",
3867 " suffix..names[cname].suffix or \"> \",",
3868 " names[cname].msgprefix or \"\",",
3869 " }",
3870 " if type(names[cname].realname) == \"string\" then",
3871 " table.insert(sdata,names[cname].realname)",
3872 " end",
3873 " netsend(unpack(sdata))",
3874 " end",
3875 " end",
3876 "end",
3877 "",
3878 "local renderHistory = function() --this shows all the latest and greatest (optional) messages sent by fakechat clients!",
3879 " local y = scr_y-2",
3880 " local r = \"&r\"",
3881 " term.setBackgroundColor(colors.black)",
3882 " for a = #sHistory, #sHistory-(scr_y-2), -1 do",
3883 " if not sHistory[a] then break end",
3884 " term.setCursorPos(1,y)",
3885 " term.clearLine()",
3886 " filterColors(sHistory[a].p..r..sHistory[a].n..r..sHistory[a].s..r..sHistory[a].m,true)",
3887 " y = y - 1",
3888 " end",
3889 "end",
3890 "",
3891 "local server = function() --now THIS is what I call a quality function! servers are where it's at! *it* being command computers, of course...",
3892 " while true do",
3893 " local evt = {os.pullEvent(\"modem_message\")}",
3894 " if type(evt[5]) == \"table\" then",
3895 " local i = evt[5]",
3896 " if type(i.name) == \"string\" and type(i.msg) == \"string\" and type(i.prefix) == \"string\" and type(i.suffix) == \"string\" and type(i.realname) == \"string\" then",
3897 " table.insert(sHistory,{n=i.name, m=i.msg, p=i.prefix, s=i.suffix})",
3898 " send( i.name, i.msg, i.prefix, i.suffix, i.realname, true)",
3899 " dnb(function() return renderHistory() end)",
3900 " end",
3901 " end",
3902 " end",
3903 "end",
3904 "",
3905 "moreModems = function() --keep them modems loaded!",
3906 " while true do",
3907 " setModems()",
3908 " sleep(0)",
3909 " end",
3910 "end",
3911 "",
3912 "switchNames = function() --in case you happen to be named harry kuntz, and want to change that right away",
3913 " local evt, key, rerender",
3914 " while true do",
3915 " rerender = false",
3916 " evt, key = os.pullEvent(\"key\")",
3917 " if key == keys.pageUp then",
3918 " cname = cname - 1",
3919 " rerender = true",
3920 " elseif key == keys.pageDown then",
3921 " cname = cname + 1",
3922 " rerender = true",
3923 " end",
3924 " if cname <= 0 then",
3925 " cname = #names",
3926 " elseif cname > #names then",
3927 " cname = 1",
3928 " end",
3929 " if rerender then renderReadBar(true) end",
3930 " end",
3931 "end",
3932 "",
3933 "local funclist = { --this is the funciest list I've ever laid eyes upon",
3934 " client,",
3935 " moreModems,",
3936 " switchNames,",
3937 "}",
3938 "if isServer then table.insert(funclist,server) end --clients are not servers, you thick idiot",
3939 "",
3940 "parallel.waitForAny(unpack(funclist)) --execute the SHIT out of this!",
3941 "",
3942 "term.setCursorPos(1,scr_y)",
3943 "term.setBackgroundColor(colors.black)",
3944 "term.clearLine() --the last line is always the hardest...*sniffle*",
3945 },
3946 [ "/tron.lua" ] = {
3947 "--[[",
3948 "pastebin get jgyepx3g tron ",
3949 "std pb jgyepx3g tron ",
3950 "--]]",
3951 "",
3952 "local isOpen=false",
3953 "for k,v in pairs({\"right\",\"left\",\"top\",\"bottom\",\"front\",\"back\"}) do",
3954 " if peripheral.getType(v)==\"modem\" then",
3955 " rednet.open(v)",
3956 " isOpen=true",
3957 " end",
3958 "end",
3959 "if not isOpen then",
3960 " error(\"no modem attached\")",
3961 "end",
3962 "if not term.isColor() then",
3963 " if _CC_VERSION then",
3964 " colors.orange = colors.lightGray",
3965 " colors.blue = colors.lightGray",
3966 " colors.red = colors.white",
3967 " colors.lightBlue = colors.white",
3968 " else",
3969 " colors.gray = colors.black",
3970 " colors.orange = colors.white",
3971 " colors.blue = colors.white",
3972 " colors.red = colors.white",
3973 " colors.lightBlue = colors.white",
3974 " end",
3975 "end",
3976 "",
3977 "local Mx,My=term.getSize()",
3978 "local Cx,Cy=math.floor(Mx/2),math.floor(My/2)",
3979 "function maingame()",
3980 " local lang={\"Waiting for player\",{[0]=\"^\",\">\",\"v\",\"<\"},{{\"|\",\"/\",\"|\",\"\\\\\"},{\"/\",\"-\",\"\\\\\",\"-\"},{\"|\",\"\\\\\",\"|\",\"/\"},{\"\\\\\",\"-\",\"/\",\"-\"}},\"You died.\",\"You won.\"}",
3981 " local board=setmetatable({},{__index=function(s,n) s[n]={} return s[n] end})",
3982 " for l1=99,-99,-1 do",
3983 " board[l1][-99]={\"-\",3}",
3984 " end",
3985 " for l1=99,-99,-1 do",
3986 " board[l1][99]={\"|\",3}",
3987 " end",
3988 " for l1=99,-99,-1 do",
3989 " board[-99][l1]={\"-\",3}",
3990 " end",
3991 " for l1=99,-99,-1 do",
3992 " board[99][l1]={\"|\",3}",
3993 " end",
3994 " board[100][100]={\"/\",3}",
3995 " board[100][-100]={\"\\\\\",3}",
3996 " board[-100][100]={\"/\",3}",
3997 " board[-100][-100]={\"\\\\\",3}",
3998 " local modem",
3999 " local initheader=\"TRON:\"",
4000 " local pnid",
4001 " local function send(...)",
4002 " rednet.send(pnid,string.sub(textutils.serialize({...}),2,-2))",
4003 " end",
4004 " local function decode(dat)",
4005 " return textutils.unserialize(\"{\"..dat..\"}\")",
4006 " end",
4007 " local col",
4008 " term.setCursorPos(math.floor(Cx-(#lang[1])/2),Cy)",
4009 " term.setTextColor(colors.orange)",
4010 " term.setBackgroundColor(colors.black)",
4011 " term.clear()",
4012 " term.write(lang[1])",
4013 " rednet.broadcast(initheader..\"pingcon\")",
4014 " local p1,p2",
4015 " while true do",
4016 " local p={os.pullEvent()}",
4017 " if p[1]==\"rednet_message\" and p[2]~=os.getComputerID() then",
4018 " if p[3]==initheader..\"pingcon\" then",
4019 " rednet.send(p[2],initheader..\"pongcon\")",
4020 " pnid=p[2]",
4021 " col={colors.blue,colors.red,colors.lightBlue}",
4022 " p1={pos={x=2,y=1},dir=0}",
4023 " p2={pos={x=1,y=1},dir=0}",
4024 " break",
4025 " elseif p[3]==initheader..\"pongcon\" then",
4026 " pnid=p[2]",
4027 " col={colors.red,colors.blue,colors.lightBlue}",
4028 " p1={pos={x=1,y=1},dir=0}",
4029 " p2={pos={x=2,y=1},dir=0}",
4030 " break",
4031 " end",
4032 " end",
4033 " end",
4034 " term.setBackgroundColor(colors.black)",
4035 " term.clear()",
4036 " local frs=0",
4037 " local fps=0 -- frame counter (debugging)",
4038 " local function render()",
4039 " local tsv = term.current().setVisible",
4040 " if tsv then tsv(false) end",
4041 " frs=frs+1",
4042 " term.setTextColor(colors.gray)",
4043 " for l1=1,My do",
4044 " term.setCursorPos(1,l1)",
4045 " local pre=p1.pos.x%3",
4046 " if (l1+p1.pos.y)%3==0 then",
4047 " if pre==1 then",
4048 " pre=\"--\"",
4049 " elseif pre==2 then",
4050 " pre=\"-\"",
4051 " else",
4052 " pre=\"\"",
4053 " end",
4054 " term.write(pre..(\"+--\"):rep(math.ceil(Mx/2)))",
4055 " else",
4056 " if pre==1 then",
4057 " pre=\" \"",
4058 " elseif pre==2 then",
4059 " pre=\" \"",
4060 " else",
4061 " pre=\"\"",
4062 " end",
4063 " term.write(pre..(\"| \"):rep(math.ceil(Mx/2)))",
4064 " end",
4065 " end",
4066 " term.setTextColor(colors.blue)",
4067 " local num=0",
4068 " for k,v in pairs(board) do",
4069 " for l,y in pairs(v) do",
4070 " if (k-p1.pos.x)+Cx<=Mx and (k-p1.pos.x)+Cx>=1 and (l-p1.pos.y)+Cy<=My and (l-p1.pos.y)+Cy>=1 then",
4071 " term.setTextColor(col[y[2]] or y[2])",
4072 " term.setCursorPos((k-p1.pos.x)+Cx,(l-p1.pos.y)+Cy)",
4073 " term.write(y[1])",
4074 " num=num+1",
4075 " end",
4076 " end ",
4077 " end",
4078 " term.setCursorPos(1,1)",
4079 " if col[1]==colors.blue then",
4080 " term.setTextColor(colors.blue)",
4081 " term.write(\"BLUE\")",
4082 " else",
4083 " term.setTextColor(colors.red)",
4084 " term.write(\"RED\")",
4085 " end",
4086 " if tsv then tsv(true) end",
4087 " end",
4088 " local odr={[p1]=p1.dir,[p2]=p2.dir}",
4089 " local function processmove(u)",
4090 " local ccol",
4091 " if u==p1 then",
4092 " ccol=col[1]",
4093 " else",
4094 " ccol=col[2]",
4095 " end",
4096 " term.setTextColor(ccol)",
4097 " if u==p1 and board[u.pos.x][u.pos.y] then",
4098 " send(\"DIE\")",
4099 " term.setCursorPos(Cx,Cy)",
4100 " term.write(\"x\")",
4101 " sleep(2)",
4102 " term.setCursorPos(Cx-math.floor(#lang[4]/2),Cy)",
4103 " term.setTextColor(colors.orange)",
4104 " term.clear()",
4105 " term.write(lang[4])",
4106 " sleep(5)",
4107 " term.setTextColor(colors.white)",
4108 " term.setBackgroundColor(colors.black)",
4109 " term.setCursorPos(1,1)",
4110 " term.clear()",
4111 " error(\"\",0)",
4112 " end",
4113 " if odr[u]~=u.dir then",
4114 " board[u.pos.x][u.pos.y]={lang[3][odr[u]+1][u.dir+1],ccol}",
4115 " end",
4116 " if not board[u.pos.x][u.pos.y] then",
4117 " if u.dir%2==0 then",
4118 " board[u.pos.x][u.pos.y]={\"|\",ccol}",
4119 " else",
4120 " board[u.pos.x][u.pos.y]={\"-\",ccol}",
4121 " end",
4122 " end",
4123 " local chr=board[u.pos.x][u.pos.y][1]",
4124 " local shr={x=u.pos.x,y=u.pos.y}",
4125 " if u.dir==0 then",
4126 " u.pos.y=u.pos.y-1",
4127 " elseif u.dir==1 then",
4128 " u.pos.x=u.pos.x+1",
4129 " elseif u.dir==2 then",
4130 " u.pos.y=u.pos.y+1",
4131 " else",
4132 " u.pos.x=u.pos.x-1",
4133 " end",
4134 " odr[u]=u.dir",
4135 " return chr,shr",
4136 " end",
4137 " local function renderchar(u)",
4138 " local ccol",
4139 " if u==p1 then",
4140 " ccol=col[1]",
4141 " term.setCursorPos(Cx,Cy)",
4142 " else",
4143 " ccol=col[2]",
4144 " term.setCursorPos((p2.pos.x-p1.pos.x)+Cx,(p2.pos.y-p1.pos.y)+Cy)",
4145 " end",
4146 " term.setTextColor(ccol)",
4147 " term.write(lang[2][u.dir])",
4148 " end",
4149 " function processturn(p,u)",
4150 " local dirs={[keys.up]=0,[keys.right]=1,[keys.down]=2,[keys.left]=3}",
4151 " if (odr[u]+2)%4~=dirs[p] then",
4152 " u.dir=dirs[p]",
4153 " renderchar(u)",
4154 " if u==p1 then",
4155 " send(\"ROT\",u.dir)",
4156 " end",
4157 " end",
4158 " end",
4159 " render()",
4160 " local move=os.startTimer(0.1)",
4161 " local fct=os.startTimer(1)",
4162 " while true do",
4163 " local p={os.pullEvent()}",
4164 " if p[1]==\"key\" then",
4165 " if p[2]==keys.up or p[2]==keys.right or p[2]==keys.down or p[2]==keys.left then",
4166 " processturn(p[2],p1)",
4167 " end",
4168 " elseif p[1]==\"timer\" then",
4169 " if p[2]==move then",
4170 " local ret,ret2=processmove(p1)",
4171 " move=os.startTimer(0.1)",
4172 " send(\"MOVE\",ret2,ret)",
4173 " elseif p[2]==fct then",
4174 " fps=frs",
4175 " frs=0",
4176 " fct=os.startTimer(1)",
4177 " end",
4178 " elseif p[1]==\"rednet_message\" and p[2]==pnid then",
4179 " local dat=decode(p[3])",
4180 " if dat[1]==\"ROT\" then",
4181 " p2.dir=dat[2]",
4182 " renderchar(p2)",
4183 " elseif dat[1]==\"DIE\" then",
4184 " p1.pos=p2.pos",
4185 " render()",
4186 " term.setTextColor(col[2])",
4187 " term.setCursorPos(Cx,Cy)",
4188 " term.write(\"x\")",
4189 " sleep(2)",
4190 " term.setCursorPos(Cx-math.floor(#lang[5]/2),Cy)",
4191 " term.setTextColor(colors.orange)",
4192 " term.clear()",
4193 " term.write(lang[5])",
4194 " sleep(5)",
4195 " term.setTextColor(colors.white)",
4196 " term.setBackgroundColor(colors.black)",
4197 " term.setCursorPos(1,1)",
4198 " term.clear()",
4199 " return",
4200 " elseif dat[1]==\"MOVE\" then",
4201 " p2.pos=dat[2]",
4202 " board[p2.pos.x][p2.pos.y]={dat[3],col[2]}",
4203 " render()",
4204 " renderchar(p1)",
4205 " renderchar(p2)",
4206 " end",
4207 " end",
4208 " end",
4209 "end",
4210 "local selected=1",
4211 "function rmain()",
4212 " term.setBackgroundColor(colors.black)",
4213 " term.clear()",
4214 " term.setCursorPos(1,1)",
4215 " term.setTextColor(colors.blue)",
4216 " local txt=\" _ _______________ ________ __ _\\n/ \\\\/ _____________\\\\ / ____ \\\\ | \\\\ / |\\n\\\\_/| / / \\\\ | / / \\\\ \\\\ | \\\\ __/ |\\n | | | |\\\\ ___/ | | | || \\\\ |\\n | | | | \\\\ \\\\ | | | || __\\\\ |\\n | | | | \\\\ \\\\ \\\\ \\\\____/ / | / \\\\ |\\n \\\\_/ \\\\_/ \\\\_/ \\\\________/ |_/ \\\\__|\"",
4217 " local cnt=1",
4218 " local cnt2=Cx-23",
4219 " for char in string.gmatch(txt,\".\") do",
4220 " if char~=\" \" and char~=\"\\n\" then",
4221 " term.setCursorPos(cnt2,cnt)",
4222 " term.write(char)",
4223 " elseif char==\"\\n\" then",
4224 " cnt=cnt+1",
4225 " cnt2=Cx-23",
4226 " end",
4227 " cnt2=cnt2+1",
4228 " end",
4229 " local selections={\"Multiplayer\",\"Exit\"}",
4230 " selected=((selected-1)%(#selections))+1",
4231 " for k,v in pairs(selections) do",
4232 " if k==selected then",
4233 " term.setTextColor(colors.blue)",
4234 " term.setCursorPos(Cx-(math.floor(#v/2)+1),k+10)",
4235 " term.write(\">\"..v..\"<\")",
4236 " term.setTextColor(colors.lightBlue)",
4237 " term.setCursorPos(Cx-math.floor(#v/2),k+10)",
4238 " term.write(v)",
4239 " else",
4240 " term.setTextColor(colors.lightBlue)",
4241 " term.setCursorPos(Cx-math.floor(#v/2),k+10)",
4242 " term.write(v)",
4243 " end",
4244 " end",
4245 "end",
4246 "rmain()",
4247 "while true do",
4248 " p={os.pullEvent()}",
4249 " if p[1]==\"key\" then",
4250 " if p[2]==keys.up then",
4251 " selected=selected-1",
4252 " rmain()",
4253 " elseif p[2]==keys.down then",
4254 " selected=selected+1",
4255 " rmain()",
4256 " elseif p[2]==keys.enter then",
4257 " if selected==1 then",
4258 " a,b=pcall(maingame)",
4259 " if not a and b~=\"\" then",
4260 " error(b,0)",
4261 " end",
4262 " rmain()",
4263 " else",
4264 " break",
4265 " end",
4266 " end",
4267 " end",
4268 "end",
4269 "term.setCursorPos(1,1)",
4270 "term.clear()",
4271 },
4272 [ "/enchat3.lua" ] = {
4273 "--[[",
4274 " Enchat 3.0",
4275 " Get with:",
4276 " wget https://github.com/LDDestroier/enchat/raw/master/enchat3.lua enchat3.lua",
4277 "",
4278 "This is a stable release. You fool!",
4279 "--]]",
4280 "",
4281 "local scr_x, scr_y = term.getSize()",
4282 "CHATBOX_SAFEMODE = nil",
4283 "",
4284 "enchat = {",
4285 " version = 3.0,",
4286 " isBeta = false,",
4287 " port = 11000,",
4288 " skynetPort = \"enchat3-default\",",
4289 " url = \"https://github.com/LDDestroier/enchat/raw/master/enchat3.lua\",",
4290 " betaurl = \"https://github.com/LDDestroier/enchat/raw/beta/enchat3.lua\",",
4291 " ignoreModem = false,",
4292 " dataDir = \"/.enchat\",",
4293 " useChatbox = false",
4294 "}",
4295 "",
4296 "local enchatSettings = { -- DEFAULT settings.",
4297 " animDiv = 4, -- divisor of text animation speed (scrolling from left)",
4298 " doAnimate = true, -- whether or not to animate text moving from left side of screen",
4299 " reverseScroll = false, -- whether or not to make scrolling up really scroll down",
4300 " redrawDelay = 0.1, -- delay between redrawing",
4301 " useSetVisible = true, -- whether or not to use term.current().setVisible(), which has performance and flickering improvements",
4302 " pageKeySpeed = 8, -- how far PageUP or PageDOWN should scroll",
4303 " doNotif = true, -- whether or not to use oveerlay glasses for notifications, if possible",
4304 " doKrazy = true, -- whether or not to add &k obfuscation",
4305 " useSkynet = true, -- whether or not to use gollark's Skynet in addition to modem calls",
4306 " extraNewline = true, -- adds an extra newline after every message since setting to true",
4307 " acceptPictoChat = true -- whether or not to allow tablular enchat input, which is what /picto uses",
4308 "}",
4309 "",
4310 "local palette = {",
4311 " bg = colors.black, -- background color",
4312 " txt = colors.white, -- text color (should contrast with bg)",
4313 " promptbg = colors.gray, -- chat prompt background",
4314 " prompttxt = colors.white, -- chat prompt text",
4315 " scrollMeter = colors.lightGray, -- scroll indicator",
4316 " chevron = colors.black, -- color of \">\" left of text prompt",
4317 " title = colors.lightGray, -- color of title, if available",
4318 " titlebg = colors.lightGray -- background color of title, if available",
4319 "}",
4320 "",
4321 "UIconf = {",
4322 " promptY = 1, -- Y position of read prompt, relative to bottom of screen",
4323 " chevron = \">\", -- symbol before read prompt",
4324 " chatlogTop = 1, -- where chatlog is written to screen, relative to top of screen",
4325 " title = \"\", -- overwritten every render, don't bother here",
4326 " doTitle = false, -- whether or not to draw UIconf.title at the top of the screen",
4327 " nameDecolor = false, -- if true, sets all names to palette.chevron color,",
4328 " centerTitle = false, -- if true, centers the title",
4329 " prefix = \"<\",",
4330 " suffix = \"> \"",
4331 "}",
4332 "",
4333 "-- Attempt to get some slight optimization through localizing basic functions.",
4334 "local mathmax, mathmin, mathrandom = math.max, math.min, math.random",
4335 "local termblit, termwrite = term.blit, term.write",
4336 "local termsetCursorPos, termgetCursorPos, termsetCursorBlink = term.setCursorPos, term.getCursorPos, term.setCursorBlink",
4337 "local termsetTextColor, termsetBackgroundColor = term.setTextColor, term.setBackgroundColor",
4338 "local termgetTextColor, termgetBackgroundColor = term.getTextColor, term.getBackgroundColor",
4339 "local termclear, termclearLine = term.clear, term.clearLine",
4340 "local tableinsert, tableremove, tableconcat = table.insert, table.remove, table.concat",
4341 "local textutilsserialize, textutilsunserialize = textutils.serialize, textutils.unserialize",
4342 "local stringsub, stringgsub, stringrep = string.sub, string.gsub, string.rep",
4343 "local unpack = unpack",
4344 "-- This better do something.",
4345 "",
4346 "local initcolors = {",
4347 " bg = termgetBackgroundColor(),",
4348 " txt = termgetTextColor()",
4349 "}",
4350 "",
4351 "local tArg = {...}",
4352 "",
4353 "local yourName = tArg[1]",
4354 "local encKey = tArg[2]",
4355 "",
4356 "local setEncKey = function(newKey)",
4357 " encKey = newKey",
4358 "end",
4359 "",
4360 "local saveSettings = function()",
4361 " local file = fs.open(fs.combine(enchat.dataDir, \"settings\"), \"w\")",
4362 " file.write(",
4363 " textutilsserialize({",
4364 " enchatSettings = enchatSettings,",
4365 " palette = palette,",
4366 " UIconf = UIconf,",
4367 " })",
4368 " )",
4369 " file.close()",
4370 "end",
4371 "",
4372 "local loadSettings = function()",
4373 " local contents",
4374 " if not fs.exists(fs.combine(enchat.dataDir, \"settings\")) then",
4375 " saveSettings()",
4376 " end",
4377 " local file = fs.open(fs.combine(enchat.dataDir, \"settings\"), \"r\")",
4378 " contents = file.readAll()",
4379 " file.close()",
4380 " local newSettings = textutilsunserialize(contents)",
4381 " if newSettings then",
4382 " for k,v in pairs(newSettings.enchatSettings) do",
4383 " enchatSettings[k] = v",
4384 " end",
4385 " for k,v in pairs(newSettings.palette) do",
4386 " palette[k] = v",
4387 " end",
4388 " for k,v in pairs(newSettings.UIconf) do",
4389 " UIconf[k] = v",
4390 " end",
4391 " else",
4392 " saveSettings()",
4393 " end",
4394 "end",
4395 "",
4396 "local updateEnchat = function(doBeta)",
4397 " local pPath = shell.getRunningProgram()",
4398 " local h = http.get((doBeta or enchat.isBeta) and enchat.betaurl or enchat.url)",
4399 " if not h then",
4400 " return false, \"Could not connect.\"",
4401 " else",
4402 " local content = h.readAll()",
4403 " local file = fs.open(pPath, \"w\")",
4404 " file.write(content)",
4405 " file.close()",
4406 " return true, \"Updated!\"",
4407 " end",
4408 "end",
4409 "",
4410 "-- disables chat screen updating",
4411 "local pauseRendering = true",
4412 "",
4413 "-- primarily for use when coloring palette",
4414 "local colors_strnames = {",
4415 " [\"white\"] = colors.white,",
4416 " [\"pearl\"] = colors.white,",
4417 " [\"aryan\"] = colors.white,",
4418 " [\"#f0f0f0\"] = colors.white,",
4419 " [\"orange\"] = colors.orange,",
4420 " [\"carrot\"] = colors.orange,",
4421 " [\"pumpkin\"] = colors.orange,",
4422 " [\"#f2b233\"] = colors.orange,",
4423 " [\"magenta\"] = colors.magenta,",
4424 " [\"hotpink\"] = colors.magenta,",
4425 " [\"lightpurple\"] = colors.magenta,",
4426 " [\"light purple\"] = colors.magenta,",
4427 " [\"#e57fd8\"] = colors.magenta,",
4428 " [\"lightblue\"] = colors.lightBlue,",
4429 " [\"light blue\"] = colors.lightBlue,",
4430 " [\"skyblue\"] = colors.lightBlue,",
4431 " [\"#99b2f2\"] = colors.lightBlue,",
4432 " [\"yellow\"] = colors.yellow,",
4433 " [\"piss\"] = colors.yellow,",
4434 " [\"lemon\"] = colors.yellow,",
4435 " [\"cowardice\"] = colors.yellow,",
4436 " [\"#dede6c\"] = colors.yellow,",
4437 " [\"lime\"] = colors.lime,",
4438 " [\"lightgreen\"] = colors.lime,",
4439 " [\"light green\"] = colors.lime,",
4440 " [\"slime\"] = colors.lime,",
4441 " [\"#7fcc19\"] = colors.lime,",
4442 " [\"pink\"] = colors.pink,",
4443 " [\"lightishred\"] = colors.pink,",
4444 " [\"lightish red\"] = colors.pink,",
4445 " [\"communist\"] = colors.pink,",
4446 " [\"#f2b2cc\"] = colors.pink,",
4447 " [\"gray\"] = colors.gray,",
4448 " [\"grey\"] = colors.gray,",
4449 " [\"graey\"] = colors.gray,",
4450 " [\"#4c4c4c\"] = colors.gray,",
4451 " [\"lightgray\"] = colors.lightGray,",
4452 " [\"lightgrey\"] = colors.lightGray,",
4453 " [\"light gray\"] = colors.lightGray,",
4454 " [\"light grey\"] = colors.lightGray,",
4455 " [\"#999999\"] = colors.lightGray,",
4456 " [\"cyan\"] = colors.cyan,",
4457 " [\"seawater\"] = colors.cyan,",
4458 " [\"#4c99b2\"] = colors.cyan,",
4459 " [\"purple\"] = colors.purple,",
4460 " [\"purble\"] = colors.purple,",
4461 " [\"obsidian\"] = colors.purple,",
4462 " [\"#b266e5\"] = colors.purple,",
4463 " [\"blue\"] = colors.blue,",
4464 " [\"blu\"] = colors.blue,",
4465 " [\"blueberry\"] = colors.blue,",
4466 " [\"x\"] = colors.blue,",
4467 " [\"megaman\"] = colors.blue,",
4468 " [\"#3366bb\"] = colors.blue,",
4469 " [\"brown\"] = colors.brown,",
4470 " [\"shit\"] = colors.brown,",
4471 " [\"dirt\"] = colors.brown,",
4472 " [\"#7f664c\"] = colors.brown,",
4473 " [\"green\"] = colors.green,",
4474 " [\"grass\"] = colors.green,",
4475 " [\"#57a64e\"] = colors.green,",
4476 " [\"red\"] = colors.red,",
4477 " [\"menstration\"] = colors.red,",
4478 " [\"blood\"] = colors.red,",
4479 " [\"marinara\"] = colors.red,",
4480 " [\"zero\"] = colors.red,",
4481 " [\"protoman\"] = colors.red,",
4482 " [\"communism\"] = colors.red,",
4483 " [\"#cc4c4c\"] = colors.red,",
4484 " [\"black\"] = colors.black,",
4485 " [\"dark\"] = colors.black,",
4486 " [\"coal\"] = colors.black,",
4487 " [\"onyx\"] = colors.black,",
4488 " [\"#191919\"] = colors.black,",
4489 "}",
4490 "",
4491 "local toblit = {",
4492 " [0] = \" \",",
4493 " [1] = \"0\",",
4494 " [2] = \"1\",",
4495 " [4] = \"2\",",
4496 " [8] = \"3\",",
4497 " [16] = \"4\",",
4498 " [32] = \"5\",",
4499 " [64] = \"6\",",
4500 " [128] = \"7\",",
4501 " [256] = \"8\",",
4502 " [512] = \"9\",",
4503 " [1024] = \"a\",",
4504 " [2048] = \"b\",",
4505 " [4096] = \"c\",",
4506 " [8192] = \"d\",",
4507 " [16384] = \"e\",",
4508 " [32768] = \"f\"",
4509 "}",
4510 "local tocolors = {}",
4511 "for k,v in pairs(toblit) do",
4512 " tocolors[v] = k",
4513 "end",
4514 "",
4515 "local codeNames = {",
4516 " [\"r\"] = \"reset\", -- Sets either the text (&) or background (~) colors to their original color.",
4517 " [\"{\"] = \"stopFormatting\", -- Toggles formatting text off",
4518 " [\"}\"] = \"startFormatting\", -- Toggles formatting text on",
4519 " [\"k\"] = \"krazy\" -- Makes the font kuh-razy!",
4520 "}",
4521 "",
4522 "local kraziez = {",
4523 " [\"l\"] = {",
4524 " \"!\",",
4525 " \"l\",",
4526 " \"1\",",
4527 " \"|\",",
4528 " \"i\",",
4529 " \"I\",",
4530 " \":\",",
4531 " \";\",",
4532 " },",
4533 " [\"m\"] = {",
4534 " \"M\",",
4535 " \"W\",",
4536 " \"w\",",
4537 " \"m\",",
4538 " \"X\",",
4539 " \"N\",",
4540 " \"_\",",
4541 " \"%\",",
4542 " \"@\",",
4543 " },",
4544 " [\"all\"] = {}",
4545 "}",
4546 "",
4547 "for a = 1, #kraziez[\"l\"] do",
4548 " kraziez[kraziez[\"l\"][a]] = kraziez[\"l\"]",
4549 "end",
4550 "for k,v in pairs(kraziez) do",
4551 " for a = 1, #v do",
4552 " kraziez[kraziez[k][a]] = v",
4553 " end",
4554 "end",
4555 "-- check if using older CC version, omit special characters if it's too old",
4556 "if tonumber(_CC_VERSION or 0) >= 1.76 then",
4557 " for a = 1, 255 do",
4558 " if (a ~= 32) and (a ~= 13) and (a ~= 10) then",
4559 " kraziez[\"all\"][#kraziez[\"all\"]+1] = string.char(a)",
4560 " end",
4561 " end",
4562 "else",
4563 " for a = 33, 126 do",
4564 " kraziez[\"all\"][#kraziez[\"all\"]+1] = string.char(a)",
4565 " end",
4566 "end",
4567 "",
4568 "local explode = function(div, str, replstr, includeDiv)",
4569 " if (div == '') then",
4570 " return false",
4571 " end",
4572 " local pos, arr = 0, {}",
4573 " for st, sp in function() return string.find(str, div, pos, false) end do",
4574 " tableinsert(arr, string.sub(replstr or str, pos, st - 1 + (includeDiv and #div or 0)))",
4575 " pos = sp + 1",
4576 " end",
4577 " tableinsert(arr, string.sub(replstr or str, pos))",
4578 " return arr",
4579 "end",
4580 "local parseKrazy = function(c)",
4581 " if kraziez[c] then",
4582 " return kraziez[c][mathrandom(1, #kraziez[c])]",
4583 " else",
4584 " return kraziez.all[mathrandom(1, #kraziez.all)]",
4585 " end",
4586 "end",
4587 "",
4588 "local textToBlit = function(input, onlyString, initText, initBack, checkPos, useJSONformat)",
4589 " if not input then return end",
4590 " checkPos = checkPos or -1",
4591 " initText, initBack = initText or toblit[term.getTextColor()], initBack or toblit[term.getBackgroundColor()]",
4592 " tcode, bcode = \"&\", \"~\"",
4593 " local cpos, cx = 0, 0",
4594 " local skip, ignore, ex = nil, false, nil",
4595 " local text, back, nex = initText, initBack, nil",
4596 " ",
4597 " local charOut, textOut, backOut = {}, {}, {}",
4598 " local JSONoutput = {}",
4599 " ",
4600 " local krazy = false",
4601 " local bold = false",
4602 " local strikethrough = false",
4603 " local underline = false",
4604 " local italic = false",
4605 " ",
4606 " local codes = {}",
4607 " codes[\"r\"] = function(prev)",
4608 " if not ignore then",
4609 " if prev == tcode then",
4610 " text = initText",
4611 " bold = false",
4612 " strikethrough = false",
4613 " underline = false",
4614 " italic = false",
4615 " elseif prev == bcode then",
4616 " if useJSONformat then",
4617 " return 0",
4618 " else",
4619 " back = initBack",
4620 " end",
4621 " end",
4622 " krazy = false",
4623 " else",
4624 " return 0",
4625 " end",
4626 " end",
4627 " codes[\"k\"] = function(prev)",
4628 " if not ignore then",
4629 " krazy = not krazy",
4630 " else",
4631 " return 0",
4632 " end",
4633 " end",
4634 " codes[\"{\"] = function(prev)",
4635 " if not ignore then",
4636 " ignore = true",
4637 " else",
4638 " return 0",
4639 " end",
4640 " end",
4641 " codes[\"}\"] = function(prev)",
4642 " if ignore then",
4643 " ignore = false",
4644 " else",
4645 " return 0",
4646 " end",
4647 " end",
4648 " ",
4649 " if useJSONformat then",
4650 " codes[\"l\"] = function(prev)",
4651 " bold = true",
4652 " end",
4653 " codes[\"m\"] = function(prev)",
4654 " strikethrough = true",
4655 " end",
4656 " codes[\"n\"] = function(prev)",
4657 " underline = true",
4658 " end",
4659 " codes[\"o\"] = function(prev)",
4660 " italic = true",
4661 " end",
4662 " end",
4663 " ",
4664 " local sx, str = 0",
4665 " input = stringgsub(input, \"(\\\\)(%d%d?%d?)\", function(cap, val)",
4666 " if tonumber(val) < 256 then",
4667 " cpos = cpos - #val",
4668 " return string.char(val)",
4669 " else",
4670 " return cap..val",
4671 " end",
4672 " end)",
4673 " ",
4674 " local MCcolors = {",
4675 " [\"0\"] = \"white\", ",
4676 " [\"1\"] = \"gold\",",
4677 " [\"2\"] = \"light_purple\",",
4678 " [\"3\"] = \"aqua\",",
4679 " [\"4\"] = \"yellow\",",
4680 " [\"5\"] = \"green\",",
4681 " [\"6\"] = \"light_purple\",",
4682 " [\"7\"] = \"dark_gray\",",
4683 " [\"8\"] = \"gray\",",
4684 " [\"9\"] = \"dark_aqua\",",
4685 " [\"a\"] = \"dark_purple\",",
4686 " [\"b\"] = \"dark_blue\",",
4687 " [\"c\"] = \"gold\",",
4688 " [\"d\"] = \"dark_green\",",
4689 " [\"e\"] = \"red\",",
4690 " [\"f\"] = \"black\",",
4691 " }",
4692 " ",
4693 " for cx = 1, #input do",
4694 " str = stringsub(input,cx,cx)",
4695 " if skip then",
4696 " if tocolors[str] and not ignore then",
4697 " if skip == tcode then",
4698 " text = str == \" \" and initText or str",
4699 " if sx < checkPos then",
4700 " cpos = cpos - 2",
4701 " end",
4702 " elseif skip == bcode then",
4703 " back = str == \" \" and initBack or str",
4704 " if sx < checkPos then",
4705 " cpos = cpos - 2",
4706 " end",
4707 " end",
4708 " elseif codes[str] and not (ignore and str == \"{\") then",
4709 " ex = codes[str](skip) or 0",
4710 " sx = sx + ex",
4711 " if sx < checkPos then",
4712 " cpos = cpos - ex - 2",
4713 " end",
4714 " else",
4715 " sx = sx + 1",
4716 " if useJSONformat then",
4717 " JSONoutput[sx] = {",
4718 " text = (skip..str),",
4719 " color = onlyString and \"f\" or MCcolors[text],",
4720 " bold = (not onlyString) and bold,",
4721 " italic = (not onlyString) and italic,",
4722 " underline = (not onlyString) and underline,",
4723 " obfuscated = (not onlyString) and krazy,",
4724 " strikethrough = (not onlyString) and strikethrough",
4725 " }",
4726 " else",
4727 " charOut[sx] = krazy and parseKrazy(prev..str) or (skip..str)",
4728 " textOut[sx] = stringrep(text,2)",
4729 " backOut[sx] = stringrep(back,2)",
4730 " end",
4731 " end",
4732 " skip = nil",
4733 " else",
4734 " if (str == tcode or str == bcode) and (codes[stringsub(input, 1+cx, 1+cx)] or tocolors[stringsub(input,1+cx,1+cx)]) then",
4735 " skip = str",
4736 " else",
4737 " sx = sx + 1",
4738 " if useJSONformat then",
4739 " JSONoutput[sx] = {",
4740 " text = str,",
4741 " color = onlyString and \"f\" or MCcolors[text],",
4742 " bold = (not onlyString) and bold,",
4743 " italic = (not onlyString) and italic,",
4744 " underline = (not onlyString) and underline,",
4745 " obfuscated = (not onlyString) and krazy,",
4746 " strikethrough = (not onlyString) and strikethrough",
4747 " }",
4748 " else",
4749 " charOut[sx] = krazy and parseKrazy(str) or str",
4750 " textOut[sx] = text",
4751 " backOut[sx] = back",
4752 " end",
4753 " end",
4754 " end",
4755 " end",
4756 " if useJSONformat then",
4757 " return textutils.serializeJSON(JSONoutput)",
4758 " else",
4759 " if onlyString then",
4760 " return tableconcat(charOut), (checkPos > -1) and cpos or nil",
4761 " else",
4762 " return {tableconcat(charOut), tableconcat(textOut), tableconcat(backOut)}, (checkPos > -1) and cpos or nil",
4763 " end",
4764 " end",
4765 "end",
4766 "_G.textToBlit = textToBlit",
4767 "",
4768 "local colorRead = function(maxLength, _history)",
4769 " local output = \"\"",
4770 " local history, _history = {}, _history or {}",
4771 " for a = 1, #_history do",
4772 " history[a] = _history[a]",
4773 " end",
4774 " history[#history+1] = \"\"",
4775 " local hPos = #history",
4776 " local cx, cy = termgetCursorPos()",
4777 " local x, xscroll = 1, 1",
4778 " local ctrlDown = false",
4779 " termsetCursorBlink(true)",
4780 " local evt, key, bout, xmod, timtam",
4781 " while true do",
4782 " termsetCursorPos(cx, cy)",
4783 " bout, xmod = textToBlit(output, false, nil, nil, x)",
4784 " for a = 1, #bout do",
4785 " bout[a] = stringsub(bout[a], xscroll, xscroll + scr_x - cx)",
4786 " end",
4787 " termblit(unpack(bout))",
4788 " termwrite((\" \"):rep(scr_x - cx))",
4789 " termsetCursorPos(cx + x + xmod - xscroll, cy)",
4790 " evt = {os.pullEvent()}",
4791 " if evt[1] == \"char\" or evt[1] == \"paste\" then",
4792 " output = (output:sub(1, x-1)..evt[2]..output:sub(x)):sub(1, maxLength or -1)",
4793 " x = mathmin(x + #evt[2], #output+1)",
4794 " elseif evt[1] == \"key\" then",
4795 " key = evt[2]",
4796 " if key == keys.leftCtrl then",
4797 " ctrlDown = true",
4798 " elseif key == keys.left then",
4799 " x = mathmax(x - 1, 1)",
4800 " elseif key == keys.right then",
4801 " x = mathmin(x + 1, #output+1)",
4802 " elseif key == keys.backspace then",
4803 " if x > 1 then",
4804 " repeat",
4805 " output = output:sub(1,x-2)..output:sub(x)",
4806 " x = x - 1",
4807 " until output:sub(x-1,x-1) == \" \" or (not ctrlDown) or (x == 1)",
4808 " end",
4809 " elseif key == keys.delete then",
4810 " if x < #output+1 then",
4811 " repeat",
4812 " output = output:sub(1,x-1)..output:sub(x+1)",
4813 " until output:sub(x,x) == \" \" or (not ctrlDown) or (x == #output+1)",
4814 " end",
4815 " elseif key == keys.enter then",
4816 " termsetCursorBlink(false)",
4817 " return output",
4818 " elseif key == keys.home then",
4819 " x = 1",
4820 " elseif key == keys[\"end\"] then",
4821 " x = #output+1",
4822 " elseif key == keys.up then",
4823 " if history[hPos-1] then",
4824 " hPos = hPos - 1",
4825 " output = history[hPos]",
4826 " x = #output+1",
4827 " end",
4828 " elseif key == keys.down then",
4829 " if history[hPos+1] then",
4830 " hPos = hPos + 1",
4831 " output = history[hPos]",
4832 " x = #output+1",
4833 " end",
4834 " end",
4835 " elseif evt[1] == \"key_up\" then",
4836 " if evt[2] == keys.leftCtrl then",
4837 " ctrlDown = false",
4838 " end",
4839 " end",
4840 " if hPos > 1 then",
4841 " history[hPos] = output",
4842 " end",
4843 " if x+cx-xscroll+xmod > scr_x then",
4844 " xscroll = x-(scr_x-cx)+xmod",
4845 " elseif x-xscroll+xmod < 0 then",
4846 " repeat",
4847 " xscroll = xscroll - 1",
4848 " until x-xscroll-xmod >= 0",
4849 " end",
4850 " xscroll = math.max(1, xscroll)",
4851 " end",
4852 "end",
4853 "_G.colorRead = colorRead",
4854 "",
4855 "local checkValidName = function(_nayme)",
4856 " local nayme = textToBlit(_nayme,true)",
4857 " if type(nayme) ~= \"string\" then",
4858 " return false",
4859 " else",
4860 " return (#nayme >= 2 and #nayme <= 32 and nayme:gsub(\" \",\"\") ~= \"\")",
4861 " end",
4862 "end",
4863 "",
4864 "if tArg[1] == \"update\" then",
4865 " local res, message = updateEnchat(tArg[2] == \"beta\")",
4866 " return print(message)",
4867 "end",
4868 "",
4869 "local prettyClearScreen = function(start, stop)",
4870 " termsetTextColor(colors.lightGray)",
4871 " termsetBackgroundColor(colors.gray)",
4872 " if _VERSION then",
4873 " for y = start or 1, stop or scr_y do",
4874 " termsetCursorPos(1,y)",
4875 " if y == (start or 1) then",
4876 " termwrite((\"‡\"):rep(scr_x))",
4877 " elseif y == (stop or scr_y) then",
4878 " termsetTextColor(colors.gray)",
4879 " termsetBackgroundColor(colors.lightGray)",
4880 " termwrite((\"‡\"):rep(scr_x))",
4881 " else",
4882 " termclearLine()",
4883 " end",
4884 " end",
4885 " else",
4886 " termclear()",
4887 " end",
4888 "end",
4889 "",
4890 "local cwrite = function(text, y)",
4891 " local cx, cy = termgetCursorPos()",
4892 " termsetCursorPos((scr_x/2) - math.ceil(#text/2), y or cy)",
4893 " return write(text)",
4894 "end",
4895 "",
4896 "local prettyCenterWrite = function(text, y)",
4897 " local words = explode(\" \", text, nil, true)",
4898 " local buff = \"\"",
4899 " local lines = 0",
4900 " for w = 1, #words do",
4901 " if #buff + #words[w] > scr_x then",
4902 " cwrite(buff, y + lines)",
4903 " buff = \"\"",
4904 " lines = lines + 1",
4905 " end",
4906 " buff = buff..words[w]",
4907 " end",
4908 " cwrite(buff, y + lines)",
4909 " return lines",
4910 "end",
4911 "",
4912 "local prettyPrompt = function(prompt, y, replchar, doColor)",
4913 " local cy, cx = termgetCursorPos()",
4914 " termsetBackgroundColor(colors.gray)",
4915 " termsetTextColor(colors.white)",
4916 " local yadj = 1 + prettyCenterWrite(prompt, y or cy)",
4917 " termsetCursorPos(1, y + yadj)",
4918 " termsetBackgroundColor(colors.lightGray)",
4919 " termclearLine()",
4920 " local output",
4921 " if doColor then",
4922 " output = colorRead()",
4923 " else",
4924 " output = read(replchar)",
4925 " end",
4926 " return output",
4927 "end",
4928 "",
4929 "local fwrite = function(text)",
4930 " local b = textToBlit(text)",
4931 " return termblit(unpack(b))",
4932 "end",
4933 "",
4934 "local cfwrite = function(text, y)",
4935 " local cx, cy = termgetCursorPos()",
4936 " termsetCursorPos((scr_x/2) - math.ceil(#textToBlit(text,true)/2), y or cy)",
4937 " return fwrite(text)",
4938 "end",
4939 "",
4940 "if not checkValidName(yourName) then -- not so fast, evildoers",
4941 " yourName = nil",
4942 "end",
4943 "",
4944 "local currentY = 2",
4945 "",
4946 "if not (yourName and encKey) then",
4947 " prettyClearScreen()",
4948 "end",
4949 "",
4950 "if not yourName then",
4951 " cfwrite(\"&8~7Text = &, Background = ~\", scr_y-3)",
4952 " cfwrite(\"&8~7&{Krazy = &k, Reset = &r\", scr_y-2)",
4953 " cfwrite(\"&7~00~11~22~33~44~55~66&8~77&7~88~99~aa~bb~cc~dd~ee~ff\", scr_y-1)",
4954 " yourName = prettyPrompt(\"Enter your name.\", currentY, nil, true)",
4955 " if not checkValidName(yourName) then",
4956 " while true do",
4957 " yourName = prettyPrompt(\"That name isn't valid. Enter another.\", currentY, nil, true)",
4958 " if checkValidName(yourName) then",
4959 " break",
4960 " end",
4961 " end",
4962 " end",
4963 " currentY = currentY + 3",
4964 "end",
4965 "",
4966 "if not encKey then",
4967 " setEncKey(prettyPrompt(\"Enter an encryption key.\", currentY, \"*\"))",
4968 " currentY = currentY + 3",
4969 "end",
4970 "",
4971 "-- prevent terminating. It is reversed upon exit.",
4972 "local oldePullEvent = os.pullEvent",
4973 "os.pullEvent = os.pullEventRaw",
4974 "",
4975 "local bottomMessage = function(text)",
4976 " termsetCursorPos(1,scr_y)",
4977 " termsetTextColor(colors.gray)",
4978 " termclearLine()",
4979 " termwrite(text)",
4980 "end",
4981 "",
4982 "loadSettings()",
4983 "saveSettings()",
4984 "",
4985 "termsetBackgroundColor(colors.black)",
4986 "termclear()",
4987 "",
4988 "local getAPI = function(apiname, apipath, apiurl, doDoFile, doScroll)",
4989 " apipath = fs.combine(fs.combine(enchat.dataDir,\"api\"), apipath)",
4990 " if (not fs.exists(apipath)) then",
4991 " if doScroll then term.scroll(1) end",
4992 " bottomMessage(apiname .. \" API not found! Downloading...\")",
4993 " local prog = http.get(apiurl)",
4994 " if not prog then",
4995 " if doScroll then term.scroll(1) end",
4996 " bottomMessage(\"Failed to download \" .. apiname .. \" API. Abort.\")",
4997 " termsetCursorPos(1,1)",
4998 " return",
4999 " end",
5000 " local file = fs.open(apipath,\"w\")",
5001 " file.write(prog.readAll())",
5002 " file.close()",
5003 " end",
5004 " if doDoFile then",
5005 " return dofile(apipath)",
5006 " else",
5007 " os.loadAPI(apipath)",
5008 " end",
5009 " if not _ENV[fs.getName(apipath)] then",
5010 " if doScroll then term.scroll(1) end",
5011 " bottomMessage(\"Failed to load \" .. apiname .. \" API. Abort.\")",
5012 " termsetCursorPos(1,1)",
5013 " return",
5014 " else",
5015 " return _ENV[fs.getName(apipath)]",
5016 " end",
5017 "end",
5018 "",
5019 "local skynet, aes, bigfont",
5020 "_G.skynet_CBOR_path = fs.combine(enchat.dataDir,\"/api/cbor\")",
5021 "aes = getAPI(\"AES\", \"aes\", \"http://pastebin.com/raw/9E5UHiqv\", false, false)",
5022 "skynet = getAPI(\"Skynet\", \"skynet\", \"https://raw.githubusercontent.com/osmarks/skynet/master/client.lua\", true, true)",
5023 "bigfont = getAPI(\"BigFont\", \"bigfont\", \"https://pastebin.com/raw/3LfWxRWh\", false, true)",
5024 "",
5025 "if encKey and skynet then",
5026 " bottomMessage(\"Connecting to Skynet...\")",
5027 " local success = parallel.waitForAny(",
5028 " function()",
5029 " skynet.open(enchat.skynetPort)",
5030 " end,",
5031 " function()",
5032 " sleep(5)",
5033 " end",
5034 " )",
5035 " if success == 2 then",
5036 " bottomMessage(\"Failed to connect to skynet.\")",
5037 " skynet = nil",
5038 " end",
5039 "end",
5040 "",
5041 "local log = {} -- Records all sorts of data on text.",
5042 "local renderlog = {} -- Only records straight terminal output. Generated from 'log'",
5043 "local IDlog = {} -- Really only used with skynet, will prevent duplicate messages.",
5044 "",
5045 "local scroll = 0",
5046 "local maxScroll = 0",
5047 "",
5048 "local getModem = function()",
5049 " if enchat.ignoreModem then",
5050 " return nil",
5051 " else",
5052 " local modems = {peripheral.find(\"modem\")}",
5053 " return modems[1]",
5054 " end",
5055 "end",
5056 "",
5057 "local getChatbox = function()",
5058 " if enchat.useChatbox then",
5059 " if commands then -- oh baby command computer",
5060 " return {",
5061 " say = function(text)",
5062 " commands.tellraw(\"@a\", textToBlit(text, false, \"0\", \"f\", nil, true))",
5063 " end,",
5064 " tell = function(player, text)",
5065 " commands.tellraw(player, textToBlit(text, false, \"0\", \"f\", nil, true))",
5066 " end",
5067 " }",
5068 " else",
5069 " local cb = peripheral.find(\"chat_box\")",
5070 " if cb then",
5071 " if cb.setName then -- Computronics",
5072 " cb.setName(yourName)",
5073 " return {",
5074 " say = cb.say,",
5075 " tell = cb.say -- why is there no tell command???",
5076 " }",
5077 " else -- whatever whackjob mod SwitchCraft uses I forget",
5078 " return {",
5079 " say = function(text, block)",
5080 " if CHATBOX_SAFEMODE then",
5081 "-- if CHATBOX_SAFEMODE ~= block then",
5082 " cb.tell(CHATBOX_SAFEMODE, text)",
5083 "-- end",
5084 " else",
5085 " local players = cb.getPlayerList()",
5086 " for i = 1, #players do",
5087 " if players[i] ~= block then",
5088 " cb.tell(players[i], text)",
5089 " end",
5090 " end",
5091 " end",
5092 " end,",
5093 " tell = cb.tell",
5094 " }",
5095 " end",
5096 " else",
5097 " return nil",
5098 " end",
5099 " end",
5100 " else",
5101 " return nil",
5102 " end",
5103 "end",
5104 "",
5105 "local modem = getModem()",
5106 "local chatbox = getChatbox()",
5107 "",
5108 "if (not modem) and (not enchat.ignoreModem) then",
5109 " if ccemux and (not enchat.ignoreModem) then",
5110 " ccemux.attach(\"top\",\"wireless_modem\")",
5111 " modem = getModem()",
5112 " elseif not skynet then",
5113 " error(\"You should get a modem.\")",
5114 " end",
5115 "end",
5116 "",
5117 "if modem then modem.open(enchat.port) end",
5118 "",
5119 "local modemTransmit = function(freq, repfreq, message)",
5120 " if modem then",
5121 " modem.transmit(freq, repfreq, message)",
5122 " end",
5123 "end",
5124 "",
5125 "local encrite = function(input) -- standardized encryption function",
5126 " if not input then return input end",
5127 " return aes.encrypt(encKey, textutilsserialize(input))",
5128 "end",
5129 "",
5130 "local decrite = function(input) -- redundant comments cause tuberculosis",
5131 " if not input then return input end",
5132 " return textutilsunserialize(aes.decrypt(encKey, input) or \"\")",
5133 "end",
5134 "",
5135 "local dab = function(func, ...) -- \"do and back\", not...never mind",
5136 " local x, y = termgetCursorPos()",
5137 " local b, t = termgetBackgroundColor(), termgetTextColor()",
5138 " local output = {func(...)}",
5139 " termsetCursorPos(x,y)",
5140 " termsetTextColor(t)",
5141 " termsetBackgroundColor(b)",
5142 " return unpack(output)",
5143 "end",
5144 "",
5145 "local splitStr = function(str, maxLength)",
5146 " local output = {}",
5147 " for l = 1, #str, maxLength do",
5148 " output[#output+1] = str:sub(l,l+maxLength+-1)",
5149 " end",
5150 " return output",
5151 "end",
5152 "",
5153 "local splitStrTbl = function(tbl, maxLength)",
5154 " local output, tline = {}",
5155 " for w = 1, #tbl do",
5156 " tline = splitStr(tbl[w], maxLength)",
5157 " for t = 1, #tline do",
5158 " output[#output+1] = tline[t]",
5159 " end",
5160 " end",
5161 " return output",
5162 "end",
5163 "",
5164 "local blitWrap = function(char, text, back, noWrite) -- where ALL of the onscreen wrapping is done",
5165 " local cWords = splitStrTbl(explode(\" \",char,nil, true), scr_x)",
5166 " local tWords = splitStrTbl(explode(\" \",char,text,true), scr_x)",
5167 " local bWords = splitStrTbl(explode(\" \",char,back,true), scr_x)",
5168 "",
5169 " local ox,oy = termgetCursorPos()",
5170 " local cx,cy,ty = ox,oy,1",
5171 " local output = {}",
5172 " local length = 0",
5173 " local maxLength = 0",
5174 " for a = 1, #cWords do",
5175 " length = length + #cWords[a]",
5176 " maxLength = mathmax(maxLength, length)",
5177 " if ((cx + #cWords[a]) > scr_x) then",
5178 " cx = 1",
5179 " length = 0",
5180 " if (cy == scr_y) then",
5181 " term.scroll(1)",
5182 " end",
5183 " cy = mathmin(cy+1, scr_y)",
5184 " ty = ty + 1",
5185 " end",
5186 " if not noWrite then",
5187 " termsetCursorPos(cx,cy)",
5188 " termblit(cWords[a],tWords[a],bWords[a])",
5189 " end",
5190 " cx = cx + #cWords[a]",
5191 " output[ty] = output[ty] or {\"\",\"\",\"\"}",
5192 " output[ty][1] = output[ty][1]..cWords[a]",
5193 " output[ty][2] = output[ty][2]..tWords[a]",
5194 " output[ty][3] = output[ty][3]..bWords[a]",
5195 " end",
5196 " return output, maxLength",
5197 "end",
5198 "",
5199 "local pictochat = function(xsize, ysize)",
5200 " local output = {{},{},{}}",
5201 " local maxWidth, minMargin = 0, math.huge",
5202 " for y = 1, ysize do",
5203 " output[1][y] = {}",
5204 " output[2][y] = {}",
5205 " output[3][y] = {}",
5206 " for x = 1, xsize do",
5207 " output[1][y][x] = \" \"",
5208 " output[2][y][x] = \" \"",
5209 " output[3][y][x] = \" \"",
5210 " end",
5211 " end",
5212 "",
5213 " termsetBackgroundColor(colors.gray)",
5214 " termsetTextColor(colors.black)",
5215 " for y = 1, scr_y do",
5216 " termsetCursorPos(1, y)",
5217 " termwrite((\"/\"):rep(scr_x))",
5218 " end",
5219 " cwrite(\" [ENTER] to finish. \", scr_y)",
5220 " cwrite(\"Push a key to change char.\", scr_y-1)",
5221 "",
5222 " local cx, cy = math.floor((scr_x/2)-(xsize/2)), math.floor((scr_y/2)-(ysize/2))",
5223 "",
5224 " local allCols = \"0123456789abcdef\"",
5225 " local tPos, bPos = 16, 1",
5226 " local char, text, back = \" \", allCols:sub(tPos,tPos), allCols:sub(bPos,bPos)",
5227 "",
5228 " local render = function()",
5229 " termsetTextColor(colors.white)",
5230 " termsetBackgroundColor(colors.black)",
5231 " local mx, my",
5232 " for y = 1, ysize do",
5233 " for x = 1, xsize do",
5234 " mx, my = x+cx+-1, y+cy+-1",
5235 " termsetCursorPos(mx,my)",
5236 " termblit(output[1][y][x], output[2][y][x], output[3][y][x])",
5237 " end",
5238 " end",
5239 " termsetCursorPos((scr_x/2)-5,ysize+cy+1)",
5240 " termwrite(\"Char = '\")",
5241 " termblit(char, text, back)",
5242 " termwrite(\"'\")",
5243 " end",
5244 " local evt, butt, mx, my",
5245 " local isShiftDown = false",
5246 "",
5247 " render()",
5248 "",
5249 " while true do",
5250 " evt = {os.pullEvent()}",
5251 " if evt[1] == \"mouse_click\" or evt[1] == \"mouse_drag\" then",
5252 " butt, mx, my = evt[2], evt[3]-cx+1, evt[4]-cy+1",
5253 " if mx >= 1 and mx <= xsize and my >= 1 and my <= ysize then",
5254 " if butt == 1 then",
5255 " output[1][my][mx] = char",
5256 " output[2][my][mx] = text",
5257 " output[3][my][mx] = back",
5258 " elseif butt == 2 then",
5259 " output[1][my][mx] = \" \"",
5260 " output[2][my][mx] = \" \"",
5261 " output[3][my][mx] = \" \"",
5262 " end",
5263 " render()",
5264 " end",
5265 " elseif evt[1] == \"mouse_scroll\" then",
5266 " local oldTpos, oldBpos = tPos, bPos",
5267 " if isShiftDown then",
5268 " tPos = mathmax(1, mathmin(16, tPos + evt[2]))",
5269 " else",
5270 " bPos = mathmax(1, mathmin(16, bPos + evt[2]))",
5271 " end",
5272 " text, back = stringsub(allCols,tPos,tPos), stringsub(allCols,bPos,bPos)",
5273 " if oldTpos ~= tPos or oldBpos ~= bPos then",
5274 " render()",
5275 " end",
5276 " elseif evt[1] == \"key\" then",
5277 " if evt[2] == keys.enter then",
5278 " for y = 1, ysize do",
5279 " output[1][y] = table.concat(output[1][y])",
5280 " output[2][y] = table.concat(output[2][y])",
5281 " output[3][y] = table.concat(output[3][y])",
5282 " maxWidth = math.max(maxWidth, #stringgsub(output[3][y], \" +$\", \"\"))",
5283 " minMargin = math.min(minMargin, output[3][y]:find(\"[^ ]\") or math.huge)",
5284 " end",
5285 " --error(minMargin)",
5286 " local croppedOutput = {}",
5287 " local touched = false",
5288 " local crY = 0",
5289 " for a = 1, ysize do",
5290 " if output[1][1] == (\" \"):rep(xsize) and output[3][1] == (\" \"):rep(xsize) then",
5291 " tableremove(output[1],1)",
5292 " tableremove(output[2],1)",
5293 " tableremove(output[3],1)",
5294 " else",
5295 " for y = #output[1], 1, -1 do",
5296 " if output[1][y] == (\" \"):rep(xsize) and output[3][y] == (\" \"):rep(xsize) then",
5297 " tableremove(output[1],y)",
5298 " tableremove(output[2],y)",
5299 " tableremove(output[3],y)",
5300 " else",
5301 " break",
5302 " end",
5303 " end",
5304 " break",
5305 " end",
5306 " end",
5307 " for y = 1, #output[1] do",
5308 " output[1][y] = output[1][y]:sub(minMargin, maxWidth)",
5309 " output[2][y] = output[2][y]:sub(minMargin, maxWidth)",
5310 " output[3][y] = output[3][y]:sub(minMargin, maxWidth)",
5311 " end",
5312 " return output",
5313 " elseif evt[2] == keys.leftShift then",
5314 " isShiftDown = true",
5315 " elseif evt[2] == keys.left or evt[2] == keys.right then",
5316 " local oldTpos, oldBpos = tPos, bPos",
5317 " if isShiftDown then",
5318 " tPos = mathmax(1, mathmin(16, tPos + (evt[2] == keys.right and 1 or -1)))",
5319 " else",
5320 " bPos = mathmax(1, mathmin(16, bPos + (evt[2] == keys.right and 1 or -1)))",
5321 " end",
5322 " text, back = allCols:sub(tPos,tPos), allCols:sub(bPos,bPos)",
5323 " if oldTpos ~= tPos or oldBpos ~= bPos then",
5324 " render()",
5325 " end",
5326 " end",
5327 " elseif evt[1] == \"key_up\" then",
5328 " if evt[2] == keys.leftShift then",
5329 " isShiftDown = false",
5330 " end",
5331 " elseif evt[1] == \"char\" then",
5332 " if char ~= evt[2] then",
5333 " char = evt[2]",
5334 " render()",
5335 " end",
5336 " end",
5337 " end",
5338 "end",
5339 "",
5340 "local notif = {}",
5341 "notif.alpha = 248",
5342 "notif.height = 10",
5343 "notif.width = 6",
5344 "notif.time = 40",
5345 "notif.wrapX = 350",
5346 "notif.maxNotifs = 15",
5347 "local nList = {}",
5348 "local colorTranslate = {",
5349 " [\" \"] = {240, 240, 240},",
5350 " [\"0\"] = {240, 240, 240},",
5351 " [\"1\"] = {242, 178, 51 },",
5352 " [\"2\"] = {229, 127, 216},",
5353 " [\"3\"] = {153, 178, 242},",
5354 " [\"4\"] = {222, 222, 108},",
5355 " [\"5\"] = {127, 204, 25 },",
5356 " [\"6\"] = {242, 178, 204},",
5357 " [\"7\"] = {76, 76, 76 },",
5358 " [\"8\"] = {153, 153, 153},",
5359 " [\"9\"] = {76, 153, 178},",
5360 " [\"a\"] = {178, 102, 229},",
5361 " [\"b\"] = {51, 102, 204},",
5362 " [\"c\"] = {127, 102, 76 },",
5363 " [\"d\"] = {87, 166, 78 },",
5364 " [\"e\"] = {204, 76, 76 },",
5365 " [\"f\"] = {25, 25, 25 }",
5366 "}",
5367 "local interface, canvas = peripheral.find(\"neuralInterface\")",
5368 "if interface then",
5369 " if interface.canvas then",
5370 " canvas = interface.canvas()",
5371 " notif.newNotification = function(char, text, back, time)",
5372 " if #nList > notif.maxNotifs then",
5373 " tableremove(nList, 1)",
5374 " end",
5375 " nList[#nList+1] = {char,text,back,time,1} -- the last one is the alpha multiplier",
5376 " end",
5377 " notif.displayNotifications = function(doCountDown)",
5378 " local adjList = {",
5379 " [\"i\"] = -4,",
5380 " [\"l\"] = -3,",
5381 " [\"I\"] = -1,",
5382 " [\"t\"] = -2,",
5383 " [\"k\"] = -1,",
5384 " [\"!\"] = -4,",
5385 " [\"|\"] = -4,",
5386 " [\".\"] = -4,",
5387 " [\",\"] = -4,",
5388 " [\":\"] = -4,",
5389 " [\";\"] = -4,",
5390 " [\"f\"] = -1,",
5391 " [\"'\"] = -3,",
5392 " [\"\\\"\"] = -1,",
5393 " [\"<\"] = -1,",
5394 " [\">\"] = -1,",
5395 " }",
5396 " local drawEdgeLine = function(y,alpha)",
5397 " local l = canvas.addRectangle(notif.wrapX, 1+(y-1)*notif.height, 1, notif.height)",
5398 " l.setColor(unpack(colorTranslate[\"0\"]))",
5399 " l.setAlpha(alpha / 2)",
5400 " end",
5401 " local getWordWidth = function(str)",
5402 " local output = 0",
5403 " for a = 1, #str do",
5404 " output = output + notif.width + (adjList[stringsub(str,a,a)] or 0)",
5405 " end",
5406 " return output",
5407 " end",
5408 " canvas.clear()",
5409 " local xadj, charadj, wordadj, t, r",
5410 " local x, y, words, txtwords, bgwords = 0, 0",
5411 " for n = 1, mathmin(#nList, notif.maxNotifs) do",
5412 " xadj, charadj = 0, 0",
5413 " y = y + 1",
5414 " x = 0",
5415 " words = explode(\" \",nList[n][1],nil,true)",
5416 " txtwords = explode(\" \",nList[n][1],nList[n][2],true)",
5417 " bgwords = explode(\" \",nList[n][1],nList[n][3],true)",
5418 " local char, text, back",
5419 " local currentX = 0",
5420 " for w = 1, #words do",
5421 " char = words[w]",
5422 " text = txtwords[w]",
5423 " back = bgwords[w]",
5424 " if currentX + getWordWidth(char) > notif.wrapX then",
5425 " y = y + 1",
5426 " x = 2",
5427 " xadj = 0",
5428 " currentX = x * notif.width",
5429 " end",
5430 " for cx = 1, #char do",
5431 " x = x + 1",
5432 " charadj = (adjList[stringsub(char,cx,cx)] or 0)",
5433 " r = canvas.addRectangle(xadj+1+(x-1)*notif.width, 1+(y-1)*notif.height, charadj+notif.width, notif.height)",
5434 " if stringsub(back,cx,cx) ~= \" \" then",
5435 " r.setAlpha(notif.alpha * nList[n][5])",
5436 " r.setColor(unpack(colorTranslate[stringsub(back,cx,cx)]))",
5437 " else",
5438 " r.setAlpha(100 * nList[n][5])",
5439 " r.setColor(unpack(colorTranslate[\"7\"]))",
5440 " end",
5441 " drawEdgeLine(y,notif.alpha * nList[n][5])",
5442 " t = canvas.addText({xadj+1+(x-1)*notif.width,2+(y-1)*notif.height}, stringsub(char,cx,cx))",
5443 " t.setAlpha(notif.alpha * nList[n][5])",
5444 " t.setColor(unpack(colorTranslate[stringsub(text,cx,cx)]))",
5445 " xadj = xadj + charadj",
5446 " currentX = currentX + charadj+notif.width",
5447 " end",
5448 " end",
5449 " end",
5450 " for n = mathmin(#nList, notif.maxNotifs), 1, -1 do",
5451 " if doCountDown then",
5452 " if nList[n][4] > 1 then",
5453 " nList[n][4] = nList[n][4] - 1",
5454 " else",
5455 " if nList[n][5] > 0 then",
5456 " while true do",
5457 " nList[n][5] = mathmax(nList[n][5] - 0.2, 0)",
5458 " notif.displayNotifications(false)",
5459 " if nList[n][5] == 0 then break else sleep(0.05) end",
5460 " end",
5461 " end",
5462 " tableremove(nList,n)",
5463 " end",
5464 " end",
5465 " end",
5466 " end",
5467 " end",
5468 "end",
5469 "",
5470 "local darkerCols = {",
5471 " [\"0\"] = \"8\",",
5472 " [\"1\"] = \"c\",",
5473 " [\"2\"] = \"a\",",
5474 " [\"3\"] = \"b\",",
5475 " [\"4\"] = \"1\",",
5476 " [\"5\"] = \"d\",",
5477 " [\"6\"] = \"2\",",
5478 " [\"7\"] = \"f\",",
5479 " [\"8\"] = \"7\",",
5480 " [\"9\"] = \"b\",",
5481 " [\"a\"] = \"7\",",
5482 " [\"b\"] = \"7\",",
5483 " [\"c\"] = \"f\",",
5484 " [\"d\"] = \"7\",",
5485 " [\"e\"] = \"7\",",
5486 " [\"f\"] = \"f\"",
5487 "}",
5488 "",
5489 "local animations = {",
5490 " slideFromLeft = function(char, text, back, frame, maxFrame, length)",
5491 " return {",
5492 " stringsub(char, (length or #char) - ((frame/maxFrame)*(length or #char))),",
5493 " stringsub(text, (length or #text) - ((frame/maxFrame)*(length or #text))),",
5494 " stringsub(back, (length or #back) - ((frame/maxFrame)*(length or #back)))",
5495 " }",
5496 " end,",
5497 " fadeIn = function(char, text, back, frame, maxFrame, length)",
5498 " -- a good example:",
5499 " -- &1what &2in &3the &4world &5are &6you &7doing &8in &9my &aswamp",
5500 " for i = 1, 3 - math.ceil(frame/maxFrame * 3) do",
5501 " text = stringgsub(text, \".\", darkerCols)",
5502 " end",
5503 " return {",
5504 " char,",
5505 " text,",
5506 " back",
5507 " }",
5508 " end,",
5509 " flash = function(char, text, back, frame, maxFrame, length)",
5510 " local t = palette.txt",
5511 " if frame ~= maxFrame then",
5512 " t = (frame % 2 == 0) and t or palette.bg",
5513 " end",
5514 " return {",
5515 " char,",
5516 " toblit[t]:rep(#text),",
5517 " (frame % 2 == 0) and back or (\" \"):rep(#back)",
5518 " }",
5519 " end,",
5520 " none = function(char, text, back, frame, maxFrame, length)",
5521 " return {",
5522 " char,",
5523 " text,",
5524 " back",
5525 " }",
5526 " end",
5527 "}",
5528 "",
5529 "local inAnimate = function(animType, buff, frame, maxFrame, length)",
5530 " local char, text, back = buff[1], buff[2], buff[3]",
5531 " if enchatSettings.doAnimate and (frame >= 0) and (maxFrame > 0) then",
5532 " return animations[animType or \"slideFromleft\"](char, text, back, frame, maxFrame, length)",
5533 " else",
5534 " return {char,text,back}",
5535 " end",
5536 "end",
5537 "",
5538 "local genRenderLog = function()",
5539 " local buff, prebuff, maxLength",
5540 " local scrollToBottom = scroll == maxScroll",
5541 " renderlog = {}",
5542 " for a = 1, #log do",
5543 " termsetCursorPos(1,1)",
5544 " if UIconf.nameDecolor then",
5545 " local dcName = textToBlit(table.concat({log[a].prefix,log[a].name,log[a].suffix}), true, toblit[palette.txt], toblit[palette.bg])",
5546 " local dcMessage = textToBlit(log[a].message, false, toblit[palette.txt], toblit[palette.bg])",
5547 " prebuff = {",
5548 " dcName..dcMessage[1],",
5549 " toblit[palette.chevron]:rep(#dcName)..dcMessage[2],",
5550 " toblit[palette.bg]:rep(#dcName)..dcMessage[3]",
5551 " }",
5552 " else",
5553 " prebuff = textToBlit(table.concat(",
5554 " {log[a].prefix, \"&}&r~r\", log[a].name, \"&}&r~r\", log[a].suffix, \"&}&r~r\", log[a].message}",
5555 " ), false, toblit[palette.txt], toblit[palette.bg])",
5556 " end",
5557 " if (log[a].frame == 0) and (canvas and enchatSettings.doNotif) then",
5558 " if not (log[a].name == \"\" and log[a].message == \" \") then",
5559 " notif.newNotification(prebuff[1],prebuff[2],prebuff[3],notif.time * 4)",
5560 " end",
5561 " end",
5562 " if log[a].maxFrame == true then",
5563 " log[a].maxFrame = math.floor(mathmin(#prebuff[1], scr_x) / enchatSettings.animDiv)",
5564 " end",
5565 " if log[a].ignoreWrap then",
5566 " buff, maxLength = {prebuff}, mathmin(#prebuff[1], scr_x)",
5567 " else",
5568 " buff, maxLength = blitWrap(prebuff[1], prebuff[2], prebuff[3], true)",
5569 " end",
5570 " -- repeat every line in multiline entries",
5571 " for l = 1, #buff do",
5572 " -- holy shit, two animations, lookit mr. roxas over here",
5573 " if log[a].animType then",
5574 " renderlog[#renderlog + 1] = inAnimate(log[a].animType, buff[l], log[a].frame, log[a].maxFrame, maxLength)",
5575 " else",
5576 " renderlog[#renderlog + 1] = inAnimate(\"fadeIn\", inAnimate(\"slideFromLeft\", buff[l], log[a].frame, log[a].maxFrame, maxLength), log[a].frame, log[a].maxFrame, maxLength)",
5577 " end",
5578 " end",
5579 " if (log[a].frame < log[a].maxFrame) and log[a].frame >= 0 then",
5580 " log[a].frame = log[a].frame + 1",
5581 " else",
5582 " log[a].frame = -1",
5583 " end",
5584 " end",
5585 " maxScroll = mathmax(0, #renderlog - (scr_y - 2))",
5586 " if scrollToBottom then",
5587 " scroll = maxScroll",
5588 " end",
5589 "end",
5590 "",
5591 "local tsv = function(visible)",
5592 " if term.current().setVisible and enchatSettings.useSetVisible then",
5593 " return term.current().setVisible(visible)",
5594 " end",
5595 "end",
5596 "",
5597 "local renderChat = function(doScrollBackUp)",
5598 " tsv(false)",
5599 " termsetCursorBlink(false)",
5600 " genRenderLog(log)",
5601 " local ry",
5602 " termsetBackgroundColor(palette.bg)",
5603 " for y = UIconf.chatlogTop, (scr_y-UIconf.promptY) - 1 do",
5604 " ry = (y + scroll - (UIconf.chatlogTop - 1))",
5605 " termsetCursorPos(1,y)",
5606 " termclearLine()",
5607 " if renderlog[ry] then",
5608 " termblit(unpack(renderlog[ry]))",
5609 " end",
5610 " end",
5611 " if UIconf.promptY ~= 0 then",
5612 " termsetCursorPos(1,scr_y)",
5613 " termsetTextColor(palette.scrollMeter)",
5614 " termclearLine()",
5615 " termwrite(scroll..\" / \"..maxScroll..\" \")",
5616 " end",
5617 "",
5618 " local _title = UIconf.title:gsub(\"YOURNAME\", yourName..\"&}&r~r\"):gsub(\"ENCKEY\", encKey..\"&}&r~r\"):gsub(\"PORT\", tostring(enchat.port))",
5619 " if UIconf.doTitle then",
5620 " termsetTextColor(palette.title)",
5621 " term.setBackgroundColor(palette.titlebg)",
5622 " if UIconf.nameDecolor then",
5623 " if UIconf.centerTitle then",
5624 " cwrite((\" \"):rep(scr_x)..textToBlit(_title, true)..(\" \"):rep(scr_x), UIconf.titleY or 1)",
5625 " else",
5626 " termsetCursorPos(1, UIconf.titleY or 1)",
5627 " termwrite(textToBlit(_title, true)..(\" \"):rep(scr_x))",
5628 " end",
5629 " else",
5630 " local blTitle = textToBlit(_title)",
5631 " termsetCursorPos(UIconf.centerTitle and ((scr_x/2) - math.ceil(#blTitle[1]/2)) or 1, UIconf.titleY or 1)",
5632 " termclearLine()",
5633 " termblit(unpack(blTitle))",
5634 " end",
5635 " end",
5636 " termsetCursorBlink(true)",
5637 " tsv(true)",
5638 "end",
5639 "",
5640 "local logadd = function(name, message, animType, maxFrame, ignoreWrap)",
5641 " log[#log + 1] = {",
5642 " prefix = name and UIconf.prefix or \"\",",
5643 " suffix = name and UIconf.suffix or \"\",",
5644 " name = name or \"\",",
5645 " message = message or \" \",",
5646 " ignoreWrap = ignoreWrap,",
5647 " frame = 0,",
5648 " maxFrame = maxFrame or true,",
5649 " animType = animType",
5650 " }",
5651 "end",
5652 "",
5653 "local logaddTable = function(name, message, animType, maxFrame, ignoreWrap)",
5654 " if type(message) == \"table\" and type(name) == \"string\" then",
5655 " if #message > 0 then",
5656 " local isGood = true",
5657 " for l = 1, #message do",
5658 " if type(message[l]) ~= \"string\" then",
5659 " isGood = false",
5660 " break",
5661 " end",
5662 " end",
5663 " if isGood then",
5664 " logadd(name,message[1],animType,maxFrame,ignoreWrap)",
5665 " for l = 2, #message do",
5666 " logadd(nil,message[l],animType,maxFrame,ignoreWrap)",
5667 " end",
5668 " end",
5669 " end",
5670 " end",
5671 "end",
5672 "",
5673 "local makeRandomString = function(length)",
5674 " local output = \"\"",
5675 " for a = 1, length do",
5676 " output = output .. string.char(math.random(1,255))",
5677 " end",
5678 " return output",
5679 "end",
5680 "",
5681 "local enchatSend = function(name, message, doLog, animType, maxFrame, crying, recipient, ignoreWrap)",
5682 " if doLog then",
5683 " if type(message) == \"string\" then",
5684 " logadd(name, message, animType, maxFrame, ignoreWrap)",
5685 " else",
5686 " logaddTable(name, message, animType, maxFrame, ignoreWrap)",
5687 " end",
5688 " end",
5689 " local messageID = makeRandomString(64)",
5690 " local outmsg = encrite({",
5691 " name = name,",
5692 " message = message,",
5693 " animType = animType,",
5694 " maxFrame = maxFrame,",
5695 " messageID = messageID,",
5696 " recipient = recipient,",
5697 " ignoreWrap = ignoreWrap,",
5698 " cry = crying",
5699 " })",
5700 " IDlog[messageID] = true",
5701 " if not enchat.ignoreModem then modemTransmit(enchat.port, enchat.port, outmsg) end",
5702 " if skynet and enchatSettings.useSkynet then",
5703 " skynet.send(enchat.skynetPort, outmsg)",
5704 " end",
5705 "end",
5706 "",
5707 "local cryOut = function(name, crying)",
5708 " enchatSend(name, nil, false, nil, nil, crying)",
5709 "end",
5710 "",
5711 "local getPictureFile = function(path) -- ONLY NFP or NFT, fuck BLT",
5712 " if not fs.exists(path) then",
5713 " return false, \"No such image.\"",
5714 " else",
5715 " local file = fs.open(path,\"r\")",
5716 " local content = file.readAll()",
5717 " file.close()",
5718 " local output",
5719 " if content:find(\"\\31\") and content:find(\"\\30\") then",
5720 " output = explode(\"\\n\",content:gsub(\"\\31\",\"&\"):gsub(\"\\30\",\"~\"),nil,false)",
5721 " else",
5722 " if content:lower():gsub(\"[0123456789abcdef\\n ]\",\"\") ~= \"\" then",
5723 " return false, \"Invalid image.\"",
5724 " else",
5725 " output = explode(\"\\n\",content:gsub(\"[^\\n]\",\"~%1 \"),nil,false)",
5726 " end",
5727 " end",
5728 " return output",
5729 " end",
5730 "end",
5731 "",
5732 "local getTableLength = function(tbl)",
5733 " local output = 0",
5734 " for k,v in pairs(tbl) do",
5735 " output = output + 1",
5736 " end",
5737 " return output",
5738 "end",
5739 "",
5740 "local userCryList = {}",
5741 "",
5742 "local commandInit = \"/\"",
5743 "local commands = {}",
5744 "-- Commands only have one argument, being a single string.",
5745 "-- Separate arguments can be extrapolated with the explode() function.",
5746 "commands.about = function()",
5747 " if enchatSettings.extraNewline then",
5748 " logadd(nil,nil)",
5749 " end",
5750 " logadd(nil,\"Enchat \"..enchat.version..\" by LDDestroier.\")",
5751 " logadd(nil,\"'Encrypted, decentralized, &1c&2o&3l&4o&5r&6i&7z&8e&9d&r chat program'\")",
5752 " logadd(nil,\"Made in 2018, out of gum and procrastination.\")",
5753 " logadd(nil,nil)",
5754 " logadd(nil,\"AES Lua implementation made by SquidDev.\")",
5755 " logadd(nil,\"'Skynet' (enables HTTP chat) belongs to gollark (osmarks).\")",
5756 "end",
5757 "commands.exit = function()",
5758 " enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' buggered off. (disconnect)\")",
5759 " return \"exit\"",
5760 "end",
5761 "commands.me = function(msg)",
5762 " if enchatSettings.extraNewline then",
5763 " logadd(nil,nil)",
5764 " end",
5765 " if msg then",
5766 " enchatSend(\"&2*\", yourName..\"~r&2 \"..msg, true)",
5767 " else",
5768 " logadd(\"*\",commandInit..\"me [message]\")",
5769 " end",
5770 "end",
5771 "commands.tron = function()",
5772 " local url = \"https://raw.githubusercontent.com/LDDestroier/CC/master/tron.lua\"",
5773 " local prog, contents = http.get(url)",
5774 " if prog then",
5775 " enchatSend(\"*\", yourName .. \"&}&r~r has started a game of TRON.\")",
5776 " contents = prog.readAll()",
5777 " pauseRendering = true",
5778 " prog = load(contents, nil, nil, _ENV)(enchatSettings.useSkynet and \"skynet\", \"quick\", yourName)",
5779 " else",
5780 " logadd(\"*\",\"Could not download TRON.\")",
5781 " end",
5782 " pauseRendering = false",
5783 " doRender = true",
5784 "end",
5785 "commands.colors = function()",
5786 " if enchatSettings.extraNewline then",
5787 " logadd(nil,nil)",
5788 " end",
5789 " logadd(\"*\", \"&{Color codes: (use & or ~)&}\")",
5790 " logadd(nil, \" &7~11~22~33~44~55~66~7&87~8&78~99~aa~bb~cc~dd~ee~ff\")",
5791 " logadd(nil, \" &{Reset text/BG with &r and ~r.&}\")",
5792 " logadd(nil, \" &{Use &k for krazy text.&}\")",
5793 "end",
5794 "commands.update = function()",
5795 " local res, message = updateEnchat()",
5796 " if res then",
5797 " enchatSend(\"*\",yourName..\"&}&r~r has updated and exited.\")",
5798 " termsetBackgroundColor(colors.black)",
5799 " termsetTextColor(colors.white)",
5800 " termclear()",
5801 " termsetCursorPos(1,1)",
5802 " print(message)",
5803 " return \"exit\"",
5804 " else",
5805 " logadd(\"*\", res)",
5806 " end",
5807 "end",
5808 "commands.picto = function(filename)",
5809 " local image, output, res",
5810 " local isEmpty",
5811 " if filename then",
5812 " output, res = getPictureFile(filename)",
5813 " if not output then",
5814 " logadd(\"*\",res)",
5815 " logadd(nil,nil)",
5816 " return",
5817 " else",
5818 " tableinsert(output,1,\"\")",
5819 " end",
5820 " else",
5821 " isEmpty = true",
5822 " output = {\"\"}",
5823 " pauseRendering = true",
5824 " local image = pictochat(26,11)",
5825 " pauseRendering = false",
5826 " for y = 1, #image[1] do",
5827 " output[#output+1] = \"\"",
5828 " for x = 1, #image[1][1] do",
5829 " output[#output] = table.concat({",
5830 " output[#output],",
5831 " \"&\",",
5832 " image[2][y]:sub(x,x),",
5833 " \"~\",",
5834 " image[3][y]:sub(x,x),",
5835 " image[1][y]:sub(x,x)",
5836 " })",
5837 " isEmpty = isEmpty and (image[1][y]:sub(x,x) == \" \" and image[3][y]:sub(x,x) == \" \")",
5838 " end",
5839 " end",
5840 " end",
5841 " if not isEmpty then",
5842 " enchatSend(yourName,output,true,\"slideFromLeft\",nil,nil,nil,true)",
5843 " end",
5844 "end",
5845 "commands.list = function()",
5846 " userCryList = {}",
5847 " local tim = os.startTimer(0.5)",
5848 " cryOut(yourName, true)",
5849 " while true do",
5850 " local evt = {os.pullEvent()}",
5851 " if evt[1] == \"timer\" then",
5852 " if evt[2] == tim then",
5853 " break",
5854 " end",
5855 " end",
5856 " end",
5857 " if enchatSettings.extraNewline then",
5858 " logadd(nil,nil)",
5859 " end",
5860 " if getTableLength(userCryList) == 0 then",
5861 " logadd(nil,\"Nobody's there.\")",
5862 " else",
5863 " for k,v in pairs(userCryList) do",
5864 " logadd(nil,\"+'\"..k..\"'\")",
5865 " end",
5866 " end",
5867 "end",
5868 "commands.nick = function(newName)",
5869 " if enchatSettings.extraNewline then",
5870 " logadd(nil,nil)",
5871 " end",
5872 " if newName then",
5873 " if checkValidName(newName) then",
5874 " if newName == yourName then",
5875 " logadd(\"*\",\"But you're already called that!\")",
5876 " else",
5877 " enchatSend(\"*\",\"'\"..yourName..\"&}&r~r' is now known as '\"..newName..\"&}&r~r'.\", true)",
5878 " yourName = newName",
5879 " end",
5880 " else",
5881 " if #newName < 2 then",
5882 " logadd(\"*\",\"That name is too damned small.\")",
5883 " elseif #newName > 32 then",
5884 " logadd(\"*\",\"Woah there, that name is too large.\")",
5885 " end",
5886 " end",
5887 " else",
5888 " logadd(\"*\",commandInit..\"nick [newName]\")",
5889 " end",
5890 "end",
5891 "commands.whoami = function(now)",
5892 " if enchatSettings.extraNewline then",
5893 " logadd(nil,nil)",
5894 " end",
5895 " if now == \"now\" then",
5896 " logadd(\"*\",\"You are still '\"..yourName..\"&}&r~r'!\")",
5897 " else",
5898 " logadd(\"*\",\"You are '\"..yourName..\"&}&r~r'!\")",
5899 " end",
5900 "end",
5901 "commands.key = function(newKey)",
5902 " if enchatSettings.extraNewline then",
5903 " logadd(nil,nil)",
5904 " end",
5905 " if newKey then",
5906 " if newKey ~= encKey then",
5907 " enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' buggered off. (keychange)\", false)",
5908 " setEncKey(newKey)",
5909 " logadd(\"*\", \"Key changed to '\"..encKey..\"&}&r~r'.\")",
5910 " enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' has moseyed on over.\", false)",
5911 " else",
5912 " logadd(\"*\", \"That's already the key, though.\")",
5913 " end",
5914 " else",
5915 " logadd(\"*\",\"Key = '\"..encKey..\"&}&r~r'\")",
5916 " logadd(\"*\",\"Channel = '\"..enchat.port..\"'\")",
5917 " end",
5918 "end",
5919 "commands.shrug = function(face)",
5920 " if enchatSettings.extraNewline then",
5921 " logadd(nil,nil)",
5922 " end",
5923 " enchatSend(yourName, \"¯\\\\_\"..(face and (\"(\"..face..\")\") or \"\\2\")..\"_/¯\", true)",
5924 "end",
5925 "commands.asay = function(_argument)",
5926 " local sPoint = (_argument or \"\"):find(\" \")",
5927 " if enchatSettings.extraNewline then",
5928 " logadd(nil,nil)",
5929 " end",
5930 " if not sPoint then",
5931 " logadd(\"*\",\"Animation types:\")",
5932 " for k,v in pairs(animations) do",
5933 " logadd(nil,\" '\"..k..\"'\")",
5934 " end",
5935 " else",
5936 " local animType = _argument:sub(1,sPoint-1)",
5937 " local message = _argument:sub(sPoint+1)",
5938 " local animFrameMod = {",
5939 " flash = 8,",
5940 " fadeIn = 4,",
5941 " }",
5942 " if animations[animType] then",
5943 " if textToBlit(message,true):gsub(\" \",\"\") ~= \"\" then",
5944 " enchatSend(yourName, message, true, animType, animFrameMod[animType])",
5945 " else",
5946 " logadd(\"*\",\"That message is no good.\")",
5947 " end",
5948 " else",
5949 " logadd(\"*\",\"Invalid animation type.\")",
5950 " end",
5951 " end",
5952 "end",
5953 "commands.big = function(_argument)",
5954 " local sPoint = (_argument or \"\"):find(\" \")",
5955 " if enchatSettings.extraNewline then",
5956 " logadd(nil,nil)",
5957 " end",
5958 " if not sPoint then",
5959 " logadd(\"*\",commandInit .. \"big <size> <text>\")",
5960 " else",
5961 " local fontSize = tonumber(_argument:sub(1,sPoint-1))",
5962 " local message = _argument:sub(sPoint+1)",
5963 " if not fontSize then",
5964 " logadd(\"*\",\"Size must be number between 1 and 3.\")",
5965 " elseif fontSize < 0 or fontSize > 3 then",
5966 " logadd(\"*\",\"Size must be number between 1 and 3.\")",
5967 " else",
5968 " fontSize = math.floor(.5+fontSize)",
5969 " local tOutput",
5970 " if fontSize > 0 then",
5971 " message = textToBlit(message, false, \"0\", \"f\")",
5972 " local output = {{},{},{}}",
5973 " local x, y = 1, 1",
5974 " local char",
5975 " for i = 1, #message[1] do",
5976 " char = bigfont.makeBlittleText(",
5977 " fontSize,",
5978 " stringsub(message[1],i,i),",
5979 " stringsub(message[2],i,i),",
5980 " stringsub(message[3],i,i)",
5981 " )",
5982 " x = x + char.width",
5983 " if x >= scr_x then",
5984 " y = y + char.height",
5985 " x = char.width",
5986 " end",
5987 " for charY = 1, char.height do",
5988 " output[1][y+charY-1] = (output[1][y+charY-1] or \" \") .. char[1][charY]",
5989 " output[2][y+charY-1] = (output[2][y+charY-1] or \" \") .. char[2][charY]",
5990 " output[3][y+charY-1] = (output[3][y+charY-1] or \" \") .. char[3][charY]",
5991 " end",
5992 " end",
5993 " tOutput = {\"\"}",
5994 " for y = 1, #output[1] do",
5995 " tOutput[#tOutput+1] = \"\"",
5996 " for x = 1, #output[1][y] do",
5997 " tOutput[#tOutput] = table.concat({tOutput[#tOutput],\"&\",output[2][y]:sub(x,x),\"~\",output[3][y]:sub(x,x),output[1][y]:sub(x,x)})",
5998 " end",
5999 " end",
6000 " else",
6001 " tOutput = message",
6002 " end",
6003 " enchatSend(yourName, tOutput, true)",
6004 " end",
6005 " end",
6006 "end",
6007 "commands.msg = function(_argument)",
6008 " local sPoint = (_argument or \"\"):find(\" \")",
6009 " if enchatSettings.extraNewline then",
6010 " logadd(nil,nil)",
6011 " end",
6012 " if not sPoint then",
6013 " logadd(\"*\",commandInit..\"msg <recipient> <message>\")",
6014 " else",
6015 " local recipient = _argument:sub(1,sPoint-1)",
6016 " local message = _argument:sub(sPoint+1)",
6017 " if not message then",
6018 " logadd(\"*\",\"You got half of the arguments down pat, at least.\")",
6019 " else",
6020 " if textToBlit(message,true):gsub(\" \",\"\") == \"\" then",
6021 " logadd(\"*\",\"That message is no good.\")",
6022 " else",
6023 " enchatSend(yourName, message, false, nil, nil, false, recipient)",
6024 " logadd(\"*\",\"to '\"..recipient..\"': \"..message)",
6025 " end",
6026 " end",
6027 " end",
6028 "end",
6029 "commands.palette = function(_argument)",
6030 " local argument = _argument or \"\"",
6031 " if enchatSettings.extraNewline then",
6032 " logadd(nil,nil)",
6033 " end",
6034 " if argument:gsub(\"%s\",\"\") == \"\" then",
6035 " local buff = \"\"",
6036 " for k,v in pairs(palette) do",
6037 " buff = buff..k..\", \"",
6038 " end",
6039 " buff = buff:sub(1,-3)",
6040 " logadd(\"*\",commandInit..\"palette \"..buff..\" <colorcode>\")",
6041 " else",
6042 " argument = explode(\" \",argument)",
6043 " if #argument == 1 then",
6044 " if argument[1]:gsub(\"%s\",\"\"):lower() == \"reset\" or argument[1]:gsub(\"%s\",\"\"):lower() == \"enchat3\" then",
6045 " palette = {",
6046 " bg = colors.black,",
6047 " txt = colors.white,",
6048 " promptbg = colors.gray,",
6049 " prompttxt = colors.white,",
6050 " scrollMeter = colors.lightGray,",
6051 " chevron = colors.black,",
6052 " title = colors.lightGray,",
6053 " titlebg = colors.lightGray,",
6054 " }",
6055 " UIconf = {",
6056 " promptY = 1,",
6057 " chevron = \">\",",
6058 " chatlogTop = 1,",
6059 " title = \"\",",
6060 " doTitle = false,",
6061 " titleY = 1,",
6062 " nameDecolor = false,",
6063 " centerTitle = false,",
6064 " prefix = \"<\",",
6065 " suffix = \"> \"",
6066 " }",
6067 " termsetBackgroundColor(palette.bg)",
6068 " termclear()",
6069 " logadd(\"*\",\"You cleansed your palette.\")",
6070 " saveSettings()",
6071 " elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"enchat2\" then",
6072 " palette = {",
6073 " bg = colors.gray,",
6074 " txt = colors.white,",
6075 " promptbg = colors.white,",
6076 " prompttxt = colors.black,",
6077 " scrollMeter = colors.white,",
6078 " chevron = colors.lightGray,",
6079 " title = colors.lightGray,",
6080 " titlebg = colors.lightGray,",
6081 " }",
6082 " UIconf = {",
6083 " promptY = 1,",
6084 " chevron = \">\",",
6085 " chatlogTop = 1,",
6086 " title = \"\",",
6087 " doTitle = false,",
6088 " titleY = 1,",
6089 " nameDecolor = false,",
6090 " centerTitle = false,",
6091 " prefix = \"<\",",
6092 " suffix = \"> \"",
6093 " }",
6094 " termsetBackgroundColor(palette.bg)",
6095 " termclear()",
6096 " logadd(\"*\",\"Switched to the old Enchat2 palette.\")",
6097 " saveSettings()",
6098 " elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"enchat1\" then",
6099 " logadd(\"*\",\"We don't talk about that one.\")",
6100 " elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"chat.lua\" then",
6101 " palette = {",
6102 " bg = colors.black,",
6103 " txt = colors.white,",
6104 " promptbg = colors.black,",
6105 " prompttxt = colors.white,",
6106 " scrollMeter = colors.white,",
6107 " chevron = colors.yellow,",
6108 " title = colors.yellow,",
6109 " titlebg = colors.black,",
6110 " }",
6111 " UIconf = {",
6112 " promptY = 0,",
6113 " chevron = \": \",",
6114 " chatlogTop = 2,",
6115 " title = \"YOURNAME on ENCKEY\",",
6116 " doTitle = true,",
6117 " titleY = 1,",
6118 " nameDecolor = true,",
6119 " centerTitle = true,",
6120 " prefix = \"<\",",
6121 " suffix = \"> \"",
6122 " }",
6123 " termsetBackgroundColor(palette.bg)",
6124 " termclear()",
6125 " logadd(\"*\",\"Switched to /rom/programs/rednet/chat.lua palette.\")",
6126 " saveSettings()",
6127 " elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"talk\" then",
6128 " palette = {",
6129 " bg = colors.black,",
6130 " txt = colors.white,",
6131 " promptbg = colors.black,",
6132 " prompttxt = colors.white,",
6133 " scrollMeter = colors.white,",
6134 " chevron = colors.white,",
6135 " title = colors.black,",
6136 " titlebg = colors.white,",
6137 " }",
6138 " UIconf = {",
6139 " promptY = 0,",
6140 " chevron = \"\",",
6141 " chatlogTop = 1,",
6142 " title = \" enchat v3.0 channel: ENCKEY:PORT\",",
6143 " titleY = scr_y - 1,",
6144 " doTitle = true,",
6145 " nameDecolor = false,",
6146 " centerTitle = false,",
6147 " prefix = \"<\",",
6148 " suffix = \"> \"",
6149 " }",
6150 " termsetBackgroundColor(palette.bg)",
6151 " termclear()",
6152 " logadd(\"*\",\"Switched to Talk palette.\")",
6153 " saveSettings()",
6154 " elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"darkchat\" then",
6155 " palette = {",
6156 " bg = colors.black,",
6157 " txt = colors.white,",
6158 " promptbg = colors.black,",
6159 " prompttxt = colors.white,",
6160 " scrollMeter = colors.white,",
6161 " chevron = colors.white,",
6162 " title = colors.white,",
6163 " titlebg = colors.blue,",
6164 " }",
6165 " UIconf = {",
6166 " promptY = 0,",
6167 " chevron = \"Message: \",",
6168 " chatlogTop = 1,",
6169 " title = \"<User: YOURNAME> <Channel: ENCKEY>\",",
6170 " titleY = scr_y - 1,",
6171 " doTitle = true,",
6172 " nameDecolor = false,",
6173 " centerTitle = true,",
6174 " prefix = \"\",",
6175 " suffix = \": \"",
6176 " }",
6177 " termsetBackgroundColor(palette.bg)",
6178 " termclear()",
6179 " logadd(\"*\",\"Switched to DarkChat palette.\")",
6180 " saveSettings()",
6181 " else",
6182 " if not palette[argument[1]] then",
6183 " logadd(\"*\",\"There's no such palette option.\")",
6184 " else",
6185 " logadd(\"*\",\"'\"..argument[1]..\"' = '\"..toblit[palette[argument[1]]]..\"'\")",
6186 " end",
6187 " end",
6188 " else",
6189 " if #argument > 2 then",
6190 " argument = {argument[1], table.concat(argument,\" \",2)}",
6191 " end",
6192 " argument[1] = argument[1]:lower()",
6193 " local newcol = argument[2]:lower()",
6194 " if not palette[argument[1]] then",
6195 " logadd(\"*\",\"That's not a valid palette choice.\")",
6196 " else",
6197 " if not (tocolors[newcol] or colors_strnames[newcol]) then",
6198 " logadd(\"*\",\"That isn't a valid color code. (0-f)\")",
6199 " else",
6200 " palette[argument[1]] = (tocolors[newcol] or colors_strnames[newcol])",
6201 " logadd(\"*\",\"Palette changed.\",false)",
6202 " saveSettings()",
6203 " end",
6204 " end",
6205 " end",
6206 " end",
6207 "end",
6208 "commands.clear = function()",
6209 " log = {}",
6210 " IDlog = {}",
6211 "end",
6212 "commands.ping = function(pong)",
6213 " if enchatSettings.extraNewline then",
6214 " logadd(nil,nil)",
6215 " end",
6216 " logadd(nil, pong or \"Pong!\")",
6217 "end",
6218 "commands.set = function(_argument)",
6219 " if enchatSettings.extraNewline then",
6220 " logadd(nil,nil)",
6221 " end",
6222 " argument = _argument or \"\"",
6223 " local collist = {",
6224 " [\"string\"] = function() return \"0\" end,",
6225 " [\"table\"] = function() return \"5\" end,",
6226 " [\"number\"] = function() return \"0\" end,",
6227 " [\"boolean\"] = function(val) if val then return \"d\" else return \"e\" end end,",
6228 " [\"function\"] = function() return \"c\" end,",
6229 " [\"nil\"] = function() return \"8\" end,",
6230 " [\"thread\"] = function() return \"d\" end,",
6231 " [\"userdata\"] = function() return \"c\" end, -- ha",
6232 " }",
6233 " local custColorize = function(input)",
6234 " return \"&\"..collist[type(input)](input)",
6235 " end",
6236 " local contextualQuote = function(judgetxt,txt)",
6237 " if type(judgetxt) == \"string\" then",
6238 " return table.concat({\"'\",txt,\"'\"})",
6239 " else",
6240 " return txt",
6241 " end",
6242 " end",
6243 " local arguments = explode(\" \",argument)",
6244 " if #argument == 0 then",
6245 " for k,v in pairs(enchatSettings) do",
6246 " logadd(nil,\"&4'\"..k..\"'&r = \"..contextualQuote(v,custColorize(v)..tostring(v)..\"&r\"))",
6247 " end",
6248 " else",
6249 " if enchatSettings[arguments[1]] ~= nil then",
6250 " if #arguments >= 2 then",
6251 " local newval = table.concat(arguments,\" \",2)",
6252 " if tonumber(newval) then",
6253 " newval = tonumber(newval)",
6254 " elseif textutilsunserialize(newval) ~= nil then",
6255 " newval = textutilsunserialize(newval)",
6256 " end",
6257 " if type(enchatSettings[arguments[1]]) == type(newval) then",
6258 " enchatSettings[arguments[1]] = newval",
6259 " logadd(\"*\",\"Set '&4\"..arguments[1]..\"&r' to &{\"..contextualQuote(newval,textutilsserialize(newval)..\"&}\")..\" (\"..type(newval)..\")\")",
6260 " saveSettings()",
6261 " else",
6262 " logadd(\"*\",\"Wrong value type (it's \"..type(enchatSettings[arguments[1]])..\")\")",
6263 " end",
6264 " else",
6265 " logadd(\"*\",\"'\"..arguments[1]..\"' is set to \"..contextualQuote(enchatSettings[arguments[1]],custColorize(enchatSettings[arguments[1]])..textutilsserialize(enchatSettings[arguments[1]])..\"&r\")..\" (\"..type(enchatSettings[arguments[1]])..\")\")",
6266 " end",
6267 " else",
6268 " logadd(\"*\",\"No such setting.\")",
6269 " end",
6270 " end",
6271 " if enchatSettings.useSkynet and (not skynet) then",
6272 " pauseRendering = true",
6273 " termsetBackgroundColor(colors.black)",
6274 " termclear()",
6275 " downloadSkynet()",
6276 " pauseRendering = false",
6277 " end",
6278 "end",
6279 "commands.help = function(cmdname)",
6280 " if enchatSettings.extraNewline then",
6281 " logadd(nil,nil)",
6282 " end",
6283 " if cmdname then",
6284 " local helpList = {",
6285 " exit = \"Exits Enchat and returns to loader (most likely CraftOS)\",",
6286 " about = \"Tells you a bit about this here Enchat.\",",
6287 " me = \"Sends a message in the format of \\\"* yourName message\\\"\",",
6288 " colors = \"Lists all the colors you can use.\",",
6289 " update = \"Updates and overwrites Enchat, then exits if successful.\",",
6290 " list = \"Lists all users in range using the same key.\",",
6291 " nick = \"Give yourself a different username.\",",
6292 " whoami = \"Tells you your current username.\",",
6293 " key = \"Change the current encryption key. Tells you the key, if without argument.\",",
6294 " clear = \"Clears the local chat log. Not your inventory, I swear.\",",
6295 " ping = \"Pong. *sigh*\",",
6296 " shrug = \"Sends out a shrugging emoticon.\",",
6297 " set = \"Changes config options during the current session. Lists all options, if without argument.\",",
6298 " msg = \"Sends a message that is only logged by a specific user.\",",
6299 " picto = \"Opens an image maker and sends the result. Use the scroll wheel to change color, and hold left shift to change text color. If argument given, will look for an image at the given path and use that instead.\",",
6300 " tron = \"Starts up a game of TRON.\",",
6301 " big = \"Sends your message, but enlarged by a specified amount via Wojbie's BigFont API.\",",
6302 " help = \"Shows every command, or describes a specific command.\",",
6303 " }",
6304 " cmdname = cmdname:gsub(\" \",\"\"):gsub(\"/\",\"\")",
6305 " if helpList[cmdname] then",
6306 " logadd(\"*\", helpList[cmdname])",
6307 " else",
6308 " if commands[cmdname] then",
6309 " logadd(\"*\", \"No help info for that command.\")",
6310 " else",
6311 " logadd(\"*\", \"No such command to get help for.\")",
6312 " end",
6313 " end",
6314 " else",
6315 " logadd(\"*\",\"All commands:\")",
6316 " local output = \"\"",
6317 " for k,v in pairs(commands) do",
6318 " output = output..\" \"..commandInit..k..\",\"",
6319 " end",
6320 " logadd(nil, output:sub(1,-2))",
6321 " end",
6322 "end",
6323 "commandAliases = {",
6324 " quit = commands.exit,",
6325 " colours = commands.colors,",
6326 " ls = commands.list,",
6327 " cry = commands.list,",
6328 " nickname = commands.nick,",
6329 " channel = commands.key,",
6330 " palate = commands.palette,",
6331 " tell = commands.msg,",
6332 " whisper = commands.msg,",
6333 " [\"?\"] = commands.help,",
6334 " porn = function() logadd(\"*\",\"Yeah, no.\") end,",
6335 " whoareyou = function() logadd(\"*\", \"I'm Enchat. But surely, you know this?\") end,",
6336 " fuck = function() logadd(\"*\",\"A mind is a terrible thing to waste.\") end,",
6337 " hello = function() logadd(\"*\",\"Hey.\") end,",
6338 " hi = function() logadd(\"*\",\"Hiya.\") end,",
6339 " hey = function() logadd(\"*\",\"That's for horses.\") end,",
6340 " bye = function() logadd(\"*\",\"You know, you can use /exit.\") end,",
6341 " die = function() logadd(\"*\",\"You wish.\") end,",
6342 " nap = function() logadd(\"*\",\"The time for napping has passed.\") end,",
6343 " sorry = function() logadd(\"*\",\"That's okay.\") end,",
6344 " jump = function() logadd(\"*\",\"Sorry. This program is in a NO JUMPING zone.\") end,",
6345 " enchat = function() logadd(\"*\",\"At your service!\") end,",
6346 " win = function() logadd(\"*\",\"Naturally!\") end,",
6347 " lose = function() logadd(\"*\",\"Preposterous!\") end,",
6348 " xyzzy = function() logadd(\"*\",\"A hollow voice says \\\"Fool.\\\"\") end,",
6349 " wait = function() logadd(\"*\",\"Time passes...\") end,",
6350 " stop = function() logadd(\"*\",\"Hammertime!\",\"fadeIn\") end,",
6351 " shit = function() logadd(\"*\",\"Man, you're telling me!\") end,",
6352 " eat = function() logadd(\"*\",\"You're not hungry.\") end,",
6353 " what = function() logadd(\"*\",\"What indeed.\") end,",
6354 " ldd = function() logadd(nil,\"& that's me\") end,",
6355 " OrElseYouWill = function()",
6356 " enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' buggered off. (disconnect)\")",
6357 " error(\"DIE\")",
6358 " end",
6359 "}",
6360 "",
6361 "local checkIfCommand = function(input)",
6362 " if input:sub(1,#commandInit) == commandInit then",
6363 " return true",
6364 " else",
6365 " return false",
6366 " end",
6367 "end",
6368 "",
6369 "local parseCommand = function(input)",
6370 " local sPos1, sPos2 = input:find(\" \")",
6371 " local cmdName, cmdArgs",
6372 " if sPos1 then",
6373 " cmdName = input:sub(#commandInit+1, sPos1-1)",
6374 " cmdArgs = input:sub(sPos2+1)",
6375 " else",
6376 " cmdName = input:sub(#commandInit+1)",
6377 " cmdArgs = nil",
6378 " end",
6379 "",
6380 " local res",
6381 " local CMD = commands[cmdName] or commandAliases[cmdName]",
6382 " if CMD then",
6383 " res = CMD(cmdArgs)",
6384 " if res == \"exit\" then",
6385 " return \"exit\"",
6386 " end",
6387 " else",
6388 " logadd(\"*\", \"No such command.\")",
6389 " end",
6390 "end",
6391 "",
6392 "local main = function()",
6393 " termsetBackgroundColor(palette.bg)",
6394 " termclear()",
6395 " os.queueEvent(\"render_enchat\")",
6396 " local mHistory = {}",
6397 "",
6398 " while true do",
6399 "",
6400 " termsetCursorPos(1, scr_y-UIconf.promptY)",
6401 " termsetBackgroundColor(palette.promptbg)",
6402 " termclearLine()",
6403 " termsetTextColor(palette.chevron)",
6404 " termwrite(UIconf.chevron)",
6405 " termsetTextColor(palette.prompttxt)",
6406 "",
6407 " local input = colorRead(nil, mHistory)",
6408 " if textToBlit(input,true):gsub(\" \",\"\") ~= \"\" then -- people who send blank messages in chat programs deserve to die",
6409 " if checkIfCommand(input) then",
6410 " local res = parseCommand(input)",
6411 " if res == \"exit\" then",
6412 " return \"exit\"",
6413 " end",
6414 " else",
6415 " if enchatSettings.extraNewline then",
6416 " logadd(nil,nil) -- readability is key",
6417 " end",
6418 " enchatSend(yourName, input, true)",
6419 " end",
6420 " if mHistory[#mHistory] ~= input then",
6421 " mHistory[#mHistory+1] = input",
6422 " end",
6423 " elseif input == \"\" then",
6424 " logadd(nil,nil)",
6425 " end",
6426 " os.queueEvent(\"render_enchat\")",
6427 "",
6428 " end",
6429 "",
6430 "end",
6431 "",
6432 "local handleReceiveMessage = function(user, message, animType, maxFrame)",
6433 " if enchatSettings.extraNewline then",
6434 " logadd(nil,nil) -- readability is still key",
6435 " end",
6436 " logadd(user, message,animations[animType] and animType or nil,(type(maxFrame) == \"number\") and maxFrame or nil)",
6437 " os.queueEvent(\"render_enchat\")",
6438 "end",
6439 "",
6440 "local adjScroll = function(distance)",
6441 " scroll = mathmin(maxScroll, mathmax(0, scroll + distance))",
6442 "end",
6443 "",
6444 "local handleEvents = function()",
6445 " local oldScroll",
6446 " local keysDown = {}",
6447 " while true do",
6448 " local evt = {os.pullEvent()}",
6449 " if evt[1] == \"enchat_receive\" then",
6450 " if type(evt[2]) == \"string\" and type(evt[3]) == \"string\" then",
6451 " handleReceiveMessage(evt[2], evt[3])",
6452 " end",
6453 " elseif evt[1] == \"chat\" then",
6454 " if enchat.useChatbox then",
6455 " if enchatSettings.extraNewline then",
6456 " logadd(nil,nil) -- readability is key",
6457 " end",
6458 " enchatSend(evt[2], evt[3], true)",
6459 " end",
6460 " elseif evt[1] == \"chat_message\" then -- computronics",
6461 " if enchat.useChatbox then",
6462 " if enchatSettings.extraNewline then",
6463 " logadd(nil,nil) -- readability is key",
6464 " end",
6465 " enchatSend(evt[3], evt[4], true)",
6466 " end",
6467 " elseif (evt[1] == \"modem_message\") or (evt[1] == \"skynet_message\" and enchatSettings.useSkynet) then",
6468 " local side, freq, repfreq, msg, distance",
6469 " if evt[1] == \"modem_message\" then",
6470 " side, freq, repfreq, msg, distance = evt[2], evt[3], evt[4], evt[5], evt[6]",
6471 " else",
6472 " freq, msg = evt[2], evt[3]",
6473 " end",
6474 " if (freq == enchat.port) or (freq == enchat.skynetPort) then",
6475 " msg = decrite(msg)",
6476 " if type(msg) == \"table\" then",
6477 " if (type(msg.name) == \"string\") then",
6478 " if #msg.name <= 32 then",
6479 " if msg.messageID and (not IDlog[msg.messageID]) then",
6480 " userCryList[msg.name] = true",
6481 " IDlog[msg.messageID] = true",
6482 " if ((not msg.recipient) or (msg.recipient == yourName or msg.recipient == textToBlit(yourName,true))) then",
6483 " if type(msg.message) == \"string\" then",
6484 " handleReceiveMessage(msg.name, tostring(msg.message), msg.animType, msg.maxFrame, msg.ignoreWrap)",
6485 " if chatbox and enchat.useChatbox then",
6486 " chatbox.say(UIconf.prefix .. msg.name .. UIconf.suffix .. msg.message, msg.name)",
6487 " end",
6488 " elseif type(msg.message) == \"table\" and enchatSettings.acceptPictoChat and #msg.message <= 64 then",
6489 " logaddTable(msg.name, msg.message, msg.animType, msg.maxFrame, msg.ignoreWrap)",
6490 " if enchatSettings.extraNewline then",
6491 " logadd(nil,nil)",
6492 " end",
6493 " end",
6494 " end",
6495 " if (msg.cry == true) then",
6496 " cryOut(yourName, false)",
6497 " end",
6498 " end",
6499 " end",
6500 " end",
6501 " end",
6502 " end",
6503 " elseif evt[1] == \"mouse_scroll\" and (not pauseRendering) then",
6504 " local dist = evt[2]",
6505 " oldScroll = scroll",
6506 " adjScroll(enchatSettings.reverseScroll and -dist or dist)",
6507 " if scroll ~= oldScroll then",
6508 " dab(renderChat)",
6509 " end",
6510 " elseif evt[1] == \"key\" and (not pauseRendering) then",
6511 " local key = evt[2]",
6512 " keysDown[key] = true",
6513 " oldScroll = scroll",
6514 " local pageSize = (scr_y-UIconf.promptY) - UIconf.chatlogTop",
6515 " if key == keys.pageUp then",
6516 " adjScroll(-(keysDown[keys.leftCtrl] and pageSize or enchatSettings.pageKeySpeed))",
6517 " elseif key == keys.pageDown then",
6518 " adjScroll(keysDown[keys.leftCtrl] and pageSize or enchatSettings.pageKeySpeed)",
6519 " end",
6520 " if scroll ~= oldScroll then",
6521 " dab(renderChat)",
6522 " end",
6523 " elseif evt[1] == \"key_up\" then",
6524 " local key = evt[2]",
6525 " keysDown[key] = nil",
6526 " elseif (evt[1] == \"render_enchat\") and (not pauseRendering) then",
6527 " dab(renderChat)",
6528 " elseif (evt[1] == \"tron_complete\") then",
6529 " if evt[3] then",
6530 " if enchatSettings.extraNewline then",
6531 " logadd(nil,nil)",
6532 " end",
6533 " if evt[2] == \"win\" then",
6534 " enchatSend(\"*\", yourName .. \"&}&r~r beat \" .. (evt[4] or \"someone\") .. \"&}&r~r in TRON!\", true)",
6535 " elseif evt[2] == \"lose\" then",
6536 " enchatSend(\"*\", (evt[4] or \"Someone\") .. \"&}&r~r beat \" .. yourName .. \"&}&r~r in TRON!\", true)",
6537 " elseif evt[2] == \"tie\" then",
6538 " enchatSend(\"*\", yourName .. \"&}&r~r tied with \" .. (evt[4] or \"someone\") .. \"&}&r~r in TRON!\", true)",
6539 " end",
6540 " elseif evt[2] == \"timeout\" then",
6541 " if enchatSettings.extraNewline then",
6542 " logadd(nil,nil)",
6543 " end",
6544 " enchatSend(\"*\", yourName .. \"&}&r~r timed out against \" .. (evt[4] or \"someone\") .. \"&}&r~r in TRON...\", true)",
6545 " end",
6546 " elseif evt[1] == \"terminate\" then",
6547 " return \"exit\"",
6548 " end",
6549 " end",
6550 "end",
6551 "",
6552 "local keepRedrawing = function()",
6553 " while true do",
6554 " sleep(enchatSettings.redrawDelay)",
6555 " if not pauseRendering then",
6556 " os.queueEvent(\"render_enchat\")",
6557 " end",
6558 " end",
6559 "end",
6560 "",
6561 "local handleNotifications = function()",
6562 " while true do",
6563 " os.pullEvent(\"render_enchat\")",
6564 " if canvas and enchatSettings.doNotif then",
6565 " notif.displayNotifications(true)",
6566 " end",
6567 " end",
6568 "end",
6569 "",
6570 "getModem()",
6571 "",
6572 "enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' has moseyed on over.\", true)",
6573 "",
6574 "local funky = {",
6575 " main,",
6576 " handleEvents,",
6577 " keepRedrawing,",
6578 " handleNotifications",
6579 "}",
6580 "",
6581 "if skynet then",
6582 " funky[#funky+1] = function()",
6583 " while true do",
6584 " if skynet then",
6585 " pcall(skynet.listen)",
6586 " local success, msg = pcall(skynet.open, enchat.skynetPort)",
6587 " if not success then",
6588 " skynet = nil",
6589 " end",
6590 " end",
6591 " sleep(5)",
6592 " end",
6593 " end",
6594 "end",
6595 "",
6596 "pauseRendering = false",
6597 "",
6598 "local res, outcome = pcall(function()",
6599 " return parallel.waitForAny(unpack(funky))",
6600 "end)",
6601 "",
6602 "os.pullEvent = oldePullEvent",
6603 "if skynet then",
6604 " if skynet.socket then",
6605 " skynet.socket.close()",
6606 " end",
6607 "end",
6608 "",
6609 "if canvas then",
6610 " canvas.clear()",
6611 "end",
6612 "",
6613 "tsv(true) -- in case it's false, y'know",
6614 "",
6615 "if not res then",
6616 " prettyClearScreen(1,scr_y-1)",
6617 " termsetTextColor(colors.white)",
6618 " termsetBackgroundColor(colors.gray)",
6619 " cwrite(\"There was an error.\",2)",
6620 " cfwrite(\"Report this to &3@LDDestroier#2901&r\",3)",
6621 " cwrite(\"on Discord,\",4)",
6622 " cwrite(\"if you feel like it.\",5)",
6623 " termsetCursorPos(1,7)",
6624 " printError(outcome)",
6625 " termsetTextColor(colors.lightGray)",
6626 " cwrite(\"I'll probably fix it, maybe.\",10)",
6627 "end",
6628 "",
6629 "termsetCursorPos(1,scr_y)",
6630 "termsetBackgroundColor(initcolors.bg)",
6631 "termsetTextColor(initcolors.txt)",
6632 "termclearLine()",
6633 },
6634 [ "/dodge.lua" ] = {
6635 "--[[",
6636 " Wall Dodge! What a riveting game!",
6637 " Dodge the walls before they kill you.",
6638 " ",
6639 " Download with:",
6640 " pastebin get fDTts7wz dodge",
6641 " std PB fDTts7wz dodge",
6642 " std ld dodge dodge",
6643 "--]]",
6644 "",
6645 "local scr_x, scr_y = term.getSize()",
6646 "local keysDown = {} --holds all pressed keys. It's way better than using \"key\" event for movement",
6647 "local walls = {} --holds all screen data for walls. I could do slants if I wanted, not just walls",
6648 "local frame = 0 --for every screen update-oh, you know what a frame is",
6649 "local maxFrame = 26 --max frames until new wall",
6650 "local fframe = 0 --not a typo. is the buffer of spaces until the spaces between walls shrinks",
6651 "local maxFFrame = 6 --max fframes until the space between walls gets slightly tighter (down to 5, good luck m8)",
6652 "local pause = false --pausing is a nice thing",
6653 "local tsv = term.current().setVisible --it is my belief that monitors and normal computers do not have the setVisible method for term.current()",
6654 "for a = 1, scr_x do",
6655 " table.insert(walls,{top=1,bottom=scr_y,color=colors.black})",
6656 "end",
6657 "",
6658 "local score = 0 --increases for every wall.",
6659 "local time = 0 --in seconds, increases in increments of 0.1",
6660 "",
6661 "local addNewWall = function(top,bottom,color)",
6662 " table.remove(walls,1)",
6663 " table.insert(walls,{top=top,bottom=bottom,color=color})",
6664 "end",
6665 "",
6666 "local guyX = 2",
6667 "local guyY = math.floor(scr_y/2)",
6668 "",
6669 "local maxY = scr_y-1",
6670 "local minY = 2",
6671 "",
6672 "local clearLines = function(y1,y2)",
6673 " local _x,_y = term.getCursorPos()",
6674 " for a = y1, y2 or y1 do",
6675 " term.setCursorPos(1,a)",
6676 " term.clearLine()",
6677 " end",
6678 " term.setCursorPos(_x,_y)",
6679 "end",
6680 "",
6681 "local renderTEXT = function(_txt)",
6682 " local txt = _txt or \"YOU ARE DEAD\"",
6683 " local midY = math.floor(scr_y/2)",
6684 " for a = 0, 2 do",
6685 " term.setBackgroundColor(colors.gray)",
6686 " clearLines(midY-a,midY+a)",
6687 " sleep(0.1)",
6688 " end",
6689 " term.setCursorPos(4,midY)",
6690 " term.write(txt)",
6691 "end",
6692 "",
6693 "local trymove = function(dir)",
6694 " if (guyY+dir)>=minY and (guyY+dir)<=maxY then",
6695 " guyY = guyY + dir",
6696 " return true",
6697 " end",
6698 " return false",
6699 "end",
6700 "",
6701 "local render = function()",
6702 " if tsv then tsv(false) end",
6703 " term.setBackgroundColor(colors.white)",
6704 " term.setTextColor(colors.white)",
6705 " term.clear()",
6706 " term.setCursorPos(guyX,guyY)",
6707 " term.setBackgroundColor(colors.black)",
6708 " term.write(\" \")",
6709 " term.setCursorPos(1,1)",
6710 " term.clearLine()",
6711 " term.setCursorPos(1,scr_y)",
6712 " term.clearLine()",
6713 " for x = 1, #walls do",
6714 " term.setBackgroundColor(walls[x].color)",
6715 " for y = 1, walls[x].top do",
6716 " term.setCursorPos(x,y)",
6717 " term.write(\" \")",
6718 " end",
6719 " for y = walls[x].bottom, scr_y do",
6720 " term.setCursorPos(x,y)",
6721 " term.write(\" \")",
6722 " end",
6723 " end",
6724 " term.setCursorPos(2,1)",
6725 " term.setBackgroundColor(colors.black)",
6726 " term.write(\"SCORE: \"..score..\" | TIME: \"..time)",
6727 " if tsv then tsv(true) end",
6728 "end",
6729 "",
6730 "local keepTime = function()",
6731 " time = 0",
6732 " while true do",
6733 " sleep(0.1)",
6734 " if not pause then",
6735 " time = time + 0.1",
6736 " end",
6737 " end",
6738 "end",
6739 "",
6740 "local doGame = function()",
6741 " local wf = 0",
6742 " local gap = 2",
6743 " local ypos, randomcol",
6744 " while true do",
6745 " if not pause then",
6746 " if frame >= maxFrame or wf > 0 then",
6747 " if frame >= maxFrame then",
6748 " frame = 0",
6749 " fframe = fframe + 1",
6750 " ypos = math.random(4,scr_y-3)",
6751 " wf = 3",
6752 " randomcol = 2^math.random(1,14)",
6753 " end",
6754 " if wf > 0 then",
6755 " wf = wf - 1",
6756 " end",
6757 " if not term.isColor() then",
6758 " randomcol = colors.black --Shame.",
6759 " end",
6760 " addNewWall(ypos-gap,ypos+gap,randomcol)",
6761 " else",
6762 " frame = frame + 1",
6763 " addNewWall(1,scr_y,colors.black)",
6764 " end",
6765 " if fframe >= maxFFrame then",
6766 " fframe = 0",
6767 " if maxFrame > 7 then",
6768 " maxFrame = maxFrame - 1",
6769 " end",
6770 " end",
6771 " if keysDown[keys.up] then",
6772 " trymove(-1)",
6773 " end",
6774 " if keysDown[keys.down] then",
6775 " trymove(1)",
6776 " end",
6777 " if walls[guyX-1].top > 1 or walls[guyX-1].bottom < scr_y then",
6778 " if walls[guyX].top < walls[guyX-1].top or walls[guyX].bottom > walls[guyX-1].bottom then",
6779 " score = score + 1",
6780 " end",
6781 " end",
6782 " render()",
6783 " end",
6784 " sleep(0)",
6785 " if guyY<=walls[guyX].top or guyY>=walls[guyX].bottom then",
6786 " return \"dead\"",
6787 " end",
6788 " end",
6789 "end",
6790 "",
6791 "local getInput = function()",
6792 " while true do",
6793 " local evt = {os.pullEvent()}",
6794 " if evt[1] == \"key\" then",
6795 " if evt[2] == keys.q then",
6796 " return \"quit\"",
6797 " end",
6798 " if evt[2] == keys.p then",
6799 " pause = not pause",
6800 " if pause then",
6801 " local pauseMSGs = {",
6802 " \"PAUSED\",",
6803 " \"Paused. Press 'P' to resume\",",
6804 " \"The game is paused\",",
6805 " \"GAME PAUSE !\",",
6806 " \"What, gotta catch your breath??\",",
6807 " \"Paused, the game is, hmmm?\",",
6808 " \"PAUSED GAME\",",
6809 " \"GAME PAUSED\",",
6810 " \"THE GAME IS PAUSED\",",
6811 " \"THE PAUSED IS GAME\",",
6812 " \"Buh-buh-buh-BEEP\",",
6813 " \"UNPAUSE WITH 'P'\",",
6814 " \"Tip: press UP to go up\",",
6815 " \"Tip: press DOWN to go down\",",
6816 " \"Tip: read Narbonic comic, you tool\",",
6817 " \"Tip: read Skin Horse comic, you twat\",",
6818 " \"YOU HAVE NO CHANCE TO SURVIVE MAKE YOUR TIME\",",
6819 " \"-PAUSED-\",",
6820 " \"=PAUSED=\",",
6821 " \"PAISED\",",
6822 " \"THOUST GAME BE PAUSETH\",",
6823 " \"Yon game is paused. Obvious exits are 'Q', 'CTRL+T'\",",
6824 " \"Tip: don't hit the walls\",",
6825 " \"Tip: press 'P' to pause the game\",",
6826 " }",
6827 " renderTEXT(pauseMSGs[math.random(1,#pauseMSGs)])",
6828 " keysDown[keys.up] = false",
6829 " keysDown[keys.down] = false",
6830 " end",
6831 " end",
6832 " keysDown[evt[2]] = true",
6833 " end",
6834 " if evt[1] == \"key_up\" then",
6835 " keysDown[evt[2]] = false",
6836 " end",
6837 " end",
6838 "end",
6839 "",
6840 "local uut = parallel.waitForAny(getInput,doGame,keepTime)",
6841 "if uut == 2 then",
6842 " renderTEXT()",
6843 "end",
6844 "sleep(0.05)",
6845 "term.setCursorPos(1,scr_y)",
6846 "term.setBackgroundColor(colors.black)",
6847 "term.clearLine()",
6848 },
6849 [ "/breakout.lua" ] = {
6850 "--[[",
6851 " Breakout!! for CC",
6852 " By EldidiStroyrr",
6853 " get with:",
6854 " pastebin get LTRYaSKt breakout",
6855 " std pb LTRYaSKt breakout",
6856 "",
6857 " TODO",
6858 " -make cooler",
6859 "--]]",
6860 "local level = 1",
6861 "local lives = 3",
6862 "local bdepth = 5",
6863 "local y_clip = 3",
6864 "local x_clip = 5",
6865 "local paused = false",
6866 "local ballslow = 2 --divides ball speed by that",
6867 "local rigged = false",
6868 "",
6869 "local titlescreen = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,},{1,4,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,4,1,},{1,4,16384,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,16384,4,1,},{1,32768,32768,32768,16,16,32768,32768,32768,16,16,32768,32768,32768,32768,16,32768,32768,32768,32768,32768,16,32768,16,16,32768,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,2,16384,4,1,},{1,32768,16384,2,32768,32,32768,32,32,32768,32,32768,32,32,32,32,32768,32,32,32,32768,32,32768,32,32,32768,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,16,2,16384,4,1,},{1,32768,32768,32768,16,32,32768,32768,32768,8192,8192,32768,32768,8192,8192,8192,32768,32768,32768,32768,32768,8192,32768,32768,32768,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,32,16,2,16384,4,1,},{1,32768,16384,2,32768,32,32768,2048,2048,32768,2048,32768,2048,2048,2048,2048,32768,2048,2048,2048,32768,2048,32768,2048,2048,32768,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,8192,32,16,2,16384,4,1,},{1,32768,32768,32768,32768,32,32768,2048,1024,32768,1024,32768,32768,32768,32768,1024,32768,1024,1024,1024,32768,1024,32768,1024,1024,32768,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,2048,8192,32,16,2,16384,4,1,},{1,32768,32768,32768,16,32,32768,2048,1024,32768,1024,32768,32768,32768,32768,1024,32768,1024,1024,1024,32768,1024,32768,1024,1024,32768,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,2048,8192,32,16,2,16384,4,1,},{1,4,16384,2,16,32,8192,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,8192,32,16,2,16384,4,1,},{1,4,16384,2,16,32,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,32768,32768,32768,32768,32768,8192,32768,8192,8192,32768,8192,32768,32768,32768,32768,32768,8192,32768,32768,8192,32768,32768,8192,8192,32,16,2,16384,4,1,},{1,4,16384,2,16,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32768,32,32,32,32768,32,32768,32,32,32768,32,32,32,32768,32,32,32,32768,32768,32,32768,32768,32,32,32,16,2,16384,4,1,},{1,4,16384,2,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,32768,16,16,16,32768,16,32768,16,16,32768,16,16,16,32768,16,16,16,32768,32768,16,32768,32768,16,16,16,16,2,16384,4,1,},{1,4,16384,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,32768,2,2,2,32768,2,32768,2,2,32768,2,2,2,32768,2,2,2,32768,32768,2,32768,32768,2,2,2,2,2,16384,4,1,},{1,4,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,32768,32768,32768,32768,32768,16384,32768,32768,32768,32768,16384,16384,16384,32768,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,4,1,},{1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,32768,32768,32768,32768,32768,4,32768,32768,32768,32768,4,4,4,32768,4,4,4,32768,32768,4,32768,32768,4,4,4,4,4,4,4,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},}",
6870 "",
6871 "local prevColors = {",
6872 " term.getTextColor(),",
6873 " term.getBackgroundColor()",
6874 "}",
6875 "",
6876 "local scr_x, scr_y = term.getSize()",
6877 "local board = {",
6878 " length = 8,",
6879 " x = math.floor(scr_x/2),",
6880 " y = scr_y-1,",
6881 " bgcolor = colors.white,",
6882 " txtcolor = colors.white,",
6883 " char = \" \",",
6884 " dir = 0,",
6885 " canMove = true,",
6886 "}",
6887 "local ball = {",
6888 " x = math.floor(scr_x/2),",
6889 " y = scr_y-5,",
6890 " xv = 1,",
6891 " yv = -1,",
6892 " px = 1,",
6893 " py = 1,",
6894 " txtcolor = colors.white,",
6895 " bgcolor = colors.white,",
6896 " char = \"O\",",
6897 "}",
6898 "local sr = string.rep",
6899 "local remakeBricks = function(xclip,yclip,depth)",
6900 " local output, entry = {}, 0",
6901 " local blitColors = \"0123456789abcdef\"",
6902 " for a = yclip, depth do",
6903 " for b = (xclip+1), scr_x-xclip do",
6904 " entry = entry + 1",
6905 " local d = math.random(1,15)",
6906 " local c = string.sub(blitColors,d,d)",
6907 " output[entry] = {x = b, y = a, color = {c,c},char=\"L\"}",
6908 " end",
6909 " end",
6910 " return output",
6911 "end",
6912 "local cprint = function(msg,cy)",
6913 " term.setCursorPos((scr_x/2)-math.floor(#msg/2), cy or (scr_y/2))",
6914 " print(msg)",
6915 "end",
6916 "local waitForEvents = function(...)",
6917 " local targ = {...}",
6918 " while true do",
6919 " local evt = {os.pullEvent()}",
6920 " for a = 1, #targ do",
6921 " if evt[1] == targ[a] then",
6922 " return table.unpack(evt)",
6923 " end",
6924 " end",
6925 " end",
6926 "end",
6927 "local titleScreen = function()",
6928 " paintutils.drawImage(titlescreen,1,1)",
6929 " sleep(0)",
6930 " return waitForEvents(\"key\",\"mouse_click\")",
6931 "end",
6932 "local clearLines = function(startY,endY)",
6933 " local ori = {term.getCursorPos()}",
6934 " for a = startY,endY do",
6935 " term.setCursorPos(1,a)",
6936 " term.clearLine()",
6937 " end",
6938 " term.setCursorPos(table.unpack(ori))",
6939 " return",
6940 "end",
6941 "local clearDot = function(x,y)",
6942 " local pX,pY = term.getCursorPos()",
6943 " term.setCursorPos(x,y)",
6944 " term.write(\" \")",
6945 " term.setCursorPos(pX,pY)",
6946 "end",
6947 "",
6948 "local render = function(brd,blocktbl)",
6949 " term.setBackgroundColor(colors.black)",
6950 " term.setCursorPos(2,1)",
6951 " term.write(\"Lives: \"..lives)",
6952 " local lvlcount = \"Level: \"..tostring(level)",
6953 " term.setCursorPos(scr_x-#lvlcount,1)",
6954 " term.write(lvlcount)",
6955 " term.setCursorPos(brd.x,brd.y)",
6956 " term.clearLine()",
6957 " term.setTextColor(brd.txtcolor)",
6958 " term.setBackgroundColor(brd.bgcolor)",
6959 " term.write(sr(brd.char,brd.length))",
6960 " for k,v in pairs(blocktbl) do",
6961 " term.setCursorPos(v.x,v.y)",
6962 " term.blit(v.char,v.color[1],v.color[2])",
6963 " end",
6964 " term.setCursorPos(ball.px,ball.py)",
6965 " term.blit(\" \",\"f\",\"f\")",
6966 " term.setCursorPos(ball.x,ball.y)",
6967 " term.setTextColor(ball.txtcolor)",
6968 " term.setBackgroundColor(ball.bgcolor)",
6969 " term.write(ball.char)",
6970 "end",
6971 "",
6972 "local levelComplete = function()",
6973 " local txt = \"LEVEL COMPLETE!\"",
6974 " term.setTextColor(colors.gray)",
6975 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
6976 " term.write(txt)",
6977 " sleep(0.1)",
6978 " term.setTextColor(colors.lightGray)",
6979 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
6980 " term.write(txt)",
6981 " sleep(0.1)",
6982 " for a = 1, 8 do",
6983 " term.setTextColor(colors.white)",
6984 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
6985 " term.write(txt)",
6986 " sleep(0.3)",
6987 " term.setTextColor(colors.black)",
6988 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
6989 " term.write(txt)",
6990 " sleep(0.3)",
6991 " end",
6992 " sleep(0.3)",
6993 " blocks = remakeBricks(x_clip,y_clip,bdepth)",
6994 " lives = lives + 2",
6995 " level = level + 1",
6996 " board.x = math.floor((scr_x/2)-(board.length/2))",
6997 " ball.x = math.floor(scr_x/3)",
6998 " ball.y = board.y - 3",
6999 " ball.xv = 1",
7000 " ball.yv = -1",
7001 "end",
7002 "",
7003 "local checkCollision = function()",
7004 " local good = false",
7005 " for a = 1, #blocks do",
7006 " if blocks[a] then",
7007 " if blocks[a].x == ball.x + ball.xv and blocks[a].y == ball.y then",
7008 " ball.xv = -ball.xv",
7009 " clearDot(blocks[a].x,blocks[a].y)",
7010 " good = true",
7011 " end",
7012 " if blocks[a].y == ball.y + ball.yv and blocks[a].x == ball.x then",
7013 " ball.yv = -ball.yv",
7014 " clearDot(blocks[a].x,blocks[a].y)",
7015 " good = true",
7016 " end",
7017 " if good then",
7018 " table.remove(blocks,a)",
7019 " good = false",
7020 " end",
7021 " end",
7022 " end",
7023 "end",
7024 "",
7025 "local animateDeath = function()",
7026 " board.dir = 0",
7027 " local tbl = {",
7028 " {\"*\",\"7\",\"0\"},",
7029 " {\"x\",\"7\",\"8\"},",
7030 " {\"X\",\"f\",\"8\"},",
7031 " {\"X\",\"f\",\"7\"},",
7032 " }",
7033 " term.setBackgroundColor(colors.black)",
7034 " term.setCursorPos(ball.x,ball.y)",
7035 " term.write(\" \")",
7036 " term.setCursorPos(1,board.y)",
7037 " term.clearLine()",
7038 " for a = 1, #tbl do",
7039 " term.setCursorPos(board.x,board.y)",
7040 " local char,txt,bg = tbl[a][1]:rep(board.length),tbl[a][2]:rep(board.length),tbl[a][3]:rep(board.length)",
7041 " term.blit(char,txt,bg)",
7042 " sleep(0.05)",
7043 " end",
7044 " term.setCursorPos(board.x,board.y)",
7045 " term.setBackgroundColor(colors.black)",
7046 " term.clearLine()",
7047 " sleep(0.5)",
7048 " board.x = (scr_x/2)-(board.length/2)",
7049 "end",
7050 "",
7051 "local animateGameOver = function()",
7052 " board.canMove = false",
7053 " animateDeath()",
7054 " local txt = \"GAME OVER\"",
7055 " term.setTextColor(colors.white)",
7056 " term.setBackgroundColor(colors.black)",
7057 " for a = 0, scr_y/2 do",
7058 " term.clearLine()",
7059 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y-a)",
7060 " term.write(txt)",
7061 " sleep(0.1)",
7062 " end",
7063 " sleep(0.5)",
7064 " return",
7065 "end",
7066 "",
7067 "local togglePauseScreen = function(_paused)",
7068 " local txt = \"PAUSED ('P' to unpause)\"",
7069 " term.setBackgroundColor(colors.black)",
7070 " if _paused then",
7071 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
7072 " term.blit(txt,sr(\"7\",#txt),sr(\"f\",#txt))",
7073 " sleep(0.1)",
7074 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
7075 " term.blit(txt,sr(\"8\",#txt),sr(\"f\",#txt))",
7076 " sleep(0.1)",
7077 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
7078 " term.blit(txt,sr(\"0\",#txt),sr(\"f\",#txt))",
7079 " sleep(0.1)",
7080 " else",
7081 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
7082 " term.blit(txt,sr(\"8\",#txt),sr(\"f\",#txt))",
7083 " sleep(0.1)",
7084 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
7085 " term.blit(txt,sr(\"7\",#txt),sr(\"f\",#txt))",
7086 " sleep(0.1)",
7087 " term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
7088 " term.clearLine()",
7089 " end",
7090 "end",
7091 "",
7092 "local game = function()",
7093 " term.setBackgroundColor(colors.black)",
7094 " term.clear()",
7095 " blocks = remakeBricks(x_clip,y_clip,bdepth)",
7096 " local frame = 1",
7097 " while true do",
7098 " if not paused then",
7099 " ball.x = math.floor(ball.x)",
7100 " ball.y = math.floor(ball.y)",
7101 " if rigged then",
7102 " board.x = ball.x-math.floor(board.length/2)",
7103 " else",
7104 " board.x = board.x + board.dir",
7105 " end",
7106 " if frame % ballslow == 0 then",
7107 " if frame > 40000000 then",
7108 " frame = 100",
7109 " end",
7110 " if frame > 60 then",
7111 " ballslow = 1",
7112 " end",
7113 " if ball.x <= 1 or ball.x >= scr_x then",
7114 " ball.xv = ball.xv * -1",
7115 " end",
7116 " if ball.y <= 1 then",
7117 " ball.yv = -ball.yv",
7118 " elseif ball.y >= scr_y then",
7119 " if lives > 1 then",
7120 " board.canMove = false",
7121 " animateDeath()",
7122 " ball.x = scr_x/2",
7123 " ball.y = scr_y-8",
7124 " ball.xv = 1",
7125 " ball.yv = -1",
7126 " lives = lives - 1",
7127 " board.canMove = true",
7128 " else",
7129 " lives = lives - 1",
7130 " animateGameOver()",
7131 " return \"lose\"",
7132 " end",
7133 " end",
7134 " ball.px = ball.x",
7135 " ball.py = ball.y",
7136 " ball.y = math.floor(ball.y + ball.yv)",
7137 " term.setBackgroundColor(colors.black)",
7138 " checkCollision()",
7139 " ball.x = math.floor(ball.x + ball.xv)",
7140 " checkCollision()",
7141 " if #blocks == 0 then levelComplete() end",
7142 " if (ball.y+1 == board.y or ball.y == board.y) and (ball.x >= board.x and ball.x <= board.x+board.length) then",
7143 " ball.yv = -ball.yv",
7144 " if ball.x < board.x+(board.length/2)-1 then",
7145 " ball.xv = -1",
7146 " elseif ball.x > board.x+(board.length/2)+1 then",
7147 " ball.xv = 1",
7148 " end",
7149 " end",
7150 " end",
7151 " sleep(0)",
7152 " frame = frame + 1",
7153 " render(board,blocks)",
7154 " end",
7155 " sleep(0)",
7156 " end",
7157 "end",
7158 "",
7159 "local getInput = function()",
7160 " local event, key",
7161 " local downKeys = {left = false, right = false}",
7162 " while true do",
7163 " event, key, mx, my = os.pullEvent()",
7164 " if event == \"key\" then",
7165 " if board.canMove and not paused then",
7166 " if key == keys.left and board.x > 1 then",
7167 " board.dir = -1",
7168 " downKeys.left = true",
7169 " elseif key == keys.right and board.x < (scr_x+1)-board.length then",
7170 " board.dir = 1",
7171 " downKeys.right = true",
7172 " end",
7173 " else board.dir = 0 end",
7174 " if key == keys.q then return end",
7175 " if key == keys.p then",
7176 " if not paused then --this is to fix a rendering problem",
7177 " paused = true",
7178 " togglePauseScreen(true)",
7179 " else",
7180 " togglePauseScreen(false)",
7181 " paused = false",
7182 " end",
7183 " end",
7184 " elseif event == \"key_up\" then",
7185 " if key == keys.left then",
7186 " downKeys.left = false",
7187 " elseif key == keys.right then",
7188 " downKeys.right = false",
7189 " end",
7190 " if (downKeys.left == false and downKeys.right == false) or (board.x <= 1 or board.x-board.length >= scr_x) then",
7191 " board.dir = 0",
7192 " end",
7193 " elseif event == \"mouse_click\" or event == \"mouse_drag\" then",
7194 " if board.canMove and not paused then",
7195 " board.x = mx-(board.length/2)",
7196 " end",
7197 " end",
7198 " if board.x < 1 then board.x = 1 board.dir = 0",
7199 " elseif board.x > (scr_x+1)-board.length then board.x = (scr_x+1)-board.length board.dir = 0 end",
7200 " end",
7201 "end",
7202 "",
7203 "local outro = function(txtcolor,bgcolor,result)",
7204 " term.setTextColor(txtcolor)",
7205 " term.setBackgroundColor(bgcolor)",
7206 " term.clear()",
7207 " term.setCursorPos(1,1)",
7208 " print(\"Thanks for playing!\")",
7209 " return result",
7210 "end",
7211 "",
7212 "titleScreen()",
7213 "local startFuncs = {",
7214 " game,",
7215 " getInput,",
7216 "}",
7217 "parallel.waitForAny(table.unpack(startFuncs))",
7218 "outro(prevColors[1],prevColors[2])",
7219 "sleep(0)",
7220 },
7221 [ "/quickdraw.lua" ] = {
7222 "--[[",
7223 " QuickDraw!",
7224 " Can you outshoot the cowbow?",
7225 " I bet you can! It's actually really easy...",
7226 "",
7227 " pastebin get uGTzMxNL quickdraw",
7228 " std pb uGTzMxNL quickdraw",
7229 " std ld quickdraw",
7230 "--]]",
7231 "",
7232 "local difficulty = 1.2 --amount of time you have to shoot im'",
7233 "",
7234 "local isRunning = true --whether the game should loop",
7235 "local over = false --whether you or the guy is dead",
7236 "",
7237 "local wins = 0",
7238 "local losses = 0",
7239 "",
7240 "local s = {",
7241 " enemy = {",
7242 " getready = {{},{},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,4096,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,128,4096,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,128,4096,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,128,4096,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,256,4096,128,4096,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
7243 " shoot1 = {{},{},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,256,0,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
7244 " shoot2 = {{},{},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,256,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
7245 " laugh = {{},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,1,1,32768,1,1,32768,1,1,32768,32768,1,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,0,0,1,1,1,1,32768,1,1,32768,1,32768,1,1,32768,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,1,1,1,1,1,1,32768,32768,32768,32768,1,32768,32768,32768,32768,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,1,1,1,1,32768,1,1,32768,1,32768,1,1,32768,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,0,0,0,0,1,1,32768,1,1,32768,1,32768,1,1,32768,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,0,4096,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
7246 " dead = {{},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,1,1,1,32768,32768,1,1,32768,1,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,16,16,16,16,0,4096,0,1,1,1,1,32768,1,1,32768,1,32768,1,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,16,16,16,16,0,1,1,1,1,1,1,32768,32768,32768,32768,1,32768,32768,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,0,16,16,0,0,4096,0,1,1,1,1,32768,1,1,32768,1,32768,1,32768,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,0,4096,0,0,0,1,1,32768,1,1,32768,1,32768,1,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
7247 " },",
7248 " bg = {{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,1,1,1,1,8,8,8,1,1,8,8,8,8,8,8,8,8,8,8,8,8,8,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,8,16,16,8,8,8,8,8,8,},{8,8,8,1,1,1,1,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,16,16,16,16,8,8,8,8,8,},{8,8,8,1,1,1,1,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,16,16,8,8,8,8,8,8,},{8,8,8,1,1,1,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,8,8,8,1,1,8,1,1,1,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,1,1,1,8,8,8,1,1,1,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,128,128,128,128,128,128,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,128,128,128,128,128,128,128,128,128,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,},{16,16,16,16,16,128,128,128,128,128,128,128,128,128,16,16,16,16,16,16,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},{16,16,16,16,16,128,128,128,128,128,128,128,128,128,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},{16,16,16,16,16,128,128,128,128,128,128,128,128,128,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},},",
7249 "}",
7250 "_s = s",
7251 "",
7252 "local scr_x, scr_y = term.getSize()",
7253 "",
7254 "local yield = function()",
7255 " os.queueEvent(\"yield\")",
7256 " os.pullEvent(\"yield\")",
7257 "end",
7258 "",
7259 "local RPGslowprint = function(text,rate)",
7260 " local cX,cY = term.getCursorPos()",
7261 " yield()",
7262 " local uutcome = parallel.waitForAny(function()",
7263 " textutils.slowPrint(text,rate or 20)",
7264 " end, function()",
7265 " os.pullEvent(\"key\")",
7266 " end)",
7267 " if uutcome == 2 then",
7268 " term.setCursorPos(cX,cY)",
7269 " print(text)",
7270 " end",
7271 "end",
7272 "",
7273 "local displayHelp = function(cli)",
7274 " local helptext = [[",
7275 " QuickDraw by EldidiStroyrr",
7276 "",
7277 " HOW TO PLAY:",
7278 "",
7279 " 1) Click and hold on the green square for three seconds.",
7280 " 2) As soon as it says DRAW, quickly move your mouse over the guy and let go.",
7281 " 3) If you win, it'll get slightly harder",
7282 "",
7283 " Press 'Q' to quit ingame.",
7284 "]]",
7285 " if cli then",
7286 " print(helptext)",
7287 " else",
7288 " term.setBackgroundColor(colors.gray)",
7289 " term.setTextColor(colors.white)",
7290 " term.setCursorPos(1,2)",
7291 " term.clear()",
7292 " RPGslowprint(helptext,30)",
7293 " term.setCursorPos(2,scr_y-1)",
7294 " term.write(\"Press any key to continue!\")",
7295 " yield()",
7296 " os.pullEvent(\"key\")",
7297 " end",
7298 "end",
7299 "",
7300 "function mixImages( img1, img2 )",
7301 " local output = { }",
7302 " for a = 1, #img2 do",
7303 " output[ a ] = { }",
7304 " if not img1[ a ] then",
7305 " for b = 1, #img2[ a ] do",
7306 " output[ a ][ b ] = img2[ a ][ b ]",
7307 " end",
7308 " else",
7309 " for b = 1, #img2[ a ] do",
7310 " if img1[ a ][ b ] then",
7311 " if img1[ a ][ b ] ~= 0 then",
7312 " output[ a ][ b ] = img1[ a ][ b ]",
7313 " else",
7314 " output[ a ][ b ] = img2[ a ][ b ]",
7315 " end",
7316 " else",
7317 " output[ a ][ b ] = img2[ a ][ b ]",
7318 " end",
7319 " end",
7320 " end",
7321 " end",
7322 " return output",
7323 "end",
7324 "",
7325 "local function clear()",
7326 " local b,t = term.getBackgroundColor(), term.getTextColor()",
7327 " term.setBackgroundColor(colors.black)",
7328 " term.clear()",
7329 " term.setBackgroundColor(b)",
7330 "end",
7331 "",
7332 "local function cprint(txt)",
7333 " local pX, pY = term.getCursorPos()",
7334 " term.setCursorPos((scr_x/2)-math.floor(#txt/2),(scr_y/2)+4)",
7335 " term.write(txt)",
7336 " term.setCursorPos(pX,pY)",
7337 "end",
7338 "",
7339 "local gameArea, alive",
7340 "",
7341 "local function handleShooting()",
7342 " currentSprite = \"getready\"",
7343 " sleep(difficulty/4)",
7344 " paintutils.drawImage(mixImages(s.enemy.shoot1,s.bg),1,1)",
7345 " currentSprite = \"shoot1\"",
7346 " sleep(difficulty/4)",
7347 " paintutils.drawImage(mixImages(s.enemy.shoot2,s.bg),1,1)",
7348 " currentSprite = \"shoot2\"",
7349 " sleep(difficulty/2)",
7350 " os.queueEvent(\"thoseWhoDig\",false)",
7351 " return false, \"dead\"",
7352 "end",
7353 "",
7354 "function drawHitBox(color)",
7355 " paintutils.drawFilledBox(scr_x-3,scr_y-2,scr_x,scr_y,color)",
7356 " term.setBackgroundColor(colors.lightBlue)",
7357 " term.setTextColor(colors.white)",
7358 " local txt = \"YOU: \"..wins..\" / ENEMY: \"..losses",
7359 " term.setCursorPos(scr_x-(#txt+1)+1,1)",
7360 " term.write(txt)",
7361 " term.setBackgroundColor(colors.lightGray)",
7362 " term.setTextColor(colors.gray)",
7363 " local txt = \"TIME: \"..tostring(difficulty):sub(1,5)..\" SEC\"",
7364 " term.setCursorPos(2,scr_y-1)",
7365 " term.write(txt)",
7366 "end",
7367 "",
7368 "function exitGame()",
7369 " if not isRunning then",
7370 " term.setCursorPos(1,scr_y)",
7371 " term.setBackgroundColor(colors.black)",
7372 " term.write(string.rep(\" \",scr_x-4))",
7373 " term.setCursorPos(1,scr_y)",
7374 " sleep(0)",
7375 " end",
7376 " error()",
7377 "end",
7378 "",
7379 "currentSprite = \"getready\"",
7380 "",
7381 "local function countdown()",
7382 " term.setCursorPos((scr_x/2)-2,scr_y/2)",
7383 " term.setTextColor(colors.black)",
7384 " term.setBackgroundColor(colors.lightBlue)",
7385 " cprint(\"3...\")",
7386 " sleep(0.8)",
7387 " cprint(\"2...\")",
7388 " sleep(0.8)",
7389 " cprint(\"1...\")",
7390 " sleep(0.8)",
7391 " cprint(\"DRAW!\")",
7392 "end",
7393 "",
7394 "function getInput()",
7395 " alive = true",
7396 " os.pullEvent(\"getMeSomeInput\")",
7397 " while true do",
7398 " local evt",
7399 " if gameArea == \"beginning1\" then",
7400 " evt = {os.pullEvent()}",
7401 " if evt[1] == \"mouse_click\" then",
7402 " if evt[3] >= scr_x-3 and evt[4] >= scr_y-2 then",
7403 " local res = parallel.waitForAny(function()",
7404 " while true do",
7405 " local evt = {os.pullEvent()}",
7406 " if evt[1] == \"mouse_up\" or evt[1] == \"mouse_click\" then",
7407 " break",
7408 " elseif evt[1] == \"mouse_drag\" then",
7409 " if (evt[3] < scr_x-3) or (evt[4] < scr_y-2) then",
7410 " break",
7411 " end",
7412 " end",
7413 " end",
7414 " end, countdown)",
7415 " if (res == 1) and not over then",
7416 " cprint(\"FOUL!!\")",
7417 " exitGame()",
7418 " end",
7419 " os.queueEvent(\"imready\")",
7420 " parallel.waitForAny(function()",
7421 " while alive do",
7422 " evt = {os.pullEvent()}",
7423 " if evt[1] == \"mouse_up\" then",
7424 " local x,y = evt[3],evt[4]",
7425 " if _s.enemy[currentSprite][y] then",
7426 " if _s.enemy[currentSprite][y][x] then",
7427 " if _s.enemy[currentSprite][y][x] ~= 0 then",
7428 " os.queueEvent(\"thoseWhoDig\",true,x,y)",
7429 " break",
7430 " end",
7431 " end",
7432 " end",
7433 " sleep(0.2)",
7434 " elseif evt[1] == \"mouse_click\" then --yay for anticheating",
7435 " sleep(1)",
7436 " end",
7437 " end",
7438 " end, handleShooting)",
7439 " end",
7440 " elseif evt[1] == \"key\" then",
7441 " if evt[2] == keys.q then",
7442 " isRunning = false",
7443 " exitGame()",
7444 " end",
7445 " end",
7446 " end",
7447 " end",
7448 "end",
7449 "",
7450 "local flash = {",
7451 " colors.white,",
7452 " colors.lightGray,",
7453 " colors.black,",
7454 " colors.gray,",
7455 "}",
7456 "",
7457 "local tArg = {...}",
7458 "if tArg[1] == \"help\" then",
7459 " return displayHelp(true)",
7460 "end",
7461 "",
7462 "function game()",
7463 " over = false",
7464 " term.setTextColor(colors.white)",
7465 " while true do",
7466 " gameArea = \"beginning1\"",
7467 " paintutils.drawImage(mixImages(s.enemy.getready,s.bg),1,1)",
7468 " drawHitBox(colors.green)",
7469 " currentSprite = \"getready\"",
7470 " os.queueEvent(\"getMeSomeInput\")",
7471 " os.pullEvent(\"imready\")",
7472 " os.queueEvent(\"shootStart!\")",
7473 " local _,alive,x,y = os.pullEvent(\"thoseWhoDig\")",
7474 " over = true",
7475 " if not alive then",
7476 " for a = 1, #flash do",
7477 " term.setBackgroundColor(flash[a])",
7478 " term.clear()",
7479 " sleep(0.1)",
7480 " end",
7481 " losses = losses + 1",
7482 " paintutils.drawImage(mixImages(s.enemy.laugh,s.bg),1,1)",
7483 " term.setTextColor(colors.red)",
7484 " term.setBackgroundColor(colors.lightBlue)",
7485 " sleep(0.5)",
7486 " exitGame()",
7487 " else",
7488 " paintutils.drawImage(mixImages(s.enemy.dead,s.bg),1,1)",
7489 " paintutils.drawPixel(x,y,colors.red)",
7490 " sleep(0.2)",
7491 " term.setBackgroundColor(colors.lightBlue)",
7492 " term.setTextColor(colors.black)",
7493 " cprint(\"YOU WIN!\")",
7494 " wins = wins + 1",
7495 " sleep(0.8)",
7496 " difficulty = difficulty * 0.92",
7497 " exitGame()",
7498 " end",
7499 " end",
7500 "end",
7501 "",
7502 "clear()",
7503 "displayHelp(false)",
7504 "while isRunning do",
7505 " parallel.waitForAny(getInput,game)",
7506 " if isRunning then",
7507 " sleep(0.8)",
7508 " end",
7509 "end",
7510 },
7511 [ "/progdor.lua" ] = {
7512 "--[[",
7513 " PROGDOR file bundling program",
7514 "",
7515 "Download with:",
7516 " pastebin get YXx5jjMV progdor",
7517 " std ld progdor progdor",
7518 "",
7519 "This is a stable release. You fool!",
7520 "--]]",
7521 "",
7522 "local doCompress = false --even if this is false, it will decompress compressed files. nifty, huh?",
7523 "",
7524 "local doPastebin = false",
7525 "local tArg = {...}",
7526 "local input, outpath",
7527 "if tArg[1] == \"-p\" then --the p is for pastebin",
7528 " doPastebin = true",
7529 " input = tArg[2]",
7530 " outpath = tArg[3]",
7531 "else",
7532 " input = tArg[1]",
7533 " outpath = tArg[2]",
7534 "end",
7535 "",
7536 "local progdor = fs.getName(shell.getRunningProgram())",
7537 "local dir = shell.dir()",
7538 "local displayHelp = function()",
7539 " local txt = progdor..\" <input> [output]\\nCompression is \"..tostring(doCompress):upper()..\".\"",
7540 " return print(txt)",
7541 "end",
7542 "",
7543 "local yield = function()",
7544 " os.queueEvent(\"yield\")",
7545 " os.pullEvent(\"yield\")",
7546 "end",
7547 "",
7548 "-- CCA API START --",
7549 "",
7550 "local bit = bit32",
7551 "local function pack(bn1, bn2)",
7552 " return bit.band(bn1, 0xFF), bit.rshift(bn1, 8) + bit.lshift(bit.band(bn2, 0xF), 4), bit.rshift(bn2, 4)",
7553 "end",
7554 "local function upack(b1, b2, b3)",
7555 " return (b1 + bit.lshift(bit.band(b2, 0xF), 8)), (bit.lshift(b3,4) + bit.band(bit.rshift(b2, 4), 0xF))",
7556 "end",
7557 "local function createDict(bool)",
7558 " local ret = {}",
7559 " for i = 1, 255 do",
7560 " if bool then",
7561 " ret[string.char(i)] = i",
7562 " else",
7563 " ret[i] = string.char(i)",
7564 " end",
7565 " end",
7566 " if not bool then ret[256] = 256 end",
7567 " return ret",
7568 "end",
7569 "local function cp(sInput)",
7570 " local dic = createDict(true)",
7571 " local s = \"\"",
7572 " local ch",
7573 " local dlen = 256",
7574 " local result = {}",
7575 " local temp",
7576 " for i = 1, #sInput do",
7577 " if dlen == 4095 then",
7578 " result[#result + 1] = dic[s]",
7579 " result[#result + 1] = 256",
7580 " dic = createDict(true)",
7581 " dlen = 256",
7582 " s = \"\"",
7583 " end",
7584 " ch = sInput:sub(i, i)",
7585 " temp = s..ch",
7586 " if dic[temp] then",
7587 " s = temp",
7588 " else",
7589 " result[#result + 1] = dic[s]",
7590 " dlen = dlen +1",
7591 " dic[temp] = dlen ",
7592 " s = ch",
7593 " end",
7594 " end",
7595 " result[#result + 1] = dic[s]",
7596 " ",
7597 " return result",
7598 "end",
7599 "local function dc(data)",
7600 " local dic = createDict(false) ",
7601 " local entry",
7602 " local ch",
7603 " local currCode",
7604 " local result = {}",
7605 " result[#result + 1] = dic[data[1]]",
7606 " prefix = dic[data[1]]",
7607 " for i = 2, #data do",
7608 " currCode = data[i]",
7609 " if currCode == 256 then",
7610 " dic = createDict(false)",
7611 " prefix = \"\"",
7612 " else",
7613 " entry = dic[currCode]",
7614 " if entry then--exists in dictionary",
7615 " ch = entry:sub(1, 1) ",
7616 " result[#result + 1] = entry",
7617 " if prefix ~= \"\" then",
7618 " dic[#dic+1] = prefix .. ch",
7619 " end",
7620 " else ",
7621 " ch = prefix:sub(1, 1)",
7622 " result[#result + 1] = prefix..ch",
7623 " dic[#dic + 1] = prefix..ch",
7624 " end",
7625 " ",
7626 " prefix = dic[currCode]",
7627 " end",
7628 " end",
7629 " ",
7630 " return table.concat(result)",
7631 "end",
7632 "local function trim(inp)",
7633 " for i = 0,2 do",
7634 " if inp[#inp] == 0 then",
7635 " inp[#inp] = nil",
7636 " end",
7637 " end",
7638 "end",
7639 "local function decompress(input)",
7640 " local rec = {}",
7641 " for i = 1, #input, 3 do",
7642 " if i % 66 == 0 then",
7643 " yield()",
7644 " end",
7645 " rec[#rec+1], rec[#rec+2] = upack(input[i], input[i+1] or 0, input[i+2] or 0)",
7646 " end",
7647 " trim(rec)",
7648 " return dc(rec)",
7649 "end",
7650 "local function compress(input)",
7651 " local rec = {}",
7652 " local data = cp(input)",
7653 " for i=1, #data, 2 do",
7654 " yield()",
7655 " rec[#rec+1], rec[#rec+2], rec[#rec+3] = pack(data[i], data[i+1] or 0)",
7656 " end",
7657 " trim(rec)",
7658 " return rec",
7659 "end",
7660 "",
7661 "-- CCA API END --",
7662 "",
7663 "local fixstr = function(str)",
7664 " return str:gsub(\"\\\\(%d%d%d)\",string.char)",
7665 "end",
7666 "",
7667 "local explode = function(div,str)",
7668 " if (div=='') then return false end",
7669 " local pos,arr = 0,{}",
7670 " for st,sp in function() return string.find(str,div,pos,true) end do",
7671 " table.insert(arr,str:sub(pos,st-1))",
7672 " pos = sp + 1",
7673 " end",
7674 " table.insert(arr,str:sub(pos))",
7675 " return arr",
7676 "end",
7677 "local sanitize = function(sani,tize)",
7678 " local _,x = string.find(sani,tize)",
7679 " if x then",
7680 " return sani:sub(x+1)",
7681 " else",
7682 " return sani",
7683 " end",
7684 "end",
7685 "local tablize = function(input)",
7686 " if type(input) == \"string\" then",
7687 " return explode(\"\\n\",input)",
7688 " elseif type(input) == \"table\" then",
7689 " return table.concat(input,\"\\n\")",
7690 " end",
7691 "end",
7692 "local compyress = function(input)",
7693 " return string.char(unpack(compress(input)))",
7694 "end",
7695 "local decompyress = function(input)",
7696 " local out = {}",
7697 " for a = 1, #input do",
7698 " table.insert(out,string.byte(input:sub(a,a)))",
7699 " end",
7700 " return decompress(out)",
7701 "end",
7702 "local listAll",
7703 "listAll = function(_path, _files, noredundant)",
7704 " local path = _path or \"\"",
7705 " local files = _files or {}",
7706 " if #path > 1 then table.insert(files, path) end",
7707 " for _, file in ipairs(fs.list(path)) do",
7708 " local path = fs.combine(path, file)",
7709 " if (file ~= thisProgram) then",
7710 " local guud = true",
7711 " if guud then",
7712 " if fs.isDir(path) then",
7713 " listAll(path, files, noredundant)",
7714 " else",
7715 " table.insert(files, path)",
7716 " end",
7717 " end",
7718 " end",
7719 " end",
7720 " if noredundant then",
7721 " for a = 1, #files do",
7722 " if fs.isDir(tostring(files[a])) then",
7723 " if #fs.list(tostring(files[a])) ~= 0 then",
7724 " table.remove(files,a)",
7725 " end",
7726 " end",
7727 " end",
7728 " end",
7729 " return files",
7730 "end",
7731 "if not (input) then",
7732 " return displayHelp()",
7733 "end",
7734 "if not outpath then",
7735 " outpath = input",
7736 "end",
7737 "",
7738 "local choice = function(input,verbose)",
7739 " if not input then",
7740 " input = \"yn\"",
7741 " end",
7742 " if verbose then",
7743 " write(\"[\")",
7744 " for a = 1, #input do",
7745 " write(input:sub(a,a):upper())",
7746 " if a < #input then",
7747 " write(\",\")",
7748 " end",
7749 " end",
7750 " write(\"]?\")",
7751 " end",
7752 " local evt,char",
7753 " repeat",
7754 " evt,char = os.pullEvent(\"char\")",
7755 " until string.find(input:lower(),char:lower())",
7756 " if verbose then",
7757 " print(char:upper())",
7758 " end",
7759 " local pos = string.find(input:lower(),char:lower())",
7760 " return pos, char:lower()",
7761 "end",
7762 "",
7763 "local postToPastebin = function(name, contents)",
7764 " local key = \"0ec2eb25b6166c0c27a394ae118ad829\"",
7765 " local response = http.post(",
7766 " \"http://pastebin.com/api/api_post.php\",",
7767 " \"api_option=paste&\"..",
7768 " \"api_dev_key=\"..key..\"&\"..",
7769 " \"api_paste_format=lua&\"..",
7770 " \"api_paste_name=\"..textutils.urlEncode(name)..\"&\"..",
7771 " \"api_paste_code=\"..textutils.urlEncode(contents)",
7772 " )",
7773 " if response then",
7774 " local sResponse = response.readAll()",
7775 " response.close()",
7776 " local sCode = string.match( sResponse, \"[^/]+$\" )",
7777 " return sCode",
7778 " else",
7779 " return false",
7780 " end",
7781 " return ",
7782 "end",
7783 "",
7784 "function doPack(input,output,doCompress,verbose) --make sure that shell exists before using verbose mode",
7785 " local tx = term.getTextColor()",
7786 " if not doPastebin then",
7787 " if not fs.exists(input) then return 3 end",
7788 " if fs.isReadOnly(output) then return 5 end",
7789 " end",
7790 " local packageSelf = true",
7791 " local packageReadOnly = true",
7792 " local ro_asked = false",
7793 " local ps_asked = false",
7794 " if fs.isDir(input) then --if not a package",
7795 " local out = {}",
7796 " local list = listAll(input,nil,true)",
7797 " if verbose then",
7798 " for a = 1, #list do --this checks for self and read-only files",
7799 " if fs.isReadOnly(list[a]) and (not ro_asked) then",
7800 " write(\"Include read-only files? \")",
7801 " if choice(\"yn\",true) == 2 then",
7802 " packageReadOnly = false",
7803 " end",
7804 " ro_asked = true",
7805 " end",
7806 " if fs.combine(\"\",list[a]) == shell.getRunningProgram() and (not ps_asked) then",
7807 " write(\"Include self? \")",
7808 " if choice(\"yn\",true) == 2 then",
7809 " packageSelf = false",
7810 " end",
7811 " ps_asked = true",
7812 " end",
7813 " end",
7814 " end",
7815 " for a = 1, #list do --this loop kills fascists",
7816 " local is_self = fs.combine(\"\",list[a]) == fs.combine(\"\",shell.getRunningProgram())",
7817 " if not ((is_self and not packageSelf) or (fs.isReadOnly(list[a]) and not packageReadOnly)) then",
7818 " if verbose then",
7819 " write(\"[\")",
7820 " if term.isColor() then term.setTextColor(colors.lightGray) end",
7821 " write(sanitize(list[a],fs.combine(dir,input)))",
7822 " term.setTextColor(tx)",
7823 " write(\"]\")",
7824 " end",
7825 " if fs.isDir(list[a]) then",
7826 " out[sanitize(list[a],fs.combine(dir,input))] = true",
7827 " else",
7828 " local file = fs.open(list[a],\"r\")",
7829 " local cont = file.readAll()",
7830 " file.close()",
7831 " if doCompress then",
7832 " out[sanitize(list[a],fs.combine(dir,input))] = tablize(compyress(cont))",
7833 " else",
7834 " out[sanitize(list[a],fs.combine(dir,input))] = tablize(cont)",
7835 " end",
7836 " end",
7837 " local tx = term.getTextColor()",
7838 " if fs.getName(list[a]):lower() == \"peasant\" then",
7839 " if term.isColor() then",
7840 " term.setTextColor(colors.orange)",
7841 " end",
7842 " print(\" BURNINATED\")",
7843 " else",
7844 " if term.isColor() then",
7845 " term.setTextColor(colors.green)",
7846 " end",
7847 " print(\" GOOD\")",
7848 " end",
7849 " term.setTextColor(tx)",
7850 " else",
7851 " if fs.getName(list[a]):lower() == \"peasant\" then",
7852 " print(\"Spared \"..list[a])",
7853 " else",
7854 " print(\"Skipped \"..list[a])",
7855 " end",
7856 " end",
7857 " end",
7858 " local fullOutput = tostring(doCompress)..\"\\n\"..fixstr(textutils.serialize(out))",
7859 " local sCode",
7860 " if doPastebin then",
7861 " print(\"Uploading...\")",
7862 " sCode = postToPastebin(input,fullOutput)",
7863 " return 7, \"Code = '\"..sCode..\"'\"",
7864 " else",
7865 " if fs.isDir(output) then fs.delete(output) end",
7866 " local file = fs.open(output,\"w\")",
7867 " file.write(fullOutput)",
7868 " file.close()",
7869 " return 1",
7870 " end",
7871 " else --if a package",
7872 " local list, isCompy",
7873 " if not doPastebin then",
7874 " local file = fs.open(input,\"r\")",
7875 " isCompy = file.readLine()",
7876 " list = file.readAll()",
7877 " file.close()",
7878 " else",
7879 " local file = http.get(\"http://pastebin.com/raw/\"..tostring(input))",
7880 " if file then",
7881 " isCompy = file.readLine()",
7882 " list = file.readAll()",
7883 " else",
7884 " return 6",
7885 " end",
7886 " end",
7887 " local list = textutils.unserialize(list)",
7888 " if type(list) ~= \"table\" then",
7889 " return 4",
7890 " end",
7891 " if fs.exists(output) then",
7892 " fs.delete(output)",
7893 " end",
7894 " local amnt = 0",
7895 " for k,v in pairs(list) do",
7896 " amnt = amnt + 1",
7897 " end",
7898 " local num = 0",
7899 " for k,v in pairs(list) do",
7900 " num = num + 1",
7901 " if v == true then",
7902 " fs.makeDir(fs.combine(output,fs.combine(k,dir)))",
7903 " else",
7904 " local file = fs.open(fs.combine(output,fs.combine(k,dir)),\"w\")",
7905 " if verbose then",
7906 " write(\"[\")",
7907 " if term.isColor() then term.setTextColor(colors.lightGray) end",
7908 " write(k)",
7909 " term.setTextColor(tx)",
7910 " write(\"]\")",
7911 " end",
7912 " if isCompy:gsub(\" \",\"\") == \"true\" then",
7913 " file.write(decompyress(tablize(v)))",
7914 " else",
7915 " file.write(tablize(v))",
7916 " end",
7917 " file.close()",
7918 " local tx = term.getTextColor()",
7919 " if fs.getName(k):lower() == \"peasant\" then",
7920 " if term.isColor() then",
7921 " term.setTextColor(colors.orange)",
7922 " end",
7923 " print(\" UNBURNINATED\")",
7924 " else",
7925 " if term.isColor() then",
7926 " term.setTextColor(colors.green)",
7927 " end",
7928 " print(\" GOOD\")",
7929 " end",
7930 " term.setTextColor(tx)",
7931 " end",
7932 " end",
7933 " return 2",
7934 " end",
7935 "end",
7936 "",
7937 "local success, res, otherRes = pcall( function() return doPack(input,outpath,doCompress,true) end ) --functionized it!",
7938 "",
7939 "if not success then",
7940 " term.setTextColor(colors.white)",
7941 " print(\"\\n***Something went wrong!***\")",
7942 " return printError(res)",
7943 "end",
7944 "",
7945 "if res then",
7946 " local msgs = {",
7947 " [1] = \"Successfully packed '\"..input..\"/' as '\"..outpath..\"'\",",
7948 " [2] = \"Successfully unpacked '\"..input..\"' to '\"..outpath..\"/'\",",
7949 " [3] = \"That file/folder does not exist.\",",
7950 " [4] = \"That file isn't a packed folder.\",",
7951 " [5] = \"You don't have permission.\",",
7952 " [6] = \"Failed to connect.\",",
7953 " [7] = \"Uploaded successfully.\",",
7954 " }",
7955 " print(msgs[res])",
7956 " if otherRes then",
7957 " print(otherRes)",
7958 " end",
7959 "end",
7960 },
7961 [ "/std.lua" ] = {
7962 "--[[",
7963 "Super Text Downloader by EldidiStroyrr/LDDestroier",
7964 "",
7965 "The purpose of this program is to have a single",
7966 "unified download script for ComputerCraft, as opposed",
7967 "to making multiple programs, each able to download from one site.",
7968 "",
7969 "The main aspect to make this script more modular is having",
7970 "a table (websiteSyntaxes) to store the website that it downloads",
7971 "from, as well as what abbreviation it's called with and the",
7972 "syntax of the raw download URL.",
7973 "Later updates added special prefixes that act in different ways",
7974 "that could not work with the standard syntax.",
7975 "",
7976 " pastebin get 3PBKGR4k std ",
7977 " std ld std std ",
7978 "--]]",
7979 "",
7980 "if type(std) ~= \"table\" then std = {} end",
7981 "",
7982 "std.channelURLs = { --special URLs for getting a list of files.",
7983 " [\"STD\"] = \"https://raw.githubusercontent.com/LDDestroier/STD-GUI/master/list.lua\", --stock",
7984 " [\"Discover\"] = \"https://pastebin.com/raw/9bXfCz6M\", --owned by dannysmc95",
7985 " --[\"OnlineAPPS\"] = \"https://pastebin.com/raw/g2EnDYLp\", --owned by Twijn, but discontinued",
7986 " [\"STD-Media\"] = \"https://pastebin.com/raw/3JZHXTGL\" --non-program media files",
7987 "}",
7988 "local goodchan = false",
7989 "for k,v in pairs(std.channelURLs) do",
7990 " if std.channel == k then",
7991 " goodchan = true",
7992 " break",
7993 " end",
7994 "end",
7995 "if not goodchan then",
7996 " std.channel = \"STD\"",
7997 "end",
7998 "std.prevChannel = std.channel",
7999 "std.std_version = 1.453 --Number, not string!",
8000 "std.stdList = \"/.\"..std.channel:lower()..\"_list\" --String, path of store listings",
8001 "std.websiteList = \"/.std_websites\" --String, path of website listings",
8002 "local doStore = true --If you do 'std ld', should you open up the store? Or just fuck off?",
8003 "std.serious = true",
8004 "",
8005 "local logo = {[[",
8006 " __________________________",
8007 " / ___________ ______ ____ \\",
8008 "/ / | | | | \\ \\",
8009 "\\ \\______ | | | | | |",
8010 " \\______ \\ | | | | | |",
8011 " \\ \\ | | | | | |",
8012 " ______/ / | | | |___/ /",
8013 " /_______/ |_| |______/",
8014 " Super Text Downloader",
8015 "",
8016 "]],[[",
8017 " LLL LLLLL LLL",
8018 " L L L L L",
8019 " L L L L",
8020 " LLL L L L",
8021 " L L L L",
8022 " L L L L L",
8023 " LLL L LLL",
8024 " Super Text Downloader]]",
8025 "",
8026 "}",
8027 "",
8028 "",
8029 "-- start Base64",
8030 "local b = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"",
8031 "local encode = function(data)",
8032 " return ((data:gsub('.', function(x) ",
8033 " local r,b='',x:byte()",
8034 " for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end",
8035 " return r;",
8036 " end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)",
8037 " if (#x < 6) then return '' end",
8038 " local c=0",
8039 " for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end",
8040 " return b:sub(c+1,c+1)",
8041 " end)..({ '', '==', '=' })[#data%3+1])",
8042 "end",
8043 "local decode = function(data)",
8044 " data = string.gsub(data, '[^'..b..'=]', '')",
8045 " return (data:gsub('.', function(x)",
8046 " if (x == '=') then return '' end",
8047 " local r,f='',(b:find(x)-1)",
8048 " for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end",
8049 " return r;",
8050 " end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)",
8051 " if (#x ~= 8) then return '' end",
8052 " local c=0",
8053 " for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end",
8054 " return string.char(c)",
8055 " end))",
8056 "end",
8057 "-- finished Base64",
8058 "",
8059 "local runFile = function(path)",
8060 " if not fs.exists(path) then",
8061 " return false, \"No such file!\"",
8062 " end",
8063 " local file = fs.open(path,\"r\")",
8064 " local contents = file.readAll()",
8065 " file.close()",
8066 " local func = loadstring(contents)",
8067 " setfenv(func, getfenv())",
8068 " return func()",
8069 "end",
8070 "",
8071 "local function runURL(url, ...)",
8072 " local program = http.get(url)",
8073 " if not program then return false end",
8074 " program = program.readAll()",
8075 " local func = loadstring(program)",
8076 " setfenv(func, getfenv())",
8077 " return func(...)",
8078 "end",
8079 "",
8080 "local function seperateMethods(input)",
8081 " local output={}",
8082 " for key,value in pairs(input) do",
8083 " table.insert(output, {key,value})",
8084 " end",
8085 " return output",
8086 "end",
8087 "",
8088 "local function displayHelp(mode)",
8089 " if mode == 1 then",
8090 " print(\"std <abbr> <fileid> [output]\")",
8091 " print(\"Do 'std list' to see all codes\")",
8092 " print(\"Do 'std ld' for a GUI\")",
8093 " write(\"Channel '\")",
8094 " if term.isColor() then term.setTextColor(colors.yellow) end",
8095 " write(std.channel)",
8096 " term.setTextColor(colors.white)",
8097 " print(\"' is selected.\")",
8098 " elseif mode == 2 then",
8099 " if std.serious then",
8100 " print(\"List of website codes:\")",
8101 " else",
8102 " print(\"all ur codes:\")",
8103 " end",
8104 " std.websiteSyntaxes[\"dd\"] = {} --Filler",
8105 " std.websiteSyntaxes[\"dd64\"] = {}",
8106 " std.websiteSyntaxes[\"PB\"] = {}",
8107 " for k,v in pairs(std.websiteSyntaxes) do",
8108 " if term.getTextColor then prevColor = term.getTextColor() else prevColor = colors.white end",
8109 " write(\" '\")",
8110 " if term.isColor() then term.setTextColor(colors.orange) end",
8111 " write(k)",
8112 " term.setTextColor(prevColor)",
8113 " write(\"' \")",
8114 " if k == \"dd\" then",
8115 " print(\"direct download\")",
8116 " elseif k == \"dd64\" then",
8117 " print(\"direct download + Base64\")",
8118 " elseif k == \"PB\" then",
8119 " print(\"pastebin.com (safe)\")",
8120 " elseif string.find(v.url,\"/\") then",
8121 " start = string.find(v.url,\"://\")+3",
8122 " finish = string.find(v.url,\"/\",9)-1",
8123 " print(string.sub(v.url,start,finish))",
8124 " end",
8125 " end",
8126 " elseif mode == 3 then",
8127 " print(logo[pocket and 2 or 1])",
8128 " end",
8129 "end",
8130 "",
8131 "local function choice(input) --A useful function for input. Similar to the MS-DOS 6.0 command.",
8132 " local event, key",
8133 " repeat",
8134 " event, key = os.pullEvent(\"key\")",
8135 " if type(key) == \"number\" then key = keys.getName(key) end",
8136 " if key == nil then key = \" \" end",
8137 " until string.find(string.lower(input), string.lower(key))",
8138 " return string.lower(key)",
8139 "end",
8140 "",
8141 "--This list of websites is used as a backup, should you not be able to connect to pastebin.",
8142 "std.websiteSyntaxes = {",
8143 " pb = {",
8144 " url = \"https://pastebin.com/raw.php?i=FILECODE\",",
8145 " fullName = \"Pastebin\",",
8146 " codeLength = 6,",
8147 " },",
8148 " hb = {",
8149 " url = \"https://hastebin.com/raw/FILECODE\",",
8150 " fullName = \"Hastebin\",",
8151 " codeLength = 10,",
8152 " },",
8153 " pe = {",
8154 " url = \"http://pastie.org/pastes/FILECODE/download\",",
8155 " fullName = \"Pastie\",",
8156 " codeLength = 0,",
8157 " },",
8158 " fn = {",
8159 " url = \"https://fnpaste.com/FILECODE/raw\",",
8160 " fullName = \"fnPaste\",",
8161 " codeLength = 4,",
8162 " },",
8163 " gh = {",
8164 " url = \"https://raw.githubusercontent.com/FILECODE\",",
8165 " fullName = \"Github\",",
8166 " codeLength = 0,",
8167 " },",
8168 " gg = {",
8169 " url = \"https://gist.githubusercontent.com/FILECODE/raw/\",",
8170 " fullName = \"Github Gist\",",
8171 " codeLength = 0,",
8172 " },",
8173 " sn = {",
8174 " url = \"http://s.drk.sc/FILECODE\",",
8175 " fullName = \"Snippt\",",
8176 " codeLength = 6,",
8177 " },",
8178 " cp = {",
8179 " url = \"http://codepad.org/FILECODE/raw.txt\",",
8180 " fullName = \"Codepad\",",
8181 " codeLength = 8,",
8182 " },",
8183 " id = {",
8184 " url = \"https://ideone.com/plain/FILECODE\",",
8185 " fullName = \"Ideone\",",
8186 " codeLength = 6,",
8187 " },",
8188 " db = {",
8189 " url = \"https://www.dropbox.com/s/FILECODE?raw=true\",",
8190 " fullName = \"Dropbox\",",
8191 " codeLength = 0,",
8192 " },",
8193 " dd = {",
8194 " url = \"FILECODE\",",
8195 " fullName = \"Direct Download\",",
8196 " codeLength = 0,",
8197 " },",
8198 "}",
8199 "",
8200 "local tArg = {...}",
8201 "if shell then",
8202 " std_file = shell.getRunningProgram()",
8203 "else",
8204 " std_file = \"\"",
8205 "end",
8206 "",
8207 "local getTableSize = function(tbl)",
8208 " local amnt = 0",
8209 " for k,v in pairs(tbl) do",
8210 " amnt = amnt + 1",
8211 " end",
8212 " return amnt",
8213 "end",
8214 "",
8215 "std.getSTDList = function(prevChannel)",
8216 " local weburl = \"http://pastebin.com/raw/FSCzZRUk\" --URL of URL list.",
8217 " local storeurl = std.channelURLs[std.channel] --URL of store list.",
8218 " local webcontents = http.get(weburl)",
8219 " local storecontents = http.get(storeurl)",
8220 " if not (webcontents and storecontents) then",
8221 " if shell then",
8222 " print(\"Couldn't update list!\")",
8223 " end",
8224 " return false, \"Couldn't update list!\"",
8225 " else",
8226 " local uut = runFile(std.stdList)",
8227 " if not uut then std.storeURLs = nil end",
8228 " local webprog = webcontents.readAll()",
8229 " local storeprog = storecontents.readAll()",
8230 " local webfile = fs.open(std.websiteList,\"w\")",
8231 " local storefile = fs.open(std.stdList,\"w\")",
8232 " ",
8233 " webfile.writeLine(webprog)",
8234 " webfile.close()",
8235 " storefile.writeLine(storeprog)",
8236 " storefile.close()",
8237 " runFile(std.websiteList)",
8238 " ",
8239 " local outcome = runFile(std.stdList)",
8240 " if outcome == false then",
8241 " std.channel = prevChannel",
8242 " return std.getSTDList(\"STD\")",
8243 " end",
8244 " return true, \"Downloaded to \"..std.stdList",
8245 " end",
8246 "end",
8247 "",
8248 "if tArg[1] == \"update\" or not fs.exists(std.stdList) then",
8249 " local updateChan = tArg[2]",
8250 " if (updateChan) and (not std.channelURLs[updateChan]) and tArg[1] == \"update\" then",
8251 " printError(\"No such channel.\")",
8252 " for k,v in pairs(std.channelURLs) do",
8253 " term.setTextColor(colors.white)",
8254 " write(\" \")",
8255 " if k == std.channel then",
8256 " write(\"@\")",
8257 " if term.isColor() then term.setTextColor(colors.yellow) end",
8258 " else",
8259 " write(\"O\")",
8260 " end",
8261 " print(\" \"..k)",
8262 " end",
8263 " term.setTextColor(colors.white)",
8264 " return",
8265 " end",
8266 " if std.serious then",
8267 " write(\"Updating list...\")",
8268 " else",
8269 " write(\"just a sec, gettin your repo...\")",
8270 " end",
8271 " if updateChan and std.channelURLs[updateChan] then",
8272 " std.prevChannel = std.channel",
8273 " std.channel = updateChan",
8274 " end",
8275 " local success = std.getSTDList(std.prevChannel)",
8276 " if not success then",
8277 " if std.serious then",
8278 " return printError(\"FAIL!\")",
8279 " else",
8280 " return printError(\"IT'S NO USE!\")",
8281 " end",
8282 " else",
8283 " if std.serious then",
8284 " print(\"good!\")",
8285 " else",
8286 " print(\"excellent!\")",
8287 " end",
8288 " if tArg[1] == \"update\" then return true end",
8289 " end",
8290 "end",
8291 "",
8292 "if not shell then return end",
8293 "",
8294 "local websiteCode = tArg[1]",
8295 "local fileCode = tArg[2]",
8296 "local retrieveName = tArg[3]",
8297 "",
8298 "if (websiteCode == \"list\") and (not fileCode) then",
8299 " displayHelp(2)",
8300 " return false",
8301 "elseif (websiteCode == \"you foolish fool\") and (not fileCode) then",
8302 " displayHelp(3)",
8303 " return false",
8304 "elseif (websiteCode ~= \"ld\") and (not fileCode) then",
8305 " displayHelp(1)",
8306 " return false",
8307 "end",
8308 "",
8309 "local getFile = function(filename,url)",
8310 " if fs.isReadOnly(filename) then",
8311 " return false, \"access denied\"",
8312 " end",
8313 " local prog",
8314 " if type(url) == \"table\" then",
8315 " prog = contextualGet(url[1])",
8316 " else",
8317 " prog = http.get(url)",
8318 " end",
8319 " if not prog then",
8320 " return false, \"could not connect\"",
8321 " end",
8322 " prog = prog.readAll()",
8323 " local fyle = fs.open(filename,\"w\")",
8324 " fyle.write(prog)",
8325 " fyle.close()",
8326 " return true, fs.getSize(filename)",
8327 "end",
8328 "",
8329 "runFile(std.stdList)",
8330 "runFile(std.websiteList)",
8331 "local pastebinUpload = function(sName,sText)",
8332 " write( \"Connecting to pastebin.com... \" )",
8333 " local key = \"0ec2eb25b6166c0c27a394ae118ad829\"",
8334 " local response = http.post(",
8335 " \"http://pastebin.com/api/api_post.php\", ",
8336 " \"api_option=paste&\"..",
8337 " \"api_dev_key=\"..key..\"&\"..",
8338 " \"api_paste_format=lua&\"..",
8339 " \"api_paste_name=\"..textutils.urlEncode(sName)..\"&\"..",
8340 " \"api_paste_code=\"..textutils.urlEncode(sText)",
8341 " )",
8342 " if response then",
8343 " print( \"Success.\" )",
8344 " local sResponse = response.readAll()",
8345 " response.close()",
8346 " return string.match( sResponse, \"[^/]+$\" )",
8347 " end",
8348 " return false",
8349 "end",
8350 "",
8351 "local fileURL",
8352 "if websiteCode == \"ld\" then",
8353 " if not fileCode then",
8354 " if doStore then",
8355 " runURL(\"http://pastebin.com/raw/P9dDhQ2m\")",
8356 " return",
8357 " else",
8358 " return print(\"GUI Store has been disabled.\")",
8359 " end",
8360 " else",
8361 " if not std.storeURLs then",
8362 " if std.serious then",
8363 " write(\"Updating list...\")",
8364 " else",
8365 " write(\"just a sec, gettin your repo...\")",
8366 " end",
8367 " std.getSTDList()",
8368 " end",
8369 " if not std.storeURLs[fileCode] then",
8370 " if std.serious then",
8371 " return printError(\"Invalid store code '\" .. fileCode .. \"'\")",
8372 " else",
8373 " return printError(\"ld code \"..fileCode..\" not guuud!!!\")",
8374 " end",
8375 " else",
8376 " fileURL = tostring(std.storeURLs[fileCode].url)",
8377 " end",
8378 " end",
8379 "elseif websiteCode == \"PB\" then --Hope it's not confusing.",
8380 " fileURL = \"https://pastebin.com/\"..fileCode:sub(1,8)",
8381 " write(\"Conntecting to '\"..fileURL..\"' safely...\")",
8382 " local prog = http.get(fileURL)",
8383 " if not prog then",
8384 " return printError(\"FAIL!\")",
8385 " else",
8386 " if term.isColor() then term.setTextColor(colors.green) end",
8387 " print(\"GOOD!\")",
8388 " term.setTextColor(colors.white)",
8389 " local rawget = prog.readAll()",
8390 " local s = string.find(rawget,\"<textarea id=\\\"paste_code\\\"\")+103",
8391 " local e = string.find(rawget,\"</textarea>\")-1",
8392 " local contents = string.gsub(string.sub(rawget,s,e),\""\",\"\\\"\")",
8393 " contents = contents:gsub(\"<\",\"<\")",
8394 " contents = contents:gsub(\">\",\">\")",
8395 " if retrieveName and shell then",
8396 " local dlname = fs.combine(shell.dir(),retrieveName)",
8397 " if fs.exists(dlname) then",
8398 " if std.serious then",
8399 " print(\"'\" .. dlname .. \"' exists! Overwrite?\")",
8400 " write(\"[Y,N]?\")",
8401 " else",
8402 " print(\"yoo alreddy got a '\"..dlname..\"'!! redu eet?\")",
8403 " write(\"[why,enn]??\")",
8404 " end",
8405 " local key = choice(\"yn\")",
8406 " print(string.upper(key))",
8407 " if key == \"n\" then",
8408 " if std.serious then",
8409 " print(\"Cancelled.\")",
8410 " else",
8411 " print(\"whatevz\")",
8412 " end",
8413 " sleep(0)",
8414 " return false",
8415 " end",
8416 " end",
8417 " local file = fs.open(dlname, \"w\")",
8418 " file.writeLine(contents)",
8419 " file.close()",
8420 " if std.serious then",
8421 " print(\"Done! DL'd \" .. fs.getSize(dlname) .. \" bytes.\")",
8422 " else",
8423 " print(\"yay guud! eets \".. fs.getSize(dlname)*2 ..\" nibbles\")",
8424 " end",
8425 " else",
8426 " local func = loadstring(contents)",
8427 " setfenv(func, getfenv())",
8428 " func()",
8429 " end",
8430 " sleep(0)",
8431 " return",
8432 " end",
8433 "elseif websiteCode == \"dd64\" then",
8434 " write(\"Conntecting to '\"..fileCode..\"'...\")",
8435 " local cont = http.get(fileCode)",
8436 " local dlname = fs.combine(shell.dir(),retrieveName)",
8437 " if cont then",
8438 " if term.isColor() then term.setTextColor(colors.green) end",
8439 " print(\"GOOD!\")",
8440 " term.setTextColor(colors.white)",
8441 " cont = decode(cont.readAll())",
8442 " local file = fs.open(dlname,\"w\")",
8443 " file.write(cont)",
8444 " file.close()",
8445 " if std.serious then",
8446 " print(\"Done! DL'd \" .. fs.getSize(dlname) .. \" bytes.\")",
8447 " else",
8448 " print(\"yay guud! eets \".. fs.getSize(dlname)*2 ..\" nibbles\")",
8449 " end",
8450 " return true",
8451 " else",
8452 " return printError(\"FAIL!\")",
8453 " end",
8454 "elseif websiteCode == \"pbupload\" then",
8455 " fileCode = fs.combine(\"\",fileCode)",
8456 " if not fs.exists(fileCode) then",
8457 " return printError(\"NO SUCH FILE!\")",
8458 " else",
8459 " local file = fs.open(fileCode,\"r\")",
8460 " local cont = file.readAll()",
8461 " file.close()",
8462 " local sCode = pastebinUpload(fileCode,cont)",
8463 " if sCode then",
8464 " write(\"Uploaded with code:\")",
8465 " if term.isColor() then term.setTextColor(colors.yellow) end",
8466 " print(sCode)",
8467 " term.setTextColor(colors.white)",
8468 " print(\"Don't forget it!\")",
8469 " else",
8470 " return printError(\"FAIL!\")",
8471 " end",
8472 " return true",
8473 " end",
8474 "elseif websiteCode == \"pbupload64\" then",
8475 " fileCode = fs.combine(\"\",fileCode)",
8476 " if not fs.exists(fileCode) then",
8477 " return printError(\"NO SUCH FILE!\")",
8478 " else",
8479 " local file = fs.open(fileCode,\"r\")",
8480 " local cont = encode(file.readAll())",
8481 " file.close()",
8482 " local sCode = pastebinUpload(fileCode,cont)",
8483 " if sCode then",
8484 " write(\"Uploaded with Base64 with code:\")",
8485 " if term.isColor() then term.setTextColor(colors.yellow) end",
8486 " print(sCode)",
8487 " term.setTextColor(colors.white)",
8488 " print(\"Don't forget it!\")",
8489 " else",
8490 " return printError(\"FAIL!\")",
8491 " end",
8492 " return true",
8493 " end",
8494 "else",
8495 " if not std.websiteSyntaxes[websiteCode] then",
8496 " if std.serious then",
8497 " return printError(\"Invalid website code '\" .. websiteCode .. \"'\")",
8498 " else",
8499 " return printError(\"dat '\"..websiteCode..\"' is NAWT GUUD!!\")",
8500 " end",
8501 " else",
8502 " if (std.websiteSyntaxes[websiteCode].codeLength == 0) or (not std.websiteSyntaxes[websiteCode].codeLength) then",
8503 " fileURL = string.gsub(std.websiteSyntaxes[websiteCode].url, \"FILECODE\", fileCode)",
8504 " else",
8505 " fileURL = string.gsub(std.websiteSyntaxes[websiteCode].url, \"FILECODE\", string.sub(fileCode,1,std.websiteSyntaxes[websiteCode].codeLength))",
8506 " end",
8507 " end",
8508 " sleep(0)",
8509 "end",
8510 "",
8511 "if std.serious then",
8512 " write(\"Connecting to '\" .. fileURL .. \"'...\")",
8513 "else",
8514 " if math.random(1,2) == 1 then",
8515 " write(\"gettin ze '\"..fileURL..\"'...\")",
8516 " else",
8517 " write(\"commeptin to '\"..fileURL..\"' naow...\")",
8518 " end",
8519 "end",
8520 "local contents = http.get(fileURL)",
8521 "if not contents then",
8522 " if term.isColor() then",
8523 " term.setTextColor(colors.red)",
8524 " end",
8525 " if std.serious then",
8526 " print(\"NOPE!\")",
8527 " else",
8528 " print(\"NI!\")",
8529 " end",
8530 " sleep(0)",
8531 " return false",
8532 "else",
8533 " if term.getTextColor then",
8534 " prevColor = term.getTextColor()",
8535 " else",
8536 " prevColor = colors.white",
8537 " end",
8538 " if term.isColor() then",
8539 " term.setTextColor(colors.green)",
8540 " end",
8541 " if std.serious then",
8542 " print(\"good!\")",
8543 " else",
8544 " print(\"gud!\")",
8545 " end",
8546 " term.setTextColor(prevColor)",
8547 " if retrieveName and shell then",
8548 " local dlname = fs.combine(shell.dir(),retrieveName)",
8549 " if fs.exists(dlname) then",
8550 " if std.serious then",
8551 " print(\"'\" .. dlname .. \"' exists! Overwrite?\")",
8552 " write(\"[Y,N]?\")",
8553 " else",
8554 " print(\"yoo alreddy got a '\"..dlname..\"'!! redu eet?\")",
8555 " write(\"[why,enn]??\")",
8556 " end",
8557 " local key = choice(\"yn\")",
8558 " print(string.upper(key))",
8559 " if key == \"n\" then",
8560 " if std.serious then",
8561 " print(\"Cancelled.\")",
8562 " else",
8563 " print(\"whatevz\")",
8564 " end",
8565 " sleep(0)",
8566 " return false",
8567 " end",
8568 " end",
8569 " local file = fs.open(dlname, \"w\")",
8570 " file.writeLine(contents.readAll())",
8571 " file.close()",
8572 " if std.serious then",
8573 " print(\"Done! DL'd \" .. fs.getSize(dlname) .. \" bytes.\")",
8574 " else",
8575 " print(\"yay guud! eets \".. fs.getSize(dlname)*2 ..\" nibbles\")",
8576 " end",
8577 " else",
8578 " local contents = loadstring(contents.readAll())",
8579 " setfenv(contents, getfenv())",
8580 " contents()",
8581 " end",
8582 " sleep(0)",
8583 " return true",
8584 "end",
8585 },
8586 [ "/stdgui.lua" ] = {
8587 "--[[",
8588 " STD Graphical User Interface! (STD-GUI)!",
8589 " Made by LDDestroier/EldidiStroyrr (same guy)",
8590 "",
8591 " This program is a standalone GUI for Super Text Downloader, or STD for short.",
8592 " It has category sorting, program searching, smooth scrolling, and run support (not just download)",
8593 " This will tell you if you're overwriting a file, so no worry.",
8594 "",
8595 " As of May 15th (my GOSH DARN birthday) 2016, STD-GUI now lets you install SimSoft applications in the store interface!",
8596 " As of Jan 11th 2018, STD-GUI now lets you install Axiom OS applications too!",
8597 "",
8598 " pastebin get P9dDhQ2m stdgui",
8599 " std PB P9dDhQ2m stdgui",
8600 " std ld stdgui stdgui",
8601 "",
8602 " This is a stable release. You fool!",
8603 "--]]",
8604 "",
8605 "local tsv = term.current().setVisible --comment out if you are debugging",
8606 "",
8607 "local isBeta = false --changes the update URL",
8608 "",
8609 "if not http then --why, you...",
8610 " return false, printError(\"HTTP must be enabled to use STD. Contact an administrator for assistance.\")",
8611 "else",
8612 " if not http.checkURL(\"http://pastebin.com\") then",
8613 " return false, printError(\"For some reason, Pastebin.com is whitelisted. Abort.\")",
8614 " end",
8615 "end",
8616 "local scr_x, scr_y = term.getSize()",
8617 "",
8618 "local doDisplayTitle = false",
8619 "local relativePath = false",
8620 "local doColorize = true",
8621 "",
8622 "if type(std) ~= \"table\" then std = {} end",
8623 "",
8624 "local overrideNoOS = false --prevent SimSoft functions, even if it's installed",
8625 "local isSimSoft = false --special integration into SimSoft!",
8626 "local isAxiom = false --special integration into Axiom!",
8627 "std.channel = \"STD\"",
8628 "std.prevChannel = std.channel",
8629 "",
8630 "std.channelURLs = { --special pastebin URLs for getting a list of files.",
8631 " [\"STD\"] = \"https://raw.githubusercontent.com/LDDestroier/STD-GUI/master/list.lua\", --default store list on github, more updated",
8632 " [\"STD PB\"] = \"http://pastebin.com/raw/zVws7eLq\", --default store list on pastebin",
8633 " [\"Discover\"] = \"http://pastebin.com/raw/9bXfCz6M\", --owned by dannysmc95",
8634 "-- [\"OnlineAPPS\"] = \"http://pastebin.com/raw/g2EnDYLp\", --owned by Twijn, but discontinued.",
8635 " [\"STD-Media\"] = \"https://pastebin.com/raw/3JZHXTGL\", --list of pictures and music",
8636 "}",
8637 "local palate",
8638 "palate = {",
8639 " pleasewait = {",
8640 " txt = colors.lightGray,",
8641 " bg = colors.black,",
8642 " },",
8643 " store = {",
8644 " bg = colors.black,",
8645 " txt = colors.white,",
8646 " bgchar = \" \",",
8647 " entrybg = colors.gray,",
8648 " entrytxt = colors.white,",
8649 " entryasterisk = colors.lightGray,",
8650 " closetxt = colors.white,",
8651 " closebg = colors.red,",
8652 " previewtxt = colors.white,",
8653 " previewbg = colors.cyan,",
8654 " findbg = colors.white,",
8655 " findtxt = colors.black,",
8656 " indicatetxt = colors.black,",
8657 " indicatebg = colors.white,",
8658 " theendtxt = colors.gray,",
8659 " scrollbar = {",
8660 " knobbg = colors.black,",
8661 " knobtxt = colors.gray,",
8662 " knobchar = \"|\",",
8663 " barbg = colors.lightGray,",
8664 " bartxt = colors.gray,",
8665 " barchar = \"|\",",
8666 " }",
8667 " },",
8668 " item = {",
8669 " bg = colors.gray,",
8670 " txt = colors.white,",
8671 " specialtxt = colors.yellow,",
8672 " previewtxt = colors.white,",
8673 " previewbg = colors.black,",
8674 " forumtxt = colors.lightGray,",
8675 " forumbg = colors.gray,",
8676 " closetxt = colors.white,",
8677 " closebg = colors.red,",
8678 " runtxt = colors.white,",
8679 " runbg = colors.green,",
8680 " downloadtxt = colors.white,",
8681 " downloadbg = colors.green,",
8682 " },",
8683 " menubar = {",
8684 " bg = colors.black,",
8685 " categorytxt = colors.lightGray,",
8686 " categorybg = colors.black,",
8687 " channeltxt = colors.lightGray,",
8688 " channelbg = colors.black,",
8689 " hotkeytxt = colors.gray,",
8690 " categorymenu = {",
8691 " selecttxt = colors.lightGray,",
8692 " selectbg = colors.black,",
8693 " bg = colors.black,",
8694 " txt = colors.lightGray,",
8695 " orbtxt = colors.black,",
8696 " cursortxt = colors.black,",
8697 " cursorbg = colors.lightGray,",
8698 " borderbg = colors.black,",
8699 " },",
8700 " channelmenu = {",
8701 " selecttxt = colors.lightGray,",
8702 " selectbg = colors.black,",
8703 " bg = colors.lightGray,",
8704 " txt = colors.lightGray,",
8705 " orbtxt = colors.black,",
8706 " cursortxt = colors.black,",
8707 " cursorbg = colors.lightGray,",
8708 " borderbg = colors.black,",
8709 " }",
8710 " }",
8711 "}",
8712 "",
8713 "local getEvents = function(...)",
8714 " local arg, output = table.pack(...)",
8715 " while true do",
8716 " output = {os.pullEvent()}",
8717 " for a = 1, #arg do",
8718 " if type(arg[a]) == \"boolean\" then",
8719 " if doRender == arg[a] then",
8720 " return {}",
8721 " end",
8722 " elseif output[1] == arg[a] then",
8723 " return unpack(output)",
8724 " end",
8725 " end",
8726 " end",
8727 "end",
8728 "",
8729 "local charClear = function(char)",
8730 " local cx,cy = term.getCursorPos()",
8731 " for y = 1, scr_y do",
8732 " term.setCursorPos(1,y)",
8733 " term.write(char:sub(1,1):rep(scr_x))",
8734 " end",
8735 " term.setCursorPos(cx,cy)",
8736 "end",
8737 "",
8738 "std.channelNames = {}",
8739 "for k,v in pairs(std.channelURLs) do",
8740 " table.insert(std.channelNames,k)",
8741 "end",
8742 "",
8743 "std.stdList = \".\"..std.channel:lower()..\"_list\"",
8744 "",
8745 "if (fs.isDir(\"SimSoft/Data\") and fs.isDir(\"SimSoft/SappS\")) and (not overrideNoOS) then --checks if SimSoft is installed",
8746 " isSimSoft = true",
8747 "elseif (fs.isDir(\"Axiom\") and fs.exists(\"Axiom/sys.axs\")) and (not overrideNoOS) then --checks if Axiom is installed",
8748 " isAxiom = true",
8749 "end",
8750 "",
8751 "local cprint = function(txt,y)",
8752 " local cX,cY = term.getCursorPos()",
8753 " term.setCursorPos(math.ceil(scr_x/2)-math.floor(#txt/2),y or cY)",
8754 " term.write(txt)",
8755 "end",
8756 "",
8757 "local scroll = 1 --one is the loneliest number...weaboo",
8758 "local scrollX = 1 --to view longer program names",
8759 "local maxScroll",
8760 "std.std_version = 101 --to prevent updating to std command line",
8761 "",
8762 "local setMaxScroll = function(catagory)",
8763 " local output = 0",
8764 " for k,v in pairs(std.storeURLs) do",
8765 " if (v.catagory == catagory) or catagory == 0 then",
8766 " output = output + 1",
8767 " end",
8768 " end",
8769 " return (output*4)-(scr_y-4)",
8770 "end",
8771 "local catag = 0",
8772 "",
8773 "local pleaseWait = function(text)",
8774 " term.setBackgroundColor(palate.pleasewait.bg)",
8775 " term.setTextColor(palate.pleasewait.txt)",
8776 " term.clear()",
8777 " cprint(text or \"Getting list...please wait\",scr_y/2)",
8778 "end",
8779 "",
8780 "local coolPleaseWait = function()",
8781 " local scr_x, scr_y = term.getSize()",
8782 " local cols = \"f7\"",
8783 " local length = scr_x/2",
8784 " local render = function(col1,col2,prog,forwards)",
8785 " term.setCursorPos(1,1)",
8786 " local screen = (col1:rep(prog)..col2:rep(length-prog)):rep(scr_x*scr_y):sub(1,(scr_x*scr_y))",
8787 " local line",
8788 " for a = forwards and 1 or scr_y, forwards and scr_y or 1, forwards and 1 or -1 do",
8789 " line = screen:sub((a-1)*scr_x+1,a*scr_x)",
8790 " term.setCursorPos(1,a)",
8791 " term.blit((\"L\"):rep(#line),line,line)",
8792 " end",
8793 " end",
8794 " local pos1 = 2",
8795 " local pos2 = pos1 - 1",
8796 " local forwards = true",
8797 " local reverse = false",
8798 " while true do",
8799 " for a = reverse and length or 1, reverse and 1 or length, reverse and -1 or 1 do",
8800 " render(cols:sub(pos1,pos1),cols:sub(pos2,pos2),a,forwards)",
8801 " sleep(0.0)",
8802 " end",
8803 " forwards = not forwards",
8804 " reverse = not reverse",
8805 " pos1 = (pos1 + 1)",
8806 " pos2 = (pos2 + 1)",
8807 " if pos1 > #cols then pos1 = 1 end",
8808 " if pos2 > #cols then pos2 = 1 end",
8809 " end",
8810 "end",
8811 "",
8812 "local setDefaultColors = function()",
8813 " term.setBackgroundColor(palate.store.bg)",
8814 " term.setTextColor(palate.store.txt)",
8815 "end",
8816 "",
8817 "local displayHelp = function(cli)",
8818 " local helptext = [[",
8819 "This is a graphical interface to the STD downloader program.",
8820 "Use 'stdgui update' to update the list, or use 'F5'.",
8821 "If you want your program on it, PM LDDestroier on the CC forums.",
8822 "Hotkeys:",
8823 " 'Q' quit or back",
8824 " 'F5' refresh",
8825 " 'F1' set category",
8826 " 'F3' set channel",
8827 " 'F' or 'F6' search",
8828 " 'F12' update STDGUI",
8829 " if normal computer, press 0-9 to select store item",
8830 "]]",
8831 " if cli then",
8832 " return print(helptext)",
8833 " else",
8834 " setDefaultColors()",
8835 " term.clear()",
8836 " term.setCursorPos(2,2)",
8837 " print(helptext)",
8838 " sleep(0)",
8839 " print(\"\\nPress a key to go back.\")",
8840 " os.pullEvent(\"key\")",
8841 " return",
8842 " end",
8843 "end",
8844 "",
8845 "local getTableSize = function(tbl)",
8846 " local amnt = 0",
8847 " for k,v in pairs(tbl) do",
8848 " amnt = amnt + 1",
8849 " end",
8850 " return amnt",
8851 "end",
8852 "",
8853 "local colors_names = {",
8854 " [\"0\"] = colors.white,",
8855 " [\"1\"] = colors.orange,",
8856 " [\"2\"] = colors.magenta,",
8857 " [\"3\"] = colors.lightBlue,",
8858 " [\"4\"] = colors.yellow,",
8859 " [\"5\"] = colors.lime,",
8860 " [\"6\"] = colors.pink,",
8861 " [\"7\"] = colors.gray,",
8862 " [\"8\"] = colors.lightGray,",
8863 " [\"9\"] = colors.cyan,",
8864 " [\"a\"] = colors.purple,",
8865 " [\"b\"] = colors.blue,",
8866 " [\"c\"] = colors.brown,",
8867 " [\"d\"] = colors.green,",
8868 " [\"e\"] = colors.red,",
8869 " [\"f\"] = colors.black,",
8870 "}",
8871 "",
8872 "local blit_names = {}",
8873 "for k,v in pairs(colors_names) do",
8874 " blit_names[v] = k",
8875 "end",
8876 "",
8877 "local codeNames = { --just for checking, not for any translation",
8878 " [\"r\"] = \"reset\",",
8879 " [\"{\"] = \"stopFormatting\",",
8880 " [\"}\"] = \"startFormatting\",",
8881 "}",
8882 "",
8883 "local explode = function(div,str)",
8884 " if (div=='') then return false end",
8885 " local pos,arr = 0,{}",
8886 " for st,sp in function() return string.find(str,div,pos,true) end do",
8887 " table.insert(arr,string.sub(str,pos,st-1))",
8888 " pos = sp + 1",
8889 " end",
8890 " table.insert(arr,string.sub(str,pos))",
8891 " return arr",
8892 "end",
8893 "",
8894 "local blitWrap = function(text,txt,bg)",
8895 " local allIssues = \"\"",
8896 " if not text then allIssues = allIssues..\"no text, \" end",
8897 " if not txt then allIssues = allIssues..\"no txt, \" end",
8898 " if not bg then allIssues = allIssues..\"no bg, \" end",
8899 " if not (#text == #txt and #txt == #bg) then allIssues = allIssues..\"incongruent lengths\" end",
8900 " if #allIssues > 0 then error(allIssues) end",
8901 " local wordNo = 1",
8902 " local words = explode(\" \",text)",
8903 " local lines = 0",
8904 " local scr_x, scr_y = term.getSize()",
8905 " local cx,cy",
8906 " for a = 1, #text do",
8907 " cx,cy = term.getCursorPos()",
8908 " if text:sub(a,a) == \" \" and text:sub(a-1,a-1) ~= \" \" and a > 1 then",
8909 " wordNo = wordNo + 1",
8910 " if cx + #words[wordNo] > scr_x then",
8911 " term.setCursorPos(1,cy+1)",
8912 " lines = lines + 1",
8913 " end",
8914 " end",
8915 " cx,cy = term.getCursorPos()",
8916 " if text:sub(a,a) == \"\\n\" then",
8917 " term.setCursorPos(1,cy+1)",
8918 " lines = lines + 1",
8919 " elseif not (cx == 1 and text:sub(a,a) == \" \") then",
8920 " term.blit(text:sub(a,a),txt:sub(a,a),bg:sub(a,a))",
8921 " end",
8922 " if cx == scr_x then",
8923 " term.setCursorPos(1,cy+1)",
8924 " lines = lines + 1",
8925 " end",
8926 " end",
8927 " return lines",
8928 "end",
8929 "",
8930 "local moveOn, textToBlit",
8931 "textToBlit = function(str,substart,substop)",
8932 " local p = 1",
8933 " local output = \"\"",
8934 " local txcolorout = \"\"",
8935 " local bgcolorout = \"\"",
8936 " local txcode = \"&\"",
8937 " local bgcode = \"~\"",
8938 " local doFormatting = true",
8939 " local usedformats = {}",
8940 " local txcol,bgcol = blit_names[term.getTextColor()], blit_names[term.getBackgroundColor()]",
8941 " local origTX,origBG = blit_names[term.getTextColor()], blit_names[term.getBackgroundColor()]",
8942 " local cx,cy,barestr",
8943 " substart = substart or 0",
8944 " substop = substop or #str",
8945 " if not (substart == 0 and substop == #str) then",
8946 " barestr = textToBlit(str)",
8947 " else",
8948 " if substart < 0 then",
8949 " substart = #realstr - substart",
8950 " end",
8951 " if substop < 0 then",
8952 " substop = #realstr - substop",
8953 " end",
8954 " end",
8955 " moveOn = function(tx,bg)",
8956 " if p >= substart and p <= substop then",
8957 " output = output..str:sub(p,p)",
8958 " txcolorout = txcolorout..tx",
8959 " bgcolorout = bgcolorout..bg",
8960 " end",
8961 " end",
8962 " while p <= #str do",
8963 " if str:sub(p,p) == txcode then",
8964 " if colors_names[str:sub(p+1,p+1)] and doFormatting then",
8965 " txcol = str:sub(p+1,p+1)",
8966 " usedformats.txcol = true",
8967 " p = p + 1",
8968 " elseif codeNames[str:sub(p+1,p+1)] then",
8969 " if str:sub(p+1,p+1) == \"r\" and doFormatting then",
8970 " txcol = blit_names[term.getTextColor()]",
8971 " p = p + 1",
8972 " elseif str:sub(p+1,p+1) == \"{\" and doFormatting then",
8973 " doFormatting = false",
8974 " p = p + 1",
8975 " elseif str:sub(p+1,p+1) == \"}\" and (not doFormatting) then",
8976 " doFormatting = true",
8977 " p = p + 1",
8978 " else",
8979 " moveOn(txcol,bgcol)",
8980 " end",
8981 " else",
8982 " moveOn(txcol,bgcol)",
8983 " end",
8984 " p = p + 1",
8985 " elseif str:sub(p,p) == bgcode then",
8986 " if colors_names[str:sub(p+1,p+1)] and doFormatting then",
8987 " bgcol = str:sub(p+1,p+1)",
8988 " usedformats.bgcol = true",
8989 " p = p + 1",
8990 " elseif codeNames[str:sub(p+1,p+1)] and (str:sub(p+1,p+1) == \"r\") and doFormatting then",
8991 " bgcol = blit_names[term.getBackgroundColor()]",
8992 " p = p + 1",
8993 " else",
8994 " moveOn(txcol,bgcol)",
8995 " end",
8996 " p = p + 1",
8997 " else",
8998 " moveOn(txcol,bgcol)",
8999 " p = p + 1",
9000 " end",
9001 " end",
9002 " return output, txcolorout, bgcolorout, usedformats",
9003 "end",
9004 "",
9005 "local writef = function(txt,noWrite,substart,substop)",
9006 " if doColorize then",
9007 " local text, textCol, bgCol, usedformats = textToBlit(txt,substart,substop)",
9008 " local out = blitWrap(text,textCol,bgCol,noWrite)",
9009 " return out, #text, usedformats",
9010 " else",
9011 " if noWrite then",
9012 " local cx,cy = term.getCursorPos()",
9013 " return math.floor((cx+#cf(txt))/scr_x), #cf(txt), {} --this is approximate, and might mess up with multiline strings",
9014 " else",
9015 " return write(txt), #txt, {}",
9016 " end",
9017 " end",
9018 "end",
9019 "",
9020 "local printf = function(txt,noWrite)",
9021 " return writef(tostring(txt..\"\\n\"),noWrite)",
9022 "end",
9023 "",
9024 "local runURL = function(url, ...)",
9025 " local program = http.get(url)",
9026 " if not program then return false end",
9027 " program = program.readAll()",
9028 " local func = load(program)",
9029 " setfenv(func, getfenv())",
9030 " return func(...)",
9031 "end",
9032 "",
9033 "local bow = function()",
9034 " term.setBackgroundColor(palate.store.findbg)",
9035 " term.setTextColor(palate.store.findtxt)",
9036 "end",
9037 "",
9038 "local strless = function(str,txt,bg)",
9039 " local x,y = 0,0",
9040 " local shiftDown = false",
9041 " local str = explode(\"\\n\",str or \"\")",
9042 " local render = function()",
9043 " term.setBackgroundColor(bg)",
9044 " term.setTextColor(txt)",
9045 " for i = y+1, (scr_y+y)-1 do",
9046 " term.setCursorPos(math.max(1,-x),i-y)",
9047 " term.clearLine()",
9048 " if str[i] then",
9049 " term.write(str[i]:sub(math.max(1,x+1)))",
9050 " end",
9051 " end",
9052 " term.setCursorPos(1,scr_y)",
9053 " term.setBackgroundColor(colors.gray)",
9054 " term.setTextColor(colors.white)",
9055 " term.clearLine()",
9056 " term.write(\"(Q)uit, Goto (L)ine\")",
9057 " local ting = \"Ln.\"..math.min(math.max(y+1,0),#str)",
9058 " term.setCursorPos((scr_x-#ting)+1,scr_y)",
9059 " term.write(ting)",
9060 " end",
9061 " render()",
9062 " maxY = (#str-scr_y)+1",
9063 " while true do",
9064 " local evt, key, mx, my = os.pullEvent()",
9065 " local oldY = y",
9066 " local oldX = x",
9067 " if evt == \"key\" then",
9068 " if key == keys.leftShift then",
9069 " shiftDown = true",
9070 " elseif key == keys.up then",
9071 " y = y-1",
9072 " elseif key == keys.down then",
9073 " y = y+1",
9074 " elseif key == keys.pageUp then",
9075 " y = y-(scr_y-1)",
9076 " elseif key == keys.pageDown then",
9077 " y = y+(scr_y-1)",
9078 " elseif key == keys.left then",
9079 " x = x-1",
9080 " elseif key == keys.right then",
9081 " x = x+1",
9082 " elseif key == keys.home then",
9083 " y = 0",
9084 " elseif key == keys[\"end\"] then",
9085 " y = maxY",
9086 " elseif (key == keys.q) or (key == keys.x) then",
9087 " sleep(0)",
9088 " break",
9089 " elseif (key == keys.l) then",
9090 " term.setCursorPos(1,scr_y)",
9091 " term.setBackgroundColor(colors.gray)",
9092 " term.setTextColor(colors.white)",
9093 " term.clearLine()",
9094 " term.write(\"Line #:\")",
9095 " sleep(0)",
9096 " y = (tonumber(read()) or (y+1)) - 1",
9097 " end",
9098 " elseif evt == \"key_up\" then",
9099 " if key == keys.leftShift then",
9100 " shiftDown = false",
9101 " end",
9102 " elseif evt == \"mouse_scroll\" then",
9103 " if shiftDown then",
9104 " x = x + key",
9105 " else",
9106 " y = y + key",
9107 " end",
9108 " elseif evt == \"mouse_click\" and key == 1 then",
9109 " if my == scr_y and (mx >= 1 and mx <= 11) then",
9110 " sleep(0)",
9111 " break",
9112 " end",
9113 " end",
9114 " if x < 0 then x = 0 end",
9115 " if y < 0 then y = 0 end",
9116 " if y > maxY then y = maxY end",
9117 " if (x ~= oldX) or (y ~= oldY) or (key == keys.l) then",
9118 " render()",
9119 " end",
9120 " end",
9121 "end",
9122 "local contentsFile = function(url)",
9123 " local prog = http.get(url)",
9124 " if prog then return prog.readAll()",
9125 " else return false, \"could not connect\" end",
9126 "end",
9127 "local getFile = function(filename,url)",
9128 " if fs.isReadOnly(filename) then",
9129 " return false, \"access denied\"",
9130 " end",
9131 " local prog",
9132 " if type(url) == \"table\" then",
9133 " prog = std.contextualGet(url[1])",
9134 " else",
9135 " prog = http.get(url)",
9136 " end",
9137 " if not prog then",
9138 " return false, \"could not connect\"",
9139 " end",
9140 " prog = prog.readAll()",
9141 " local fyle = fs.open(filename,\"w\")",
9142 " fyle.write(prog)",
9143 " fyle.close()",
9144 " return true, fs.getSize(filename)",
9145 "end",
9146 "local runFile = function(path, ...)",
9147 " if not fs.exists(path) then",
9148 " return false, \"No such file!\"",
9149 " end",
9150 " local file = fs.open(path,\"r\")",
9151 " local contents = file.readAll()",
9152 " file.close()",
9153 " local func = load(contents, nil, nil, _ENV)",
9154 " return func(...)",
9155 "end",
9156 "std.getSTDList = function(prevChannel)",
9157 " catag = 0",
9158 " local url = std.channelURLs[std.channel] --URL of URL list for whatever channel you have selected.",
9159 " pleaseWait()",
9160 " local outcome, size = getFile(std.stdList, std.channelURLs[std.channel])",
9161 " if not outcome then",
9162 " if shell then",
9163 " print(\"Couldn't update list!\")",
9164 " end",
9165 " return false, \"Couldn't update list!\"",
9166 " else",
9167 " local outcome = runFile(std.stdList)",
9168 " if outcome == false then",
9169 " term.setBackgroundColor(colors.black)",
9170 " term.setTextColor(term.isColor() and colors.red or colors.lightGray)",
9171 " term.clear()",
9172 " cprint(\"STD channel \\\"\"..std.channel..\"\\\" is down right now.\",2)",
9173 " term.setTextColor(colors.white)",
9174 " cprint(\"Either try again later,\",4)",
9175 " cprint(\"contact LDDestroier on the CC forums,\",5)",
9176 " cprint(\"or tell the owner of the channel.\",6)",
9177 " cprint(\"Press a key to go back.\",8)",
9178 " term.setTextColor(colors.gray)",
9179 " cprint(\"Sorry bout that!\",scr_y)",
9180 " std.channel = prevChannel",
9181 " sleep(0.1)",
9182 " os.pullEvent(\"char\")",
9183 " pleaseWait(\"Changing list...please wait...\")",
9184 " return std.getSTDList(\"STD\")",
9185 " end",
9186 " local output",
9187 " if not fs.isReadOnly(std.stdList) then",
9188 " output = \"Downloaded to \"..std.stdList",
9189 " else",
9190 " output = \"Got store codes.\"",
9191 " end",
9192 " maxScroll = setMaxScroll(catag)",
9193 " return true, output",
9194 " end",
9195 "end",
9196 "",
9197 "local cisf = function(str,fin)",
9198 " fin = fin:gsub(\"%[\",\"%%[\"):gsub(\"%(\",\"%%(\"):gsub(\"%]\",\"%%]\"):gsub(\"%)\",\"%%)\")",
9199 " return string.find(str:lower(),fin:lower())",
9200 "end",
9201 "",
9202 "local clearMostline = function(length,char)",
9203 " local pX,pY = term.getCursorPos()",
9204 " term.setCursorPos(1,pY)",
9205 " term.write(string.rep(char or \" \",length or (scr_x-1)))",
9206 " term.setCursorPos(pX,pY)",
9207 "end",
9208 "",
9209 "local dotY",
9210 "local doScrollBar = false",
9211 "",
9212 "local renderStore = function(list,filter,scrollY,namescroll,fixedDotY,buttonIndicate)",
9213 " local fullrend = {}",
9214 " local visiblerend = {}",
9215 " local amnt = 0",
9216 " local output = {}",
9217 " local colors_output = {}",
9218 " local num = 0",
9219 " if tsv then tsv(false) end",
9220 " for k,v in pairs(list) do",
9221 " if (v.catagory == filter) or filter == 0 then",
9222 " table.insert(fullrend,{\" &\"..blit_names[palate.store.entryasterisk]..\"*&\"..blit_names[palate.store.entrytxt]..v.title,v})",
9223 " table.insert(fullrend,{\" by &r\"..v.creator,v})",
9224 " table.insert(fullrend,{\" Category: \"..std.storeCatagoryNames[v.catagory],v,v.catagory})",
9225 " table.insert(fullrend,\"nilline\")",
9226 " end",
9227 " end",
9228 " table.insert(fullrend,\"\")",
9229 " dotY = fixedDotY or math.floor((scr_y-2)*((scroll-1)/(maxScroll-1)))+2",
9230 " for a = scrollY, (scr_y+scrollY)-1 do",
9231 " if type(fullrend[a]) == \"table\" then",
9232 " table.insert(visiblerend,fullrend[a][1])",
9233 " table.insert(output,fullrend[a][2])",
9234 " if fullrend[a][3] then",
9235 " table.insert(colors_output,fullrend[a][3])",
9236 " else",
9237 " table.insert(colors_output,false)",
9238 " end",
9239 " else",
9240 " table.insert(visiblerend,fullrend[a])",
9241 " table.insert(output,{})",
9242 " table.insert(colors_output,false)",
9243 " end",
9244 " end",
9245 " setDefaultColors()",
9246 " charClear(palate.store.bgchar)",
9247 " for a = 1, #visiblerend do",
9248 " term.setCursorPos(2-namescroll,a+1)",
9249 " if visiblerend[a] == \"nilline\" then",
9250 " setDefaultColors()",
9251 " clearMostline()",
9252 " else",
9253 " if a < #visiblerend then",
9254 " if term.isColor() then",
9255 " if colors_output[a] then",
9256 " term.setBackgroundColor(std.storeCatagoryColors[colors_output[a]].bg)",
9257 " term.setTextColor(std.storeCatagoryColors[colors_output[a]].txt)",
9258 " else",
9259 " term.setBackgroundColor(palate.store.entrybg)",
9260 " term.setTextColor(palate.store.entrytxt)",
9261 " end",
9262 " else",
9263 " term.setBackgroundColor(colors.gray)",
9264 " term.setTextColor(colors.white)",
9265 " end",
9266 " clearMostline()",
9267 " writef(visiblerend[a])",
9268 " else",
9269 " term.setBackgroundColor(palate.store.bg)",
9270 " term.setTextColor(palate.store.theendtxt)",
9271 " cprint(\"That's them all!\")",
9272 " end",
9273 " end",
9274 " end",
9275 " local b",
9276 " for a = 2, scr_y do",
9277 " term.setCursorPos(scr_x,a)",
9278 " if a == dotY then",
9279 " term.setTextColor(palate.store.scrollbar.knobtxt)",
9280 " term.setBackgroundColor(palate.store.scrollbar.knobbg)",
9281 " term.write(palate.store.scrollbar.knobchar)",
9282 " else",
9283 " term.setTextColor(palate.store.scrollbar.bartxt)",
9284 " term.setBackgroundColor(palate.store.scrollbar.barbg)",
9285 " term.write(palate.store.scrollbar.barchar)",
9286 " end",
9287 " if buttonIndicate then",
9288 " term.setCursorPos(scr_x-4,a)",
9289 " term.setBackgroundColor(palate.store.indicatebg)",
9290 " term.setTextColor(palate.store.indicatetxt)",
9291 " b = (a+1)/4",
9292 " if (b == math.floor(b)) and (visiblerend[a] and visiblerend[a] ~= \"nilline\") then",
9293 " term.write(\" \"..tostring(b):sub(#tostring(b))..\" \")",
9294 " end",
9295 " end",
9296 " end",
9297 " if tsv then tsv(true) end",
9298 " return output",
9299 "end",
9300 "",
9301 "local simSoftInstall = function(obj,objname,appname)",
9302 " local installSystemName = \"STD App Distribution (sad...)\"",
9303 " appname = appname or objname",
9304 " local getFromURL = function(url)",
9305 " local cunt",
9306 " if type(url) == \"table\" then",
9307 " cunt = std.contextualGet(url[1])",
9308 " else",
9309 " cunt = http.get(url)",
9310 " end",
9311 " if not cunt then",
9312 " return shit",
9313 " else",
9314 " if type(url) == \"table\" then",
9315 " return cunt.readAll(), false",
9316 " else",
9317 " return cunt.readAll(), (string.find(url,\"://pastebin.com/raw/\") and (url:sub(-9):gsub(\"/\",\"\")) or false)",
9318 " end",
9319 " end",
9320 " end",
9321 " local mainpath = fs.combine(\"/SimSoft/SappS\",objname)",
9322 " local cont,pbcode = getFromURL(obj.url)",
9323 " local file = fs.open(\"\\\"\"..fs.combine(mainpath,pbcode or \"program\")..\"\\\"\",\"w\")",
9324 " file.write(cont)",
9325 " file.close()",
9326 " local file = fs.open(fs.combine(mainpath,\"SappS\"),\"w\")",
9327 " file.writeLine(installSystemName)",
9328 " file.writeLine(\"\\\"\"..fs.combine(mainpath,pbcode or \"program\")..\"\\\"\")",
9329 " file.writeLine(appname:sub(1,9))",
9330 " file.close()",
9331 " return true, \"Installed!\"",
9332 "end",
9333 "",
9334 "local getFindList = function(name)",
9335 " local output = {}",
9336 " for k,v in pairs(std.storeURLs) do",
9337 " if cisf(k,name) or cisf(textToBlit(v.title),name) or cisf(textToBlit(v.creator),name) then",
9338 " output[k] = v",
9339 " end",
9340 " if output[k] ~= v and v.keywords then",
9341 " for a = 1, #v.keywords do",
9342 " if cisf(v.keywords[a],name) then",
9343 " output[k] = v",
9344 " break",
9345 " end",
9346 " end",
9347 " end",
9348 " end",
9349 " return output",
9350 "end",
9351 "",
9352 "local doFindFunc = function(name)",
9353 " scroll = 1",
9354 " maxScroll = setMaxScroll(catag)",
9355 " renderStore(getFindList(name),catag,scroll,scrollX,_,not term.isColor())",
9356 " term.setCursorPos(1,1)",
9357 " bow()",
9358 " term.clearLine()",
9359 " write(\"Find: \")",
9360 "end",
9361 "",
9362 "local funcread = function(repchar,rHistory,doFunc,noNewLine)",
9363 " local scr_x,scr_y = term.getSize()",
9364 " local sx,sy = term.getCursorPos()",
9365 " local cursor = 1",
9366 " rHistory = rHistory or {}",
9367 " local rCursor = #rHistory+1",
9368 " local output = \"\"",
9369 " term.setCursorBlink(true)",
9370 " while true do",
9371 " local evt,key = os.pullEvent()",
9372 " local cx,cy = term.getCursorPos()",
9373 " if evt == \"key\" then",
9374 " if key == keys.enter then",
9375 " if not noNewLine then",
9376 " write(\"\\n\")",
9377 " end",
9378 " term.setCursorBlink(false)",
9379 " return output",
9380 " elseif key == keys.left then",
9381 " if cursor-1 >= 1 then",
9382 " cursor = cursor - 1",
9383 " end",
9384 " elseif key == keys.right then",
9385 " if cursor <= #output then",
9386 " cursor = cursor + 1",
9387 " end",
9388 " elseif key == keys.up then",
9389 " if rCursor > 1 then",
9390 " rCursor = rCursor - 1",
9391 " term.setCursorPos(sx,sy)",
9392 " term.write((\" \"):rep(#output))",
9393 " output = rHistory[rCursor] or \"\"",
9394 " cursor = #output+1",
9395 " pleaseDoFunc = true",
9396 " end",
9397 " elseif key == keys.down then",
9398 " term.setCursorPos(sx,sy)",
9399 " term.write((\" \"):rep(#output))",
9400 " if rCursor < #rHistory then",
9401 " rCursor = rCursor + 1",
9402 " output = rHistory[rCursor] or \"\"",
9403 " cursor = #output+1",
9404 " pleaseDoFunc = true",
9405 " else",
9406 " rCursor = #rHistory+1",
9407 " output = \"\"",
9408 " cursor = 1",
9409 " end",
9410 " elseif key == keys.backspace then",
9411 " if cursor > 1 and #output > 0 then",
9412 " output = output:sub(1,cursor-2)..output:sub(cursor)",
9413 " cursor = cursor - 1",
9414 " pleaseDoFunc = true",
9415 " end",
9416 " elseif key == keys.delete then",
9417 " if #output:sub(cursor,cursor) == 1 then",
9418 " output = output:sub(1,cursor-1)..output:sub(cursor+1)",
9419 " pleaseDoFunc = true",
9420 " end",
9421 " end",
9422 " elseif evt == \"char\" or evt == \"paste\" then",
9423 " output = output:sub(1,cursor-1)..key..output:sub(cursor+(#key-1))",
9424 " cursor = cursor + #key",
9425 " pleaseDoFunc = true",
9426 " end",
9427 " if pleaseDoFunc then",
9428 " pleaseDoFunc = false",
9429 " if type(doFunc) == \"function\" then",
9430 " doFunc(output)",
9431 " end",
9432 " term.setCursorPos(sx,sy)",
9433 " local pOut = output",
9434 " if #output >= scr_x-(sx-2) then",
9435 " pOut = output:sub((#output+(sx))-scr_x)",
9436 " end",
9437 " if repchar then",
9438 " term.write(repchar:sub(1,1):rep(#pOut)..\" \")",
9439 " else",
9440 " term.write(pOut..\" \")",
9441 " end",
9442 " local cx,cy = term.getCursorPos()",
9443 " end",
9444 " term.setCursorPos(sx+cursor-1,cy)",
9445 " end",
9446 "end",
9447 "",
9448 "local prevList",
9449 "local findPrompt = function()",
9450 " local cX,cY = term.getCursorPos()",
9451 " sleep(0)",
9452 " if prevList then std.storeURLs = prevList end",
9453 " doFindFunc(\"\")",
9454 " prevList = std.storeURLs",
9455 " std.storeURLs = getFindList(funcread(nil,{},doFindFunc,false))",
9456 " term.setCursorBlink(false)",
9457 " maxScroll = setMaxScroll(catag)",
9458 "end",
9459 "",
9460 "local displayTitle = function()",
9461 " local title = {{},{},{},{},{0,0,0,0,0,1,1,1,1,1,0,0,2,2,2,2,2,2,2,0,2,2,2,2,0,0,32768,},{0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,2,0,0,0,0,0,2,0,2,2,0,32768,},{0,0,0,0,1,0,0,0,0,0,1,0,0,0,2,2,0,0,0,0,2,2,0,0,2,0,32768,},{0,0,0,0,1,1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,2,0,32768,},{0,0,0,0,0,1,1,1,1,1,0,0,0,0,2,0,0,0,0,2,2,0,0,2,2,0,32768,},{0,0,0,0,0,0,0,0,0,1,0,0,0,2,2,0,0,0,2,2,0,0,2,2,0,0,32768,},{0,0,0,1,1,0,0,0,1,1,0,0,2,2,0,0,0,2,2,0,0,2,2,0,0,32768,1,},{0,0,0,0,1,1,1,1,1,0,0,0,2,0,0,0,2,2,2,2,2,2,0,0,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32768,1,1,1,},{0,0,0,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,1,1,1}}",
9462 " setDefaultColors()",
9463 " term.clear()",
9464 " paintutils.drawImage(title,-1,1)",
9465 " setDefaultColors()",
9466 " term.setCursorPos(4,16)",
9467 " term.write(\"STD-GUI \"..(isBeta and \"Beta\" or \"Stable\"))",
9468 " sleep(0)",
9469 " local evt",
9470 " repeat",
9471 " evt = os.pullEvent()",
9472 " until evt == \"mouse_click\" or evt == \"key\"",
9473 " sleep(0)",
9474 "end",
9475 "",
9476 "local fixDotY",
9477 "",
9478 "local renderStoreItem = function(obj) --now being experimented on...",
9479 " if not obj.title then return false end",
9480 " local showPostURL = false",
9481 " local bruffer",
9482 " local scroll = 1",
9483 " local doRedraw = true",
9484 " local extraLines",
9485 " while true do",
9486 " bruffer = {",
9487 " \"\",",
9488 " \" &\"..blit_names[palate.item.specialtxt]..obj.title,",
9489 " \" &\"..blit_names[palate.item.txt]..\"by &\"..blit_names[palate.item.specialtxt]..obj.creator,",
9490 " \" &\"..blit_names[palate.item.txt]..\"Category: \"..std.storeCatagoryNames[obj.catagory],",
9491 " \"\",",
9492 " \"&\"..blit_names[palate.item.txt]..obj.description,",
9493 " }",
9494 " if showPostURL and obj.forumPost then",
9495 " local post = \" &\"..blit_names[palate.item.forumtxt]..\"~\"..blit_names[palate.item.forumbg]..obj.forumPost:gsub(\"http://www.\",\"\"):sub(1,-2)",
9496 " table.insert(bruffer,\"&8Forum URL: \"..post)",
9497 " end",
9498 " if doRedraw then",
9499 " term.setBackgroundColor(palate.item.bg)",
9500 " term.clear()",
9501 " term.setCursorPos(1,(-scroll)+2)",
9502 " extraLines = 0",
9503 " for y = 1, #bruffer do",
9504 " if not bruffer[y] then break end",
9505 " extraLines = extraLines + printf(bruffer[y])",
9506 " end",
9507 " ",
9508 " term.setCursorPos(1,scr_y)",
9509 " if term.isColor() then",
9510 " term.setTextColor(palate.item.closetxt)",
9511 " term.setBackgroundColor(palate.item.closebg)",
9512 " else",
9513 " term.setTextColor(colors.black)",
9514 " term.setBackgroundColor(colors.white)",
9515 " end",
9516 " term.clearLine()",
9517 " if term.isColor() then",
9518 " term.write(\"CLOSE\")",
9519 " else",
9520 " term.write(\"(Q) to CLOSE\")",
9521 " end",
9522 " if term.isColor() then",
9523 " term.setTextColor(palate.store.previewtxt)",
9524 " term.setBackgroundColor(palate.store.previewbg)",
9525 " term.setCursorPos((scr_x-16),scr_y)",
9526 " term.write(\"VIEW\")",
9527 " term.setTextColor(palate.item.runtxt)",
9528 " term.setBackgroundColor(palate.item.runbg)",
9529 " term.setCursorPos((scr_x-11),scr_y)",
9530 " term.write(\"RUN\")",
9531 " else",
9532 " term.setTextColor(colors.black)",
9533 " term.setBackgroundColor(colors.white)",
9534 " term.setCursorPos((scr_x-22),scr_y)",
9535 " term.write(\"(V)IEW\")",
9536 " term.setTextColor(colors.black)",
9537 " term.setBackgroundColor(colors.white)",
9538 " term.setCursorPos((scr_x-15),scr_y)",
9539 " term.write(\"(R)UN\")",
9540 " end",
9541 " local txt",
9542 " if isSimSoft or isAxiom then",
9543 " if term.isColor() then --yeah yeah, simsoft can't run on normal computers, but axiom can, so shut your cunting trap",
9544 " term.setTextColor(palate.item.downloadtxt)",
9545 " term.setBackgroundColor(palate.item.downloadbg)",
9546 " txt = \"INSTALL!\"",
9547 " else",
9548 " txt = \"(I)NSTALL\"",
9549 " end",
9550 " else",
9551 " if term.isColor() then",
9552 " term.setTextColor(palate.item.downloadtxt)",
9553 " term.setBackgroundColor(palate.item.downloadbg)",
9554 " txt = \"DOWNLOAD\"",
9555 " else",
9556 " txt = \"(D)OWNLOAD\"",
9557 " end",
9558 " end",
9559 " term.setCursorPos((scr_x-(#txt-1)),scr_y)",
9560 " term.write(txt)",
9561 " doRedraw = false",
9562 " end",
9563 " local evt = {getEvents(\"key\",\"mouse_click\",\"mouse_scroll\",\"term_resize\")}",
9564 " if evt[1] == \"key\" then",
9565 " if evt[2] == keys.f then",
9566 " showPostURL = not showPostURL",
9567 " doRedraw = true",
9568 " elseif evt[2] == keys.d or evt[2] == keys.i or evt[2] == keys.r or evt[2] == keys.q or evt[2] == keys.v then",
9569 " return unpack(evt)",
9570 " end",
9571 " elseif evt[1] == \"mouse_click\" then",
9572 " if evt[4] == scr_y then",
9573 " return unpack(evt)",
9574 " end",
9575 " elseif evt[1] == \"mouse_scroll\" then",
9576 " if scroll+evt[2] >= 1 and scroll+evt[2] <= (#bruffer+extraLines)-(scr_y-8) then",
9577 " scroll = scroll + evt[2]",
9578 " doRedraw = true",
9579 " end",
9580 " elseif evt[1] == \"term_resize\" then",
9581 " doRedraw = true",
9582 " scr_x,scr_y = term.getSize()",
9583 " end",
9584 " end",
9585 "end",
9586 "",
9587 "local renderCatagoryMenu = function(expanded,cursor)",
9588 " if expanded then",
9589 " term.setCursorPos(1,1)",
9590 " term.setBackgroundColor(palate.menubar.bg)",
9591 " term.clearLine()",
9592 " term.setBackgroundColor(palate.menubar.categorymenu.selectbg)",
9593 " term.setTextColor(palate.menubar.categorymenu.selecttxt)",
9594 " if term.isColor() then",
9595 " if cursor == 0 then",
9596 " term.setTextColor(palate.menubar.categorymenu.txt)",
9597 " term.write(\" No category\")",
9598 " else",
9599 " term.write(\"Select category:\")",
9600 " end",
9601 " else",
9602 " term.setCursorPos(1,1)",
9603 " if cursor == 0 then",
9604 " term.setTextColor(palate.menubar.categorymenu.txt)",
9605 " term.write(\" No category\")",
9606 " else",
9607 " term.write(\" Pick category with up/down:\")",
9608 " end",
9609 " end",
9610 " term.setTextColor(palate.menubar.categorymenu.txt)",
9611 " term.setBackgroundColor(palate.menubar.categorymenu.bg)",
9612 " local yposes = {}",
9613 " local longestLen = 0",
9614 " for a = 1, #std.storeCatagoryNames do",
9615 " if #std.storeCatagoryNames[a]+2 > longestLen then",
9616 " longestLen = #std.storeCatagoryNames[a]+2",
9617 " end",
9618 " end",
9619 " longestLen = longestLen+1",
9620 " for a = 0, #std.storeCatagoryNames do",
9621 " term.setCursorPos(1,a+1)",
9622 " if term.isColor() then",
9623 " term.setTextColor(palate.menubar.categorymenu.orbtxt)",
9624 " term.setBackgroundColor(palate.menubar.categorymenu.bg)",
9625 " if type(std.storeCatagoryColors) == \"table\" then",
9626 " if std.storeCatagoryColors[a] then",
9627 " term.setTextColor(std.storeCatagoryColors[a].txt)",
9628 " term.setBackgroundColor(std.storeCatagoryColors[a].bg)",
9629 " end",
9630 " end",
9631 " else",
9632 " term.setTextColor(colors.black)",
9633 " term.setBackgroundColor(colors.lightGray)",
9634 " end",
9635 " if a > 0 then",
9636 " clearMostline(longestLen+2)",
9637 " end",
9638 " if a == cursor then",
9639 " if type(std.storeCatagoryColors) ~= \"table\" then",
9640 " if term.isColor() then",
9641 " if cursor == 0 then",
9642 " term.setTextColor(palate.menubar.categorymenu.txt)",
9643 " term.setBackgroundColor(palate.menubar.categorymenu.bg)",
9644 " else",
9645 " term.setTextColor(palate.menubar.categorymenu.cursortxt)",
9646 " term.setBackgroundColor(palate.menubar.categorymenu.cursorbg)",
9647 " end",
9648 " else",
9649 " term.setTextColor(colors.black)",
9650 " term.setBackgroundColor(colors.lightGray)",
9651 " end",
9652 " elseif cursor == 0 then",
9653 " term.setBackgroundColor(colors.black)",
9654 " end",
9655 " write(\">\")",
9656 " elseif a > 0 then",
9657 " write(\" \")",
9658 " end",
9659 " if a > 0 then",
9660 " if type(std.storeCatagoryColors) ~= \"table\" then",
9661 " term.setTextColor(palate.menubar.categorymenu.orbtxt)",
9662 " term.setBackgroundColor(palate.menubar.categorymenu.bg)",
9663 " end",
9664 " if a == catag then",
9665 " write(\"@ \")",
9666 " else",
9667 " write(\"O \")",
9668 " end",
9669 " write(std.storeCatagoryNames[a])",
9670 " if term.isColor() then",
9671 " term.setBackgroundColor(palate.menubar.categorymenu.borderbg)",
9672 " else",
9673 " term.setBackgroundColor(colors.black)",
9674 " end",
9675 " term.setCursorPos(longestLen+2,a+1)",
9676 " term.write(\" \")",
9677 " table.insert(yposes,a+1)",
9678 " end",
9679 " end",
9680 " term.setCursorPos(1,#std.storeCatagoryNames+2)",
9681 " term.write((\" \"):rep(longestLen+2))",
9682 " return yposes,longestLen+2",
9683 " else",
9684 " term.setCursorPos(1,1)",
9685 " term.setBackgroundColor(palate.menubar.bg)",
9686 " term.clearLine()",
9687 " term.setTextColor(palate.menubar.categorytxt)",
9688 " term.setBackgroundColor(palate.menubar.categorybg)",
9689 " term.write(\"Cat.\")",
9690 " term.setTextColor(palate.menubar.hotkeytxt)",
9691 " term.write(\"F1\")",
9692 " term.setCursorPos(8,1)",
9693 " term.setTextColor(palate.menubar.channeltxt)",
9694 " term.setBackgroundColor(palate.menubar.channelbg)",
9695 " term.write(\"Chan.\")",
9696 " term.setTextColor(palate.menubar.hotkeytxt)",
9697 " term.write(\"F3\")",
9698 " --writef(\"~f&8Cat.&7F1~r&r ~f&8Chan.&7F3\")",
9699 " end",
9700 " if term.isColor() then",
9701 " term.setCursorPos(scr_x-4,1)",
9702 " term.setBackgroundColor(palate.store.closebg)",
9703 " term.setTextColor(palate.store.closetxt)",
9704 " term.write(\"CLOSE\")",
9705 " else",
9706 " term.setCursorPos(scr_x-11,1)",
9707 " term.setBackgroundColor(colors.black)",
9708 " term.setTextColor(colors.white)",
9709 " term.write(\"'Q' to CLOSE\")",
9710 " end",
9711 " setDefaultColors()",
9712 "end",
9713 "",
9714 "local renderChannelMenu = function(cursor)",
9715 " term.setCursorPos(1,1)",
9716 " term.setBackgroundColor(palate.menubar.bg)",
9717 " term.clearLine()",
9718 " term.setBackgroundColor(palate.menubar.channelmenu.selectbg)",
9719 " term.setTextColor(palate.menubar.channelmenu.selecttxt)",
9720 " term.write(\"Select channel:\")",
9721 " term.setTextColor(palate.menubar.channelmenu.txt)",
9722 " term.setBackgroundColor(palate.menubar.channelmenu.bg)",
9723 " local yposes = {}",
9724 " local longestLen = 0",
9725 " for a = 1, #std.channelNames do",
9726 " if #std.channelNames[a] > longestLen then",
9727 " longestLen = #std.channelNames[a]",
9728 " end",
9729 " end",
9730 " longestLen = longestLen + 4",
9731 " for a = 1, #std.channelNames do",
9732 " term.setBackgroundColor(palate.menubar.channelmenu.bg)",
9733 " term.setCursorPos(1,a+1)",
9734 " clearMostline(longestLen+2)",
9735 " if a == cursor then",
9736 " term.setTextColor(palate.menubar.channelmenu.cursortxt)",
9737 " term.setBackgroundColor(palate.menubar.channelmenu.cursorbg)",
9738 " write(\">\")",
9739 " else",
9740 " write(\" \")",
9741 " end",
9742 " term.setTextColor(palate.menubar.channelmenu.orbtxt)",
9743 " term.setBackgroundColor(palate.menubar.channelmenu.bg)",
9744 " if std.channel == std.channelNames[a] then",
9745 " write(\"@ \")",
9746 " else",
9747 " write(\"O \")",
9748 " end",
9749 " term.write(\" \"..std.channelNames[a])",
9750 " if term.isColor() then",
9751 " term.setBackgroundColor(palate.menubar.channelmenu.borderbg)",
9752 " else",
9753 " term.setBackgroundColor(colors.black)",
9754 " end",
9755 " term.setCursorPos(longestLen+2,a+1)",
9756 " term.write(\" \")",
9757 " table.insert(yposes,{a+1,std.channelNames[a],std.channelURLs[std.channelNames[a]]})",
9758 " end",
9759 " term.setCursorPos(1,#std.channelNames+2)",
9760 " term.write((\" \"):rep(longestLen+2))",
9761 " return yposes,longestLen+2",
9762 "end",
9763 "",
9764 "local tArg = {...}",
9765 "",
9766 "if tArg[1] == \"help\" then",
9767 " return displayHelp(true)",
9768 "elseif tArg[1] == \"upgrade\" then",
9769 " local updateURL = isBeta and \"http://pastebin.com/raw/uMZ23APu\" or \"http://pastebin.com/raw/P9dDhQ2m\"",
9770 " local res, outcome = getFile(shell.getRunningProgram(),updateURL)",
9771 " if not res then",
9772 " error(outcome)",
9773 " else",
9774 " print(\"Updated STD-GUI to latest \"..(isBeta and \"beta.\" or \"stable.\")..\" (\"..outcome..\" bytes)\")",
9775 " return",
9776 " end",
9777 "end",
9778 "",
9779 "local res, outcome",
9780 "if tArg[1] == \"update\" then",
9781 " res, outcome = std.getSTDList(std.prevChannel)",
9782 " print(outcome)",
9783 " return",
9784 "else",
9785 " if not std.storeURLs then",
9786 " pleaseWait() -- he said please",
9787 " res, outcome = std.getSTDList(std.prevChannel)",
9788 " end",
9789 "end",
9790 "",
9791 "local cleanExit = function()",
9792 " term.setTextColor(colors.white)",
9793 " term.setBackgroundColor(colors.black)",
9794 " term.clear()",
9795 " local out",
9796 " if pocket then",
9797 " out = \"Thanks for using STD!\"",
9798 " else",
9799 " out = \"Thank you for using STD-GUI!\"",
9800 " end",
9801 " if isSimSoft or isAxiom then",
9802 " term.setCursorBlink(false)",
9803 " end",
9804 " cprint(out,scr_y/2)",
9805 " term.setCursorPos(1,scr_y)",
9806 " sleep(0)",
9807 " return true, \"This shouldn't be an error.\"",
9808 "end",
9809 "local STDdownloadPrompt = function(item)",
9810 " term.setCursorPos(1,scr_y)",
9811 " for k,v in pairs(std.storeURLs) do",
9812 " if item.url == v.url then",
9813 " itname = k",
9814 " break",
9815 " end",
9816 " end",
9817 " local savepath",
9818 " if isAxiom then",
9819 " if std.storeURLs[itname].catagory == 8 then --if an API",
9820 " savepath = fs.combine(\"/home/APIs\",itname)",
9821 " else",
9822 " savepath = fs.combine(\"/Axiom/programs\",itname)..\".app\"",
9823 " end",
9824 " else",
9825 " bow()",
9826 " term.clearLine()",
9827 " write(\"Save as: \")",
9828 " savepath = funcread(nil,{},nil,true)",
9829 " term.setCursorBlink(false)",
9830 " end",
9831 " if savepath:gsub(\" \",\"\") == \"\" then",
9832 " sleep(0)",
9833 " return",
9834 " else",
9835 " if relativePath then",
9836 " savepath = fs.combine(shell.dir(),savepath)",
9837 " end",
9838 " if fs.exists(savepath) then",
9839 " term.setCursorPos(1,scr_y)",
9840 " term.clearLine()",
9841 " write(\"Overwrite? (Y/N)\")",
9842 " local key",
9843 " repeat",
9844 " _,key = os.pullEvent(\"char\")",
9845 " until string.find(\"yn\",key)",
9846 " if key == \"n\" then",
9847 " sleep(0)",
9848 " return",
9849 " end",
9850 " end",
9851 " term.setCursorPos(1,scr_y)",
9852 " term.clearLine()",
9853 " term.write(\"Downloading...\")",
9854 " local res, outcome = getFile(savepath,item.url)",
9855 " term.setCursorPos(1,scr_y)",
9856 " term.clearLine()",
9857 " if not res then",
9858 " term.write(outcome)",
9859 " sleep(0.6)",
9860 " else",
9861 " if isAxiom then",
9862 " if std.storeURLs[itname].catagory ~= 8 then --no need for an icon for an api, wouldn't you say",
9863 " local file = fs.open(fs.combine(\"home/Desktop\",itname)..\".lnk\", \"w\")",
9864 " file.write(savepath)",
9865 " file.close()",
9866 " end",
9867 " end",
9868 " term.write(\"Downloaded! (\"..outcome..\" bytes)\")",
9869 " sleep(0.7)",
9870 " end",
9871 " end",
9872 " return",
9873 "end",
9874 "",
9875 "SimSoftDownloadPrompt = function(object)",
9876 " local itname",
9877 " for k,v in pairs(std.storeURLs) do",
9878 " if object.url == v.url then",
9879 " itname = k",
9880 " break",
9881 " end",
9882 " end",
9883 " term.setCursorPos(1,scr_y)",
9884 " bow()",
9885 " term.clearLine()",
9886 " write(\"Label?:\")",
9887 " local custLabel = funcread(_,_,_,true)",
9888 " if #custLabel:gsub(\"%s\",\"\") == 0 then",
9889 " custLabel = nil",
9890 " else",
9891 " custLabel = custLabel:sub(1,9)",
9892 " end",
9893 " term.setCursorPos(1,scr_y)",
9894 " term.clearLine()",
9895 " term.write(\"Downloading...\")",
9896 " local res, outcome = simSoftInstall(object,itname or object.title:gsub(\" \",\"-\"),custLabel)",
9897 " term.setCursorPos(1,scr_y)",
9898 " term.clearLine()",
9899 " term.write(outcome)",
9900 " sleep(#outcome/13)",
9901 "end",
9902 "",
9903 "local doCategoryMenu = function()",
9904 " local mcursor = catag --(not term.isColor()) and (catag or 0) or false",
9905 " local cats,longth = renderCatagoryMenu(true,mcursor)",
9906 " local evt,butt,x,y",
9907 " while true do",
9908 " local evt,butt,x,y = os.pullEvent()",
9909 " if evt == \"mouse_click\" or (evt == \"mouse_up\" and y ~= 1) then",
9910 " doRedraw = true",
9911 " if y == 1 then",
9912 " catag = 0",
9913 " break",
9914 " else",
9915 " for a = 1, #cats do",
9916 " if cats[a] == y and x <= longth then",
9917 " catag = a",
9918 " scroll = 1",
9919 " end",
9920 " end",
9921 " break",
9922 " end",
9923 " elseif evt == \"key\" then",
9924 " if butt == keys.f1 then",
9925 " break",
9926 " elseif mcursor then",
9927 " if (butt == keys.up) and (mcursor > 0) then",
9928 " mcursor = mcursor - 1",
9929 " doRedraw = true",
9930 " elseif (butt == keys.down) and (mcursor < #std.storeCatagoryNames) then",
9931 " mcursor = mcursor + 1",
9932 " doRedraw = true",
9933 " elseif (butt == keys.enter) or (butt == keys.space) then",
9934 " os.queueEvent(\"mouse_click\",1,2,mcursor+1)",
9935 " end",
9936 " end",
9937 " end",
9938 " if doRedraw then",
9939 " renderCatagoryMenu(true,mcursor)",
9940 " doRedraw = false",
9941 " end",
9942 " end",
9943 " maxScroll = setMaxScroll(catag)",
9944 "end",
9945 "",
9946 "local doChannelMenu = function()",
9947 " local mcursor = 1 --(not term.isColor()) and 1 or false",
9948 " local yposes, longth = renderChannelMenu(mcursor)",
9949 " local evt,butt,x,y",
9950 " while true do",
9951 " local evt,butt,x,y = os.pullEvent()",
9952 " if evt == \"mouse_click\" or (evt == \"mouse_up\" and y ~= 1) then",
9953 " if y == 1 then break else",
9954 " for a = 1, #yposes do",
9955 " if (yposes[a][1] == y) and (x <= longth) then",
9956 " if std.channel ~= yposes[a][2] then",
9957 " std.prevChannel = std.channel",
9958 " std.channel = yposes[a][2]",
9959 " scroll = 1",
9960 " std.getSTDList(std.prevChannel)",
9961 " end",
9962 " break",
9963 " end",
9964 " end",
9965 " break",
9966 " end",
9967 " elseif evt == \"key\" then",
9968 " if butt == keys.f3 then",
9969 " break",
9970 " elseif mcursor then",
9971 " if (butt == keys.up) and (mcursor > 1) then",
9972 " mcursor = mcursor - 1",
9973 " elseif (butt == keys.down) and (mcursor < #std.channelNames) then",
9974 " mcursor = mcursor + 1",
9975 " elseif (butt == keys.enter) or (butt == keys.space) then",
9976 " os.queueEvent(\"mouse_click\",1,2,mcursor+1)",
9977 " end",
9978 " end",
9979 " end",
9980 " renderChannelMenu(mcursor)",
9981 " end",
9982 " maxScroll = setMaxScroll(catag)",
9983 "end",
9984 "",
9985 "local STDViewEntry = function(url)",
9986 " local contents, outcome = contentsFile(url)",
9987 " if not contents then",
9988 " term.write(outcome)",
9989 " sleep(0.6)",
9990 " return",
9991 " else",
9992 " strless(contents,palate.item.previewtxt,palate.item.previewbg)",
9993 " end",
9994 "end",
9995 "",
9996 "local doEverything = function() --do I have to do EVERYTHING?",
9997 " if not std.storeURLs then",
9998 " pleaseWait()",
9999 " std.getSTDList(std.prevChannel)",
10000 " end",
10001 " maxScroll = setMaxScroll(catag)",
10002 " local yposes",
10003 " while true do",
10004 " if scroll > maxScroll then",
10005 " scroll = maxScroll",
10006 " end",
10007 " if scroll < 1 then",
10008 " scroll = 1",
10009 " end",
10010 " if (scroll-1 % 4 ~= 0) and (not term.isColor()) then",
10011 " scroll = scroll - ((scroll-1) % 4)",
10012 " end",
10013 " local mcursor = (not term.isColor()) and 1 or false",
10014 " yposes = renderStore(std.storeURLs,catag,scroll,scrollX,fixDotY,not term.isColor())",
10015 " renderCatagoryMenu(false,mcursor)",
10016 " local evt = {getEvents(\"mouse_scroll\",\"mouse_click\",\"mouse_up\",\"key\",\"mouse_drag\",\"char\")}",
10017 " scr_x, scr_y = term.getSize()",
10018 " if evt[1] == \"mouse_scroll\" then",
10019 " if scroll+evt[2] >= 1 and scroll+evt[2] <= maxScroll then",
10020 " scroll = scroll+evt[2]",
10021 " doRedraw = true",
10022 " end",
10023 " elseif evt[1] == \"mouse_click\" and (evt[2] == 1) and (evt[4] <= scr_y) and (evt[4] >= 1) then --left click only! must deport right mouse buttons!",
10024 " if evt[3] == scr_x and evt[4] == math.floor(dotY) then",
10025 " doScrollBar = true",
10026 " end",
10027 " if evt[4] == 1 then",
10028 " if evt[3] >= scr_x-4 then",
10029 " return cleanExit()",
10030 " else",
10031 " if evt[3] >= 1 and evt[3] <= 6 then",
10032 " doCategoryMenu()",
10033 " elseif evt[3] >= 8 and evt[3] <= 14 then",
10034 " doChannelMenu()",
10035 " end",
10036 " end",
10037 " elseif yposes[evt[4]-1] and evt[3] ~= scr_x then",
10038 " local y = evt[4]-1",
10039 " local showPostURL = false",
10040 " local guud = yposes[y].title",
10041 " scrollX = 1",
10042 " while true do",
10043 " if not guud then break end",
10044 " local event,butt,cx,cy = renderStoreItem(yposes[y],showPostURL)",
10045 " if event == \"key\" then",
10046 " if butt == keys.q then",
10047 " sleep(0)",
10048 " break",
10049 " elseif butt == keys.d then --hehe",
10050 " sleep(0)",
10051 " STDdownloadPrompt(yposes[y])",
10052 " --break",
10053 " elseif butt == keys.v then",
10054 " sleep(0)",
10055 " STDViewEntry(yposes[y].url)",
10056 " --break",
10057 " elseif (butt == keys.i) then",
10058 " sleep(0)",
10059 " if isSimSoft then",
10060 " SimSoftDownloadPrompt(yposes[y])",
10061 " elseif isAxiom then",
10062 " STDdownloadPrompt(yposes[y]) --axiom only changes the ",
10063 " end",
10064 " --break",
10065 " end",
10066 " elseif event == \"mouse_click\" then",
10067 " if cy == scr_y then",
10068 " if (cx < scr_x-7) or (cx > scr_x) then",
10069 " if cx >= scr_x-11 and cx < scr_x-8 then",
10070 " term.setCursorPos(1,scr_y)",
10071 " bow()",
10072 " term.clearLine()",
10073 " if pocket or turtle then",
10074 " write(\"Args.: \")",
10075 " else",
10076 " write(\"Arguments:\")",
10077 " end",
10078 " local arguments = explode(\" \",funcread(nil,{},nil,true)) or {}",
10079 " term.setTextColor(colors.white)",
10080 " term.setBackgroundColor(colors.black)",
10081 " term.clear()",
10082 " term.setCursorPos(1,1)",
10083 " local oldcpath",
10084 " if shell then",
10085 " oldcpath = shell.dir()",
10086 " shell.setDir(\"\")",
10087 " end",
10088 " if #arguments == 0 then",
10089 " runURL(yposes[y].url)",
10090 " else",
10091 " runURL(yposes[y].url,unpack(arguments))",
10092 " end",
10093 " if shell then",
10094 " shell.setDir(oldcpath or \"\")",
10095 " end",
10096 " sleep(0)",
10097 " write(\"[press a key]\")",
10098 " os.pullEvent(\"key\")",
10099 " elseif cx >= scr_x-16 and cx < scr_x-12 then",
10100 " STDViewEntry(yposes[y].url)",
10101 " end",
10102 " sleep(0)",
10103 " break",
10104 " else",
10105 " term.setCursorPos(1,scr_y)",
10106 " bow()",
10107 " term.clearLine()",
10108 " if isSimSoft then",
10109 " SimSoftDownloadPrompt(yposes[y])",
10110 " break",
10111 " else",
10112 " STDdownloadPrompt(yposes[y])",
10113 " break",
10114 " end",
10115 " end",
10116 " end",
10117 " end",
10118 " end",
10119 " end",
10120 " elseif evt[1] == \"mouse_up\" then",
10121 " doScrollBar = false",
10122 " fixDotY = nil",
10123 " elseif evt[1] == \"mouse_drag\" then",
10124 " if doScrollBar then",
10125 " local my = evt[4]",
10126 " if my > scr_y then --operating systems might allow this to be true",
10127 " my = scr_y",
10128 " elseif my < 1 then --this too",
10129 " my = 1",
10130 " end",
10131 " if my > 1 then",
10132 " scroll = math.floor( (my-2)/(scr_y-2) * (maxScroll)) + 1",
10133 " fixDotY = my",
10134 " end",
10135 " end",
10136 " elseif evt[1] == \"key\" then",
10137 " if evt[2] == keys.q then",
10138 " return cleanExit()",
10139 " elseif evt[2] == keys.down then",
10140 " scroll = scroll + 4",
10141 " elseif evt[2] == keys.up then",
10142 " scroll = scroll - 4",
10143 " elseif evt[2] == keys.pageDown then",
10144 " scroll = scroll + (scr_y-1)",
10145 " elseif evt[2] == keys.pageUp then",
10146 " scroll = scroll - (scr_y-1)",
10147 " elseif evt[2] == keys.home then",
10148 " scroll = 1",
10149 " elseif evt[2] == keys['end'] then",
10150 " scroll = maxScroll",
10151 " elseif evt[2] == keys.h then --help screen!",
10152 " displayHelp(false)",
10153 " elseif evt[2] == keys.right then",
10154 " scrollX = scrollX + 1",
10155 " elseif evt[2] == keys.left then",
10156 " if scrollX > 1 then",
10157 " scrollX = scrollX - 1",
10158 " end",
10159 " elseif (evt[2] == keys.numPadAdd) or (evt[2] == keys.rightBracket) then",
10160 " catag = catag + 1",
10161 " if catag > #std.storeCatagoryNames then",
10162 " catag = 0",
10163 " end",
10164 " scroll = 1",
10165 " maxScroll = setMaxScroll(catag)",
10166 " elseif (evt[2] == keys.minus) or (evt[2] == keys.leftBracket) then",
10167 " catag = catag - 1",
10168 " if catag < 0 then",
10169 " catag = #std.storeCatagoryNames",
10170 " end",
10171 " scroll = 1",
10172 " maxScroll = setMaxScroll(catag)",
10173 " elseif evt[2] == keys.f5 then",
10174 " pleaseWait()",
10175 " std.getSTDList(std.prevChannel)",
10176 " elseif (evt[2] == keys.f12) and (not isSimSoft) then",
10177 " local updateURL = isBeta and \"http://pastebin.com/raw/uMZ23APu\" or \"http://pastebin.com/raw/P9dDhQ2m\"",
10178 " getFile(shell.getRunningProgram(),updateURL)",
10179 " local flashes = {",
10180 " colors.black,",
10181 " colors.white,",
10182 " colors.lightGray,",
10183 " colors.gray,",
10184 " colors.black,",
10185 " }",
10186 " for a = 1, #flashes do",
10187 " term.setBackgroundColor(flashes[a])",
10188 " term.clear()",
10189 " sleep(0)",
10190 " end",
10191 " return",
10192 " elseif evt[2] == keys.f1 then",
10193 " doCategoryMenu()",
10194 " elseif evt[2] == keys.f or evt[2] == keys.f6 then",
10195 " --runFile(std.stdList)",
10196 " findPrompt()",
10197 " elseif evt[2] == keys.f3 then",
10198 " doChannelMenu()",
10199 " end",
10200 " elseif evt[1] == \"char\" then",
10201 " if tonumber(evt[2]) then",
10202 " local a = tonumber(evt[2]) ~= \"0\" and tonumber(evt[2]) or \"10\"",
10203 " local b = (a*4)-1",
10204 " os.queueEvent(\"mouse_click\",1,scr_x-3,b)",
10205 " end",
10206 " end",
10207 " end",
10208 "end",
10209 "",
10210 "if doDisplayTitle then",
10211 " displayTitle()",
10212 "end",
10213 "",
10214 "if std.storeURLs then std.storeURLs = getFindList(\"\") end",
10215 "",
10216 "local errorHandler = function()",
10217 " local success, message = pcall(doEverything)",
10218 " if success then",
10219 " return true",
10220 " end",
10221 " if message == \"Terminated\" then",
10222 " term.setBackgroundColor(colors.black)",
10223 " term.scroll(2)",
10224 " term.setCursorPos(1, scr_y-1)",
10225 " printError(message)",
10226 " return false, message",
10227 " else",
10228 " term.setBackgroundColor(colors.white)",
10229 " for a = 1, math.ceil(scr_y/2) do",
10230 " term.scroll(2)",
10231 " end",
10232 " term.setTextColor(colors.black)",
10233 " cprint(\"STD-GUI has encountered an error!\",2)",
10234 " term.setCursorPos(1,4)",
10235 " term.setTextColor(term.isColor() and colors.red or colors.gray)",
10236 " print(message or \"\"..\"\\n\")",
10237 " term.setTextColor(colors.black)",
10238 " print(\" Please contact LDDestroier/EldidiStroyrr on either the ComputerCraft forums, or through other means.\")",
10239 " sleep(0.5)",
10240 " print(\"\\nPush a key.\")",
10241 " os.pullEvent(\"key\")",
10242 " term.setCursorPos(1,scr_y)",
10243 " term.setBackgroundColor(colors.black)",
10244 " term.setTextColor(colors.white)",
10245 " term.clearLine()",
10246 " return false, message",
10247 " end",
10248 "end",
10249 "",
10250 "return errorHandler()",
10251 },
10252 [ "/screensaver.lua" ] = {
10253 "local tArg = {...}",
10254 "",
10255 "local scr_x, scr_y = term.getSize()",
10256 "local mx, my = scr_x/2, scr_y/2",
10257 "",
10258 "-- special modes for special people",
10259 "local mouseMode = tArg[1] == \"mouse\" or tArg[2] == \"mouse\"",
10260 "local fuck = tArg[1] == \"fuck\" or tArg[2] == \"fuck\"",
10261 "",
10262 "-- localize functions to increase speed, maybe, I think",
10263 "local concat, blit = table.concat, term.blit",
10264 "local sin, cos, rad, abs, sqrt, floor = math.sin, math.cos, math.rad, math.abs, math.sqrt, math.floor",
10265 "",
10266 "-- rainbow pattern",
10267 "local palette = {\"e\",\"1\",\"4\",\"5\",\"d\",\"9\",\"b\",\"a\",\"2\"}",
10268 "",
10269 "local distance = function(x1, y1, x2, y2)",
10270 " return sqrt( (x2 - x1) ^ 2 + (y2 - y1) ^ 2 )",
10271 "end",
10272 "",
10273 "local randCase = function(str)",
10274 " local output = \"\"",
10275 " for i = 1, #str do",
10276 " output = output .. ((math.random(0,1) == 1) and str:sub(i,i):upper() or str:sub(i,i):lower())",
10277 " end",
10278 " return output",
10279 "end",
10280 "",
10281 "local render = function(iterate, xscroll1, yscroll1, xscroll2, yscroll2)",
10282 " local buffer, cx, cy = {{},{},{}}",
10283 " for y = 1, scr_y do",
10284 " buffer[1][y] = {}",
10285 " buffer[2][y] = {}",
10286 " buffer[3][y] = {}",
10287 " for x = 1, scr_x do",
10288 " cx = 0.66 * ((x - mx) > 0 and 1 or -1) * (abs(x - mx) ^ 1.2)",
10289 " cy = ((y - my) > 0 and 1 or -1) * (abs(y - my) ^ 1.2)",
10290 "",
10291 " buffer[1][y][x] = fuck and randCase(\"fuck\"):sub(1+(cx%4),1+(cx%4)) or \"\"",
10292 "",
10293 " buffer[2][y][x] = palette[1 + floor(",
10294 " iterate + distance( cx + xscroll1, cy + yscroll1, 0, 0 )",
10295 " ) % #palette] or \" \"",
10296 "",
10297 " buffer[3][y][x] = palette[1 + floor(",
10298 " iterate + distance( cx + xscroll2, cy + yscroll2, 0, 0 )",
10299 " ) % #palette] or \" \"",
10300 " end",
10301 " end",
10302 "",
10303 " for y = 1, scr_y do",
10304 " term.setCursorPos(1,y)",
10305 " -- suka",
10306 " blit(",
10307 " concat(buffer[1][y]),",
10308 " concat(buffer[2][y]),",
10309 " concat(buffer[3][y])",
10310 " )",
10311 " end",
10312 "end",
10313 "",
10314 "local main = function()",
10315 " term.clear()",
10316 " local wave, evt = 0",
10317 " local xscroll1, yscroll1, xscroll2, yscroll2 = 0, 0, 0, 0",
10318 " if mouseMode then",
10319 " parallel.waitForAny(function()",
10320 " while true do",
10321 " evt = {os.pullEvent()}",
10322 " if evt[1] == \"mouse_click\" or evt[1] == \"mouse_drag\" then",
10323 " if evt[2] == 1 then",
10324 " xscroll1 = mx - evt[3]",
10325 " yscroll1 = my - evt[4]",
10326 " elseif evt[2] == 2 then",
10327 " xscroll2 = mx - evt[3]",
10328 " yscroll2 = my - evt[4]",
10329 " end",
10330 " end",
10331 " end",
10332 " end,",
10333 " function()",
10334 " while true do",
10335 " render(wave, xscroll1, yscroll1, xscroll2, yscroll2)",
10336 " wave = (wave + 1) % (360 * 7)",
10337 " sleep(0.05)",
10338 " end",
10339 " end)",
10340 " else",
10341 " while true do",
10342 " xscroll1 = -sin(rad(wave * 2)) * scr_x * 0.4",
10343 " yscroll1 = -cos(rad(wave * 3.5)) * scr_y * 0.4",
10344 " xscroll2 = -xscroll1",
10345 " yscroll2 = -yscroll1",
10346 " render(wave, xscroll1, yscroll1, xscroll2, yscroll2)",
10347 " wave = (wave + 1) % (360 * 7)",
10348 " sleep(0.05)",
10349 " end",
10350 " end",
10351 "end",
10352 "",
10353 "-- wait for keypress to exit program",
10354 "local waitForInput = function()",
10355 " local evt",
10356 " sleep(0.25)",
10357 " os.pullEvent(\"key\")",
10358 "end",
10359 "",
10360 "parallel.waitForAny(main, waitForInput)",
10361 "term.clear()",
10362 "term.setCursorPos(1,1)",
10363 "sleep(0.05)",
10364 },
10365 [ "/connect4.lua" ] = {
10366 "local scr_x, scr_y = term.getSize()",
10367 "local midX, midY = .5 * scr_x, .5 * scr_y",
10368 "local origTX, origBG = term.getTextColor(), term.getBackgroundColor()",
10369 "",
10370 "local winLength = 4",
10371 "local sleepDelay = 0.05",
10372 "local moveCount = 0",
10373 "",
10374 "local board = {} -- connect 4 board; formatted like board[y][x]",
10375 "local block = {} -- bottom blockage; formatted like block[x]",
10376 "",
10377 "local waiting = false",
10378 "",
10379 "local boardX, boardY = 7, 6 -- size of board",
10380 "",
10381 "local palette = {",
10382 " bg = colors.black, -- color of backdrop",
10383 " board = colors.white, -- color of board",
10384 " txt = colors.white -- color of text",
10385 "}",
10386 "",
10387 "local tiles = {",
10388 " [\"bl\"] = palette.bg, -- blank space",
10389 " [\"P1\"] = colors.red, -- player 1",
10390 " [\"P2\"] = colors.blue -- player 2",
10391 "}",
10392 "",
10393 "local you = \"P1\"",
10394 "local nou = \"P2\"",
10395 "",
10396 "local cwrite = function(text, y, doClear)",
10397 " local cx, cy = term.getCursorPos()",
10398 " term.setCursorPos(midX - math.floor(#text / 2), y or cy)",
10399 " if doClear then term.clearLine() end",
10400 " term.write(text)",
10401 "end",
10402 "",
10403 "local cblit = function(char, text, back, y, doClear)",
10404 " local cx, cy = term.getCursorPos()",
10405 " term.setCursorPos(midX - math.floor(#text / 2), y or cy)",
10406 " if doClear then term.clearLine() end",
10407 " term.blit(char, text, back)",
10408 "end",
10409 "",
10410 "local resetBoard = function()",
10411 " board = {}",
10412 " for y = 1, boardY do",
10413 " board[y] = {}",
10414 " for x = 1, boardX do",
10415 " board[y][x] = {\"bl\", 0} -- owner, half-in mod",
10416 " end",
10417 " end",
10418 " for x = 1, boardX do",
10419 " block[x] = true",
10420 " end",
10421 "end",
10422 "",
10423 "local addPiece = function(owner, x)",
10424 " if board[1][x][1] == \"bl\" then",
10425 " board[1][x] = {owner, 0, x, 1}",
10426 " return true",
10427 " else",
10428 " return false",
10429 " end",
10430 "end",
10431 "",
10432 "local moveTilesDown = function()",
10433 " local settled = true -- allows for animated falling tiles",
10434 " for y = boardY, 1, -1 do",
10435 " for x = 1, boardX do",
10436 " if board[y][x][1] ~= \"bl\" then",
10437 " if board[y][x][2] == -1 then",
10438 " board[y][x][2] = 0",
10439 " settled = false",
10440 " elseif (y + 1 <= boardY) then",
10441 " if board[y + 1][x][1] == \"bl\" then",
10442 " if board[y][x][2] == 0 then",
10443 " board[y][x][2] = 1",
10444 " settled = false",
10445 " elseif board[y][x][2] == 1 then",
10446 " board[y + 1][x] = {board[y][x][1], -1, x, y + 1}",
10447 " board[y][x] = {\"bl\", 0, x, y}",
10448 " settled = false",
10449 " end",
10450 " end",
10451 " elseif not block[x] then",
10452 " if board[y][x][2] == 0 then",
10453 " board[y][x][2] = 1",
10454 " settled = false",
10455 " else",
10456 " board[y][x] = {\"bl\", 0, x, y}",
10457 " end",
10458 " end",
10459 " end",
10460 " end",
10461 " end",
10462 " return settled",
10463 "end",
10464 "",
10465 "resetBoard()",
10466 "",
10467 "local tileChar = {",
10468 " {",
10469 " \"ƒ”\",",
10470 " \"ÂÂ…\",",
10471 " },",
10472 " {",
10473 " \"10\",",
10474 " \"00\",",
10475 " },",
10476 " {",
10477 " \"01\",",
10478 " \"11\",",
10479 " }",
10480 "}",
10481 "",
10482 "local to_blit = {",
10483 " [0] = \" \",",
10484 " [colors.white] = \"0\",",
10485 " [colors.orange] = \"1\",",
10486 " [colors.magenta] = \"2\",",
10487 " [colors.lightBlue] = \"3\",",
10488 " [colors.yellow] = \"4\",",
10489 " [colors.lime] = \"5\",",
10490 " [colors.pink] = \"6\",",
10491 " [colors.gray] = \"7\",",
10492 " [colors.lightGray] = \"8\",",
10493 " [colors.cyan] = \"9\",",
10494 " [colors.purple] = \"a\",",
10495 " [colors.blue] = \"b\",",
10496 " [colors.brown] = \"c\",",
10497 " [colors.green] = \"d\",",
10498 " [colors.red] = \"e\",",
10499 " [colors.black] = \"f\",",
10500 "}",
10501 "",
10502 "term.setBackgroundColor(palette.bg)",
10503 "term.clear()",
10504 "",
10505 "local checkIfWinner = function()",
10506 " local conditions = {}",
10507 "",
10508 " -- check horizontal",
10509 " for y = 1, boardY do",
10510 " for x = 1, boardX - winLength + 1 do",
10511 " conditions[#conditions+1] = {}",
10512 " for w = 0, winLength - 1 do",
10513 " conditions[#conditions][w+1] = board[y][x+w]",
10514 " end",
10515 " end",
10516 " end",
10517 "",
10518 " -- check vertical",
10519 " for y = boardY - winLength + 1, 1, -1 do",
10520 " for x = 1, boardX do",
10521 " conditions[#conditions+1] = {}",
10522 " for w = 0, winLength - 1 do",
10523 " conditions[#conditions][w+1] = board[y+w][x]",
10524 " end",
10525 " end",
10526 " end",
10527 "",
10528 " -- check diagonals",
10529 " for y = 1, boardY - winLength + 1 do",
10530 " for x = 1, boardX - winLength + 1 do",
10531 " conditions[#conditions+1] = {}",
10532 " conditions[#conditions+1] = {}",
10533 " for w = 0, winLength - 1 do",
10534 " conditions[#conditions-1][w+1] = board[y+(winLength-w-1)][x+w]",
10535 " conditions[#conditions][w+1] = board[y+w][x+w]",
10536 " end",
10537 " end",
10538 " end",
10539 "",
10540 " local winner, check",
10541 " for set = 1, #conditions do",
10542 " winner = true",
10543 " check = conditions[set][1][1]",
10544 " for piece = 2, #conditions[set] do",
10545 " if conditions[set][piece][1] == \"bl\" or conditions[set][piece][1] ~= check then",
10546 " winner = false",
10547 " break",
10548 " end",
10549 " end",
10550 " if winner then",
10551 " return conditions[set][1][1], conditions[set]",
10552 " end",
10553 " end",
10554 " return false",
10555 "end",
10556 "",
10557 "local renderBoard = function()",
10558 " local tileColRep = {",
10559 " [\"1\"] = to_blit[palette.board]",
10560 " }",
10561 " local cx, cy",
10562 " for y = 1, boardY + 1 do",
10563 " if y == boardY + 1 then",
10564 " term.setTextColor(palette.txt)",
10565 " for x = 1, boardX do",
10566 " term.setCursorPos(midX - (boardX) + (x - 1) * #tileChar[1][1], 4)",
10567 " term.write(x)",
10568 " end",
10569 " cwrite(\"SPACE to clear\", scr_y, false)",
10570 " else",
10571 " for ymod = 1, #tileChar[1] do",
10572 " for x = 0, boardX do",
10573 " cx = x * #tileChar[1][1] + (midX - boardX) - 2",
10574 " cy = y * #tileChar[1] + ymod + (midY - boardY) - 1",
10575 " if x == 0 then",
10576 " term.setCursorPos(cx + 1, cy)",
10577 " term.blit(\"•\", to_blit[palette.bg], to_blit[palette.board])",
10578 " else",
10579 " term.setCursorPos(cx, cy)",
10580 " if (board[y][x][2] == 0) or (board[y][x][2] == -1 and ymod == 1) or (board[y][x][2] == 1 and ymod == 2) then",
10581 " tileColRep[\"0\"] = to_blit[tiles[ board[y][x][1] ]]",
10582 " elseif board[y][x][2] == 2 then",
10583 " tileColRep[\"0\"] = to_blit[palette.board]",
10584 " else",
10585 " tileColRep[\"0\"] = to_blit[tiles[\"bl\"]]",
10586 " end",
10587 " term.blit(",
10588 " tileChar[1][ymod],",
10589 " tileChar[2][ymod]:gsub(\".\", tileColRep),",
10590 " tileChar[3][ymod]:gsub(\".\", tileColRep)",
10591 " )",
10592 " end",
10593 " end",
10594 " end",
10595 " end",
10596 " end",
10597 "end",
10598 "",
10599 "local getInput = function()",
10600 " local evt",
10601 " while true do",
10602 " evt = {os.pullEvent()}",
10603 " if evt[1] == \"char\" then",
10604 " if tonumber(evt[2]) then",
10605 " if tonumber(evt[2]) >= 1 and tonumber(evt[2]) <= boardX then",
10606 " if not waiting then",
10607 " if board[1][tonumber(evt[2])][1] == \"bl\" then",
10608 " addPiece(you, tonumber(evt[2]))",
10609 " moveCount = moveCount + 1",
10610 " you, nou = nou, you",
10611 " waiting = true",
10612 " end",
10613 " end",
10614 " end",
10615 " end",
10616 " if evt[2] == \" \" then",
10617 " os.queueEvent(\"clear_board\")",
10618 " for y = 1, boardY do",
10619 " for x = 1, boardX do",
10620 " board[y][x][2] = 0",
10621 " end",
10622 " end",
10623 " for x = 1, boardX do",
10624 " block[x] = false",
10625 " sleep(0.05)",
10626 " end",
10627 " moveCount = 0",
10628 " you, nou = \"P1\", \"P2\"",
10629 " sleep(1)",
10630 " for x = 1, boardX do",
10631 " block[x] = true",
10632 " end",
10633 " elseif evt[2] == \"q\" then",
10634 " return \"exit\"",
10635 " end",
10636 " end",
10637 " end",
10638 "end",
10639 "",
10640 "local main = function()",
10641 " local winner, winPieces",
10642 " while true do",
10643 " renderBoard()",
10644 " while not moveTilesDown() do",
10645 " sleep(sleepDelay)",
10646 " renderBoard()",
10647 " end",
10648 " winner, winPieces = checkIfWinner()",
10649 " term.setTextColor(palette.txt)",
10650 " if winner then",
10651 " cblit(",
10652 " \"Winner: \" .. winner,",
10653 " to_blit[palette.txt]:rep(8) .. to_blit[tiles[winner]]:rep(#winner),",
10654 " to_blit[palette.bg]:rep(8 + #winner),",
10655 " 1,",
10656 " true",
10657 " )",
10658 " parallel.waitForAny(function()",
10659 " while true do",
10660 " for p = 1, #winPieces do",
10661 " board[winPieces[p][4]][winPieces[p][3]][2] = 0",
10662 " end",
10663 " renderBoard()",
10664 " sleep(0.3)",
10665 " for p = 1, #winPieces do",
10666 " board[winPieces[p][4]][winPieces[p][3]][2] = 2",
10667 " end",
10668 " renderBoard()",
10669 " sleep(0.2)",
10670 " end",
10671 " end, function()",
10672 " local evt",
10673 " repeat",
10674 " evt = {os.pullEvent()}",
10675 " until evt[1] == \"clear_board\"",
10676 " end)",
10677 " elseif moveCount >= boardX * boardY then",
10678 " cwrite(\"It's a tie.\", 1, true)",
10679 " waiting = true",
10680 " else",
10681 " waiting = false",
10682 " cblit(",
10683 " \"It's \" .. you .. \"'s turn.\",",
10684 " to_blit[palette.txt]:rep(5) .. to_blit[tiles[you]]:rep(#you) .. to_blit[palette.txt]:rep(8),",
10685 " to_blit[palette.bg]:rep(13 + #you),",
10686 " 1,",
10687 " true",
10688 " )",
10689 " end",
10690 " sleep(sleepDelay)",
10691 " end",
10692 "end",
10693 "",
10694 "parallel.waitForAny(main, getInput)",
10695 "cwrite(\"Thanks for playing!\", 1, true)",
10696 "term.setCursorPos(1, scr_y)",
10697 "term.clearLine()",
10698 },
10699 [ "/sinelock.lua" ] = {
10700 "--[[",
10701 " Sinelock v1.3",
10702 " The *COOLEST* computer/door lock ever!",
10703 " Now with slightly less seizure!",
10704 "",
10705 " pastebin get XDgeSDTq sinelock",
10706 " std pb XDgeSDTq sinelock",
10707 " std ld sinelock sinelock",
10708 "",
10709 " Now with salting!",
10710 "--]]",
10711 "local scr_x, scr_y = term.getSize() --Gets screen size. Don't modify this",
10712 "",
10713 "--Config variables start!",
10714 "local terminateMode = 2 --0 enables termination, 1 blocks it, 2 provides a taunting screen.",
10715 "local passFile = \".sl_password\" --The ABSOLUTE path of the password file.",
10716 "local saltFile = \".sl_salt\" --The ABSOLUTE path of the salt file.",
10717 "local characterLimit = 1024 --The cap of characters at the read() prompt. Set this to prevent crashes.",
10718 "local runProgram = \"\" --Set to something to run it when correct, and not using doors.",
10719 "local dahChar = \"*\" --The character used to hide characters when typed.",
10720 "local doKeyCards = true --Whether or not the lock also accepts keycards (floppy disks) as well as passwords.",
10721 "local doEjectDisk = false --Whether or not to eject a keycard after it's accepted, just to speed things up a bit.",
10722 "local doorSides = {} --If it has anything, the lock will open the doors instead of unlocking the PC.",
10723 "local doInvertSignal = false --If true, it will invert the redstone signal of the door, in case you need to.",
10724 "local doShowDoorSides = true --If true, will show the door sides being opened. Set to false if you are paranoid.",
10725 "local beWavey = true --Whether or not to animate the sine wave.",
10726 "local readYpos = scr_y-2 --The Y position of the read() prompt",
10727 "local requireAllPasswords = false --Whether or not the lock asks for ONE of the multiple passwords, or ALL of them in order.",
10728 "local badlength = 4 --The length in seconds that you have to wait to try again.",
10729 "local goodlength = 6 --The length in seconds that doors will stay open.",
10730 "local sineFrameDelay = 0.15 --The amount of time between sine animation frames. Tradeoff of purty vs performance.",
10731 "local palate = {",
10732 " frontsine = colors.lightGray,",
10733 " backsine = colors.gray,",
10734 " background = colors.black,",
10735 " rainColor = colors.gray,",
10736 " rainChar = \"|\",",
10737 " promptBG = colors.gray,",
10738 " promptTXT = colors.white,",
10739 " wrongBG = colors.black,",
10740 " wrongTXT = colors.gray,",
10741 "}",
10742 "local language = \"english\"",
10743 "local lang = {",
10744 " english = {",
10745 " wrong1 = \"YOU ARE WRONG.\",",
10746 " wrong2 = \"YOU ARE WRONG. AS ALWAYS.\",",
10747 " right1 = \"Correct!\",",
10748 " right2 = \"Correct, finally!\",",
10749 " },",
10750 " spanish = {",
10751 " wrong1 = \"ESTA USTED EQUIVOCADO.\",",
10752 " wrong2 = \"ESTA USTED EQUIVOCADO. TODAVIA OTRA VEZ.\",",
10753 " right1 = \"Correcto!\",",
10754 " right2 = \"Asi es, por fin!\",",
10755 " noTerminate = \"No termine!\",",
10756 " },",
10757 " german = {",
10758 " wrong1 = \"SIE LIEGEN FALSCH.\",",
10759 " wrong2 = \"SIE LIEGEN FALSCH. WIE IMMER.\",",
10760 " right1 = \"Richtig!\",",
10761 " right2 = \"Richtig, endlich!\",",
10762 " noTerminate = \"Nicht zu beenden!\",",
10763 " },",
10764 " dutch = {",
10765 " wrong1 = \"U BENT ONJUIST.\",",
10766 " wrong2 = \"JE BENT ONJUIST, ALS ALTIJD.\",",
10767 " right1 = \"Dat is juist!\",",
10768 " right2 = \"Dat is juist, eindelijk!\",",
10769 " noTerminate = \"Niet te beeindigen!\",",
10770 " },",
10771 " latin = { --As a joke",
10772 " wrong1 = \"ERRAS\",",
10773 " wrong2 = \"TU DEFICIENTES!\",",
10774 " right1 = \"Quod suus 'verum!\",",
10775 " right2 = \"Quod suus 'verum, demum!\",",
10776 " noTerminate = \"Vade futuo te ipsum!\",",
10777 " },",
10778 " italian = {",
10779 " wrong1 = \"HAI SBAGLIATO.\",",
10780 " wrong2 = \"HAI SBAGLIATO, COME SEMPRE D'ALTRONDE.\",",
10781 " right1 = \"CORRETTO!\",",
10782 " right2 = \"CORRETTO, FINALMENTE!\",",
10783 " noTerminate = \"Non cercare di terminarmi\",",
10784 " },",
10785 "}",
10786 "",
10787 "-- Config variables end. Don't touch anything else, m'kay?",
10788 "if not _VERSION then",
10789 " return printError(\"Sorry, only CC 1.7 and later supported.\")",
10790 "end",
10791 "local csv, salt, doSine",
10792 "local floor, ceil, random, abs = math.floor, math.ceil, math.random, math.abs",
10793 "local sin, cos = math.sin, math.cos",
10794 "local rhite = term.write",
10795 "local setTextColor, setBackgroundColor, getTextColor, getBackgroundColor = term.setTextColor, term.setBackgroundColor, term.getTextColor, term.getBackgroundColor",
10796 "local setCursorPos, setCursorBlink, getCursorPos, getSize = term.setCursorPos, term.setCursorBlink, term.getCursorPos, term.getSize",
10797 "local sineLevel = 1",
10798 "local isTerminable = false",
10799 "local kaykaycoolcool = true",
10800 "if term.current().setVisible then",
10801 " csv = true",
10802 "else",
10803 " csv = false",
10804 "end",
10805 "",
10806 "local writeError = function(...)",
10807 " local tx,bg = getTextColor(),getBackgroundColor()",
10808 " if term.isColor() then",
10809 " setTextColor(colors.red)",
10810 " else",
10811 " setTextColor(colors.white)",
10812 " end",
10813 " rhite(table.concat(arg,\" \"))",
10814 " setTextColor(tx)",
10815 " setBackgroundColor(bg)",
10816 "end",
10817 "",
10818 "local goodPullEvent",
10819 "if terminateMode == 1 then",
10820 " if os.pullEvent ~= os.pullEventRaw then",
10821 " goodPullEvent = os.pullEvent",
10822 " end",
10823 " os.pullEvent = os.pullEventRaw",
10824 "end",
10825 "",
10826 "local keepLooping = true",
10827 "",
10828 "---- SHA256 START ----",
10829 "--SHA256 implementation done by GravityScore.",
10830 "",
10831 "local MOD = 2^32",
10832 "local MODM = MOD-1",
10833 "",
10834 "local function memoize(f)",
10835 " local mt = {}",
10836 " local t = setmetatable({}, mt)",
10837 " function mt:__index(k)",
10838 " local v = f(k)",
10839 " t[k] = v",
10840 " return v",
10841 " end",
10842 " return t",
10843 "end",
10844 "",
10845 "local function make_bitop_uncached(t, m)",
10846 " local function bitop(a, b)",
10847 " local res,p = 0,1",
10848 " while a ~= 0 and b ~= 0 do",
10849 " local am, bm = a % m, b % m",
10850 " res = res + t[am][bm] * p",
10851 " a = (a - am) / m",
10852 " b = (b - bm) / m",
10853 " p = p*m",
10854 " end",
10855 " res = res + (a + b) * p",
10856 " return res",
10857 " end",
10858 " return bitop",
10859 "end",
10860 "",
10861 "local function make_bitop(t)",
10862 " local op1 = make_bitop_uncached(t,2^1)",
10863 " local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)",
10864 " return make_bitop_uncached(op2, 2 ^ (t.n or 1))",
10865 "end",
10866 "",
10867 "local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})",
10868 "",
10869 "local function bxor(a, b, c, ...)",
10870 " local z = nil",
10871 " if b then",
10872 " a = a % MOD",
10873 " b = b % MOD",
10874 " z = bxor1(a, b)",
10875 " if c then z = bxor(z, c, ...) end",
10876 " return z",
10877 " elseif a then return a % MOD",
10878 " else return 0 end",
10879 "end",
10880 "",
10881 "local function band(a, b, c, ...)",
10882 " local z",
10883 " if b then",
10884 " a = a % MOD",
10885 " b = b % MOD",
10886 " z = ((a + b) - bxor1(a,b)) / 2",
10887 " if c then z = bit32_band(z, c, ...) end",
10888 " return z",
10889 " elseif a then return a % MOD",
10890 " else return MODM end",
10891 "end",
10892 "",
10893 "local function bnot(x) return (-1 - x) % MOD end",
10894 "",
10895 "local function rshift1(a, disp)",
10896 " if disp < 0 then return lshift(a,-disp) end",
10897 " return floor(a % 2 ^ 32 / 2 ^ disp)",
10898 "end",
10899 "",
10900 "local function rshift(x, disp)",
10901 " if disp > 31 or disp < -31 then return 0 end",
10902 " return rshift1(x % MOD, disp)",
10903 "end",
10904 "",
10905 "local function lshift(a, disp)",
10906 " if disp < 0 then return rshift(a,-disp) end ",
10907 " return (a * 2 ^ disp) % 2 ^ 32",
10908 "end",
10909 "",
10910 "local function rrotate(x, disp)",
10911 " x = x % MOD",
10912 " disp = disp % 32",
10913 " local low = band(x, 2 ^ disp - 1)",
10914 " return rshift(x, disp) + lshift(low, 32 - disp)",
10915 "end",
10916 "",
10917 "local k = {",
10918 " 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,",
10919 " 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,",
10920 " 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,",
10921 " 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,",
10922 " 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,",
10923 " 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,",
10924 " 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,",
10925 " 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,",
10926 " 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,",
10927 " 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,",
10928 " 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,",
10929 " 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,",
10930 " 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,",
10931 " 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,",
10932 " 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,",
10933 " 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,",
10934 "}",
10935 "",
10936 "local function str2hexa(s)",
10937 " return (string.gsub(s, \".\", function(c) return string.format(\"%02x\", string.byte(c)) end))",
10938 "end",
10939 "",
10940 "local function num2s(l, n)",
10941 " local s = \"\"",
10942 " for i = 1, n do",
10943 " local rem = l % 256",
10944 " s = string.char(rem) .. s",
10945 " l = (l - rem) / 256",
10946 " end",
10947 " return s",
10948 "end",
10949 "",
10950 "local function s232num(s, i)",
10951 " local n = 0",
10952 " for i = i, i + 3 do n = n*256 + string.byte(s, i) end",
10953 " return n",
10954 "end",
10955 "",
10956 "local function preproc(msg, len)",
10957 " local extra = 64 - ((len + 9) % 64)",
10958 " len = num2s(8 * len, 8)",
10959 " msg = msg .. \"€\" .. string.rep(\"\\0\", extra) .. len",
10960 " assert(#msg % 64 == 0)",
10961 " return msg",
10962 "end",
10963 "",
10964 "local function initH256(H)",
10965 " H[1] = 0x6a09e667",
10966 " H[2] = 0xbb67ae85",
10967 " H[3] = 0x3c6ef372",
10968 " H[4] = 0xa54ff53a",
10969 " H[5] = 0x510e527f",
10970 " H[6] = 0x9b05688c",
10971 " H[7] = 0x1f83d9ab",
10972 " H[8] = 0x5be0cd19",
10973 " return H",
10974 "end",
10975 "",
10976 "local function digestblock(msg, i, H)",
10977 " local w = {}",
10978 " for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end",
10979 " for j = 17, 64 do",
10980 " local v = w[j - 15]",
10981 " local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))",
10982 " v = w[j - 2]",
10983 " w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))",
10984 " end",
10985 "",
10986 " local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]",
10987 " for i = 1, 64 do",
10988 " local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))",
10989 " local maj = bxor(band(a, b), band(a, c), band(b, c))",
10990 " local t2 = s0 + maj",
10991 " local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))",
10992 " local ch = bxor (band(e, f), band(bnot(e), g))",
10993 " local t1 = h + s1 + ch + k[i] + w[i]",
10994 " h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2",
10995 " end",
10996 "",
10997 " H[1] = band(H[1] + a)",
10998 " H[2] = band(H[2] + b)",
10999 " H[3] = band(H[3] + c)",
11000 " H[4] = band(H[4] + d)",
11001 " H[5] = band(H[5] + e)",
11002 " H[6] = band(H[6] + f)",
11003 " H[7] = band(H[7] + g)",
11004 " H[8] = band(H[8] + h)",
11005 "end",
11006 "",
11007 "local function sha256(...)",
11008 " local msg = table.concat(arg,\",\")",
11009 " msg = preproc(msg, #msg)",
11010 " local H = initH256({})",
11011 " for i = 1, #msg, 64 do digestblock(msg, i, H) end",
11012 " return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..",
11013 " num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))",
11014 "end",
11015 "",
11016 "---- SHA256 END ----",
11017 "",
11018 "local terminates = 0",
11019 "local sillyTerminate = function()",
11020 " local goodpull = _G.os.pullEvent",
11021 " os.pullEvent = os.pullEventRaw",
11022 " terminates = terminates + 1",
11023 " local script = {",
11024 " \"You shall not pass!\",",
11025 " \"THOU shalt not pass!\",",
11026 " \"Stop trying to pass!\",",
11027 " \"...maybe I'm not clear.\",",
11028 " \"YOU. SHALL NOT. PASS!!\",",
11029 " \"Pass thou shalt not!\",",
11030 " \"Hey, piss off, will ya?\",",
11031 " \"I haven't got all day.\",",
11032 " \"...no, shut up. I don't.\",",
11033 " \"I won't tell you it!\",",
11034 " \"No password for you.\",",
11035 " \"It's been hashed!\",",
11036 " \"Hashed...with a salt!\",",
11037 " \"I'll never tell you the salt.\",",
11038 " \"You know why?\",",
11039 " \"Because that requires passing!\",",
11040 " \"WHICH THOU SHALT NOT DO!\",",
11041 " \"(oh btw don't pass k?)\",",
11042 " \"You! Don't pass!\",",
11043 " \"That means YOU!\",",
11044 " \"Cut it out!\",",
11045 " \"Re: Cut it out!\",",
11046 " \"Perhaps if you keep it up...\",",
11047 " \"..hmm...\",",
11048 " \"..oh I give up.\",",
11049 " \"<bullshitterm>\",",
11050 " \"What? Is this what you wanted?\",",
11051 " \"Huh? No? I-it's not?\",",
11052 " \"Well then...!\",",
11053 " \"<toobad>\",",
11054 " \"YEAH I SAID IT\",",
11055 " \"You think you're a terminating machine!\",",
11056 " \"You think you're above consequence!\",",
11057 " \"...w-...\",",
11058 " \"eat my shorts\",",
11059 " \"Your attempts are futile anyhow.\",",
11060 " \"Here I am getting drunk off your sweat,\",",
11061 " \"...while you push CTRL and T.\",",
11062 " \"Or maybe you're pressing that [T] button.\",",
11063 " \"Like, um, in CCEmuRedux.\",",
11064 " \"But it matters not!\",",
11065 " \"For you see, my defences are great!\",",
11066 " \"Nothing can bust my rock-hard abs!\",",
11067 " \"<fuckinghell>\",",
11068 " \"Oh bualls.\",",
11069 " \"That was embarrasing.\",",
11070 " \"...?\",",
11071 " \"What're YOU lookin' at??\",",
11072 " \"You callin' me UNSTABLE!?\",",
11073 " \"HUH!??\",",
11074 " \"...\",",
11075 " \"...w-well at least I admit it\",",
11076 " \"...b-bakka\",",
11077 " \".......\",",
11078 " \"Hey, have you ever played EarthBound?\",",
11079 " \"(Yes. I'm gonna rant.)\",",
11080 " \"It's an RPG on the Super Nintendo.\",",
11081 " \"Like, instead of fighting fantasy demons,\",",
11082 " \"you fight stop signs and cars and shit\",",
11083 " \"And, like, you hit rabid dogs with a bat\",",
11084 " \"And you have magical PSI spells\",",
11085 " \"...speaking of PSI, I happen to use it a lot.\",",
11086 " \"...er, *I* as in the coder of this lock...\",",
11087 " \"And by PSI, I mean the mod.\",",
11088 " \"You don't see too many psychic locks these days.\",",
11089 " \"A shame, really.\",",
11090 " \"I bet a PSI lock could act as a heater with PSI Fire.\",",
11091 " \"Or maybe it can kill rats with PSI Ground or Thunder\",",
11092 " \"Maybe, you can get a psychic KEY lock, so, like,\",",
11093 " \"you could put it on that Psychonauts head door thing.\",",
11094 " \"...WHAT!? just a suggestion.\",",
11095 " \"Psychonauts is another game I reccommend.\",",
11096 " \"It has some really clever dialogue.\",",
11097 " \"I'm sure you'd like it quite a lot.\",",
11098 " \"I know, because you've been here for ten fucking minutes.\",",
11099 " \"And you're not ONE STEP closer to getting the password\",",
11100 " \"Which I've been guarding very, very closely.\",",
11101 " \"Yes. Extremely closely.\",",
11102 " \"Excrutiatingly, some would say.\",",
11103 " \"You know, I should probably get to shouting.\",",
11104 " \"*ahem*\",",
11105 " \"...\",",
11106 " \"*aahhhechhemmemmhmm*\",",
11107 " \"*aachkskacehchachkhackcoughfartfuckdammitaaucahkh*\",",
11108 " \"...\",",
11109 " \"STAHP IT\",",
11110 " \"STAHP TEHRMINATIN\",",
11111 " \"do it for the CHILDREN\",",
11112 " \"okay fuck the children, who needs 'em\",",
11113 " \"then\",",
11114 " \"um\",",
11115 " \"THINK OF THE...THE...\",",
11116 " \"the babies...?\",",
11117 " \"um\",",
11118 " \"<abuseofcommunity>\",",
11119 " \"That's a fucking horrible idea.\",",
11120 " \"I'd rather eat my own brain then think about that.\",",
11121 " \"I'd sooner kiss a pig!\",",
11122 " \"I'd sooner swallow an avocado pit!\",",
11123 " \"...\",",
11124 " \"You know, you suck so much.\",",
11125 " \"You suck so much, and I'm sick of writing this script\",",
11126 " \"If my knuckles bleed, you're paying my insurance\",",
11127 " \"In order to save time, money, and my joints,\",",
11128 " \"I believe it would be in order to...\",",
11129 " \"...to say,\",",
11130 " \"NO TERMINATING.\",",
11131 " }",
11132 " setCursorBlink(false)",
11133 " local mess",
11134 " if terminates > #script then",
11135 " mess = script[#script]",
11136 " else",
11137 " mess = script[terminates]",
11138 " end",
11139 " if mess == \"<bullshitterm>\" then",
11140 " setBackgroundColor(colors.black)",
11141 " if term.isColor() then",
11142 " setTextColor(colors.yellow)",
11143 " else",
11144 " setTextColor(colors.white)",
11145 " end",
11146 " term.clear()",
11147 " setCursorPos(1,1)",
11148 " print(os.version())",
11149 " write(\"> \")",
11150 " setTextColor(colors.white)",
11151 " read()",
11152 " printError(\"shell:350: Unable to pass\")",
11153 " sleep(2)",
11154 " elseif mess == \"<toobad>\" then",
11155 " setBackgroundColor(colors.black)",
11156 " if term.isColor() then",
11157 " setTextColor(colors.red)",
11158 " else",
11159 " setTextColor(colors.white)",
11160 " end",
11161 " term.clear()",
11162 " setCursorPos(1,scr_y/2)",
11163 " local toobad = \" T\"..(\"O\"):rep(scr_x-8)..\" BAD!\"",
11164 " for a = 1, #toobad do",
11165 " for y = 1, scr_y do",
11166 " setCursorPos(a,y)",
11167 " rhite(toobad:sub(a,a))",
11168 " end",
11169 " sleep(0)",
11170 " end",
11171 " sleep(1.5)",
11172 " for a = 1, 16 do",
11173 " if a%3 == 0 then",
11174 " setBackgroundColor(colors.white)",
11175 " elseif a%3 == 1 then",
11176 " setBackgroundColor(colors.black)",
11177 " else",
11178 " if term.isColor() then",
11179 " setBackgroundColor(colors.red)",
11180 " else",
11181 " setBackgroundColor(colors.gray)",
11182 " end",
11183 " end",
11184 " term.clear()",
11185 " sleep(0)",
11186 " end",
11187 " elseif mess == \"<fuckinghell>\" then",
11188 " writeError(\"Terminated\")",
11189 " setBackgroundColor(colors.black)",
11190 " setTextColor(colors.white)",
11191 " term.blit(\">\",\"4\",\"f\")",
11192 " read()",
11193 " sleep(0.75)",
11194 " for a = 1, 2 do",
11195 " sleep(0.05)",
11196 " term.scroll(1)",
11197 " end",
11198 " for a = 1, scr_y do ",
11199 " sleep(0.05)",
11200 " term.scroll(-1)",
11201 " end",
11202 " sleep(0.25)",
11203 " setBackgroundColor(colors.gray)",
11204 " term.clear()",
11205 " sleep(0.1)",
11206 " setBackgroundColor(colors.lightGray)",
11207 " term.clear()",
11208 " sleep(0.1)",
11209 " setBackgroundColor(colors.white)",
11210 " term.clear()",
11211 " sleep(0.25)",
11212 " local msg = \"taht didn't happan\"",
11213 " term.setCursorPos(scr_x-#msg,scr_y)",
11214 " setTextColor(colors.black)",
11215 " rhite(msg)",
11216 " sleep(1)",
11217 " elseif mess == \"<abuseofcommunity>\" then",
11218 " setBackgroundColor(colors.white)",
11219 " setTextColor(colors.black)",
11220 " term.clear()",
11221 " setCursorPos(2,3)",
11222 " print(\"Since you're such a smart bastard, why don't you come up with something objectionable to think about?\\n\")",
11223 " setBackgroundColor(colors.gray)",
11224 " setTextColor(colors.white)",
11225 " term.clearLine()",
11226 " local yourFuckingShittyAssResponceThatSucksSoMuchBallsThatIWouldRatherListenToThatFuckingOwlFromOcarinaOfTimeBlatherAboutHisFuckingDayThanSitWithYouForAnotherGoddamnedSecondReeeeee = read()",
11227 " setBackgroundColor(colors.white)",
11228 " setTextColor(colors.black)",
11229 " for a = 1, 5 do",
11230 " sleep(0.6)",
11231 " write(\".\")",
11232 " end",
11233 " sleep(1)",
11234 " term.setTextColor(colors.red)",
11235 " for a = 1, 20 do",
11236 " sleep(0.05)",
11237 " write(\".\")",
11238 " end",
11239 " sleep(0.5)",
11240 " else",
11241 " setBackgroundColor(colors.gray)",
11242 " setTextColor(colors.white)",
11243 " setCursorPos(math.max(1,(scr_x/2)-(#mess/2)),scr_y/2)",
11244 " if language == \"english\" then",
11245 " write(mess)",
11246 " else",
11247 " write(lang[language].noTerminate)",
11248 " end",
11249 " sleep(1.5)",
11250 " end",
11251 " os.pullEvent = goodpull",
11252 " return terminates",
11253 "end",
11254 "",
11255 "local shuffle = function(txt)",
11256 " local output = \"\"",
11257 " for a = 1, #txt do",
11258 " if a % 2 == 0 then",
11259 " output = output..txt:sub(a,a)",
11260 " else",
11261 " output = txt:sub(a,a)..output",
11262 " end",
11263 " end",
11264 " return output",
11265 "end",
11266 "",
11267 "local goodpass = function(pswd,count)",
11268 " isTerminable = true",
11269 " doSine = false",
11270 " setCursorBlink(false)",
11271 " local flashes = {",
11272 " colors.white,",
11273 " colors.lightGray,",
11274 " colors.gray,",
11275 " }",
11276 " if type(pswd) == \"table\" then",
11277 " pswd = pswd[1]",
11278 " end",
11279 " setTextColor(colors.black)",
11280 " local correctmsg",
11281 " if count < 10 then",
11282 " correctmsg = lang[language].right1",
11283 " else",
11284 " correctmsg = lang[language].right2",
11285 " end",
11286 " for a = 1, #flashes do",
11287 " setBackgroundColor(flashes[#flashes-(a-1)])",
11288 " term.clear()",
11289 " setCursorPos((scr_x/2)-(#correctmsg/2),scr_y/2)",
11290 " rhite(correctmsg)",
11291 " sleep(0)",
11292 " end",
11293 " if #doorSides == 0 then",
11294 " sleep(0.4)",
11295 " keepLooping = false",
11296 " ",
11297 },
11298 [ "/ports.lua" ] = {
11299 "-- pastebin get XxkBiYJ6 ports",
11300 "-- std pb XxkBiYJ6 ports",
11301 "function getOpenChannels()",
11302 " modemChannels = {}",
11303 " sides = peripheral.getNames()",
11304 " modemSides = {}",
11305 " modemRednetSides = {}",
11306 " for a = 1, #sides do",
11307 " if peripheral.getType(sides[a]) == \"modem\" then",
11308 " table.insert(modemSides, sides[a])",
11309 " if rednet.isOpen(sides[a]) then",
11310 " table.insert(modemRednetSides, sides[a])",
11311 " end",
11312 " end",
11313 " end",
11314 " for a = 1, #modemSides do",
11315 " if not oldPeripheralWrap then",
11316 " modem = peripheral.wrap(modemSides[a])",
11317 " else",
11318 " modem = oldPeripheralWrap(modemSides[a])",
11319 " end",
11320 " channels = {}",
11321 " for b = 1, 65535 do",
11322 " if modem.isOpen(b) then",
11323 " table.insert(modemChannels, b)",
11324 " end",
11325 " end",
11326 " end",
11327 "end",
11328 "",
11329 "function printChannels()",
11330 " print(\"ID: \" .. os.getComputerID())",
11331 " write(\"Open channels:\")",
11332 " if isLocked then",
11333 " print(\" LOCKED\")",
11334 " else",
11335 " print(\"\")",
11336 " end",
11337 " if modemChannels ~= nil then",
11338 " for a = 1, #modemChannels do",
11339 " if modemChannels[a] == rednet.CHANNEL_BROADCAST then",
11340 " print(\" Rednet \" .. modemChannels[a])",
11341 " else",
11342 " print(\" Modem \" .. modemChannels[a])",
11343 " end",
11344 " end",
11345 " else",
11346 " print(\" none!\")",
11347 " end",
11348 "end",
11349 "",
11350 "tArg = {...}",
11351 "",
11352 "command = tArg[1]",
11353 "argument1 = tArg[2]",
11354 "argument2 = tArg[3]",
11355 "argument3 = tArg[4]",
11356 "",
11357 "getOpenChannels()",
11358 "",
11359 "if not command then",
11360 " getOpenChannels()",
11361 " printChannels()",
11362 " return",
11363 "elseif command == \"open\" then",
11364 " if tonumber(argument1) == nil then",
11365 " success = false",
11366 " for a = 1, #modemSides do",
11367 " if modemSides[a] == argument1 then",
11368 " success = true",
11369 " end",
11370 " end",
11371 " if argument1 == nil then",
11372 " error(\"no side given\")",
11373 " end",
11374 " if success == true then",
11375 " rednet.open(argument1)",
11376 " print(\"Opened side \" .. argument1 .. \" on rednet\")",
11377 " else",
11378 " error(\"modem \" .. argument1 .. \" not found\")",
11379 " end",
11380 " else",
11381 " argument1 = tonumber(argument1)",
11382 " if argument1 <= 0 or argument1 > 65535 then",
11383 " error(\"channel '\" .. argument1 .. \"' not good\")",
11384 " else",
11385 " modem.open(argument1)",
11386 " print(\"Opened channel \" .. argument1)",
11387 " end",
11388 " end",
11389 "elseif command == \"close\" then",
11390 " if tonumber(argument1) == nil then",
11391 " success = false",
11392 " if argument1 == \"*\" then",
11393 " modem.closeAll()",
11394 " print(\"All channels closed.\")",
11395 " else",
11396 " for a = 1, #modemSides do",
11397 " if modemSides[a] == argument1 then",
11398 " success = true",
11399 " end",
11400 " end",
11401 " if argument1 == nil then",
11402 " error(\"no side given\")",
11403 " end",
11404 " if success == true then",
11405 " rednet.close(argument1)",
11406 " print(\"Closed side '\" .. argument1 .. \"' on rednet\")",
11407 " else",
11408 " error(\"modem '\" .. argument1 .. \"' not found\")",
11409 " end",
11410 " end",
11411 " else",
11412 " argument1 = tonumber(argument1)",
11413 " if argument1 <= 0 or argument1 > 65535 then",
11414 " error(\"channel \" .. argument1 .. \" not good\")",
11415 " else",
11416 " modem.close(argument1)",
11417 " print(\"Closed channel \" .. argument1)",
11418 " end",
11419 " end",
11420 "elseif command == \"lock\" then",
11421 " if not isLocked then",
11422 " oldOpenChannelList = modemChannels",
11423 " for a = 1, #modemSides do",
11424 " modem = peripheral.wrap(modemSides[a])",
11425 " modem.closeAll()",
11426 " end",
11427 " modem = nil",
11428 " oldRednetSend = rednet.send",
11429 " oldRednetBroadcast = rednet.broadcast",
11430 " oldPeripheralWrap = peripheral.wrap",
11431 " oldPeripheralFind = peripheral.find",
11432 " oldPeripheralCall = peripheral.call",
11433 " oldRednetLookup = rednet.lookup",
11434 " oldRednetHost = rednet.host",
11435 " oldRednetUnhost = rednet.unhost",
11436 " peripheral.wrap = function(object)",
11437 " if peripheral.getType(object) == \"modem\" then",
11438 " return nil",
11439 " else",
11440 " return oldPeripheralWrap(object)",
11441 " end",
11442 " end",
11443 " peripheral.find = function(object)",
11444 " if object == \"modem\" then",
11445 " return nil",
11446 " else",
11447 " return oldPeripheralFind(object)",
11448 " end",
11449 " end",
11450 " peripheral.call = function(...)",
11451 " arg = {...}",
11452 " if peripheral.getType(arg[1]) == \"modem\" then",
11453 " return nil",
11454 " else",
11455 " return oldPeripheralCall(...)",
11456 " end",
11457 " end",
11458 " rednet.send = function(id, contents, protocol)",
11459 " return nil",
11460 " end",
11461 " rednet.broadcast = function(contents, protocol)",
11462 " return nil",
11463 " end",
11464 " rednet.lookup = function(protocol, hostname)",
11465 " return nil",
11466 " end",
11467 " rednet.host = function(protocol, hostname)",
11468 " return nil",
11469 " end",
11470 " rednet.unhost = function(protocol, hostname)",
11471 " return nil",
11472 " end",
11473 " _G.peripheral.wrap = peripheral.wrap",
11474 " _G.peripheral.find = peripheral.find",
11475 " _G.peripheral.call = peripheral.call",
11476 " _G.rednet.send = rednet.send",
11477 " _G.rednet.broadcast = rednet.broadcast",
11478 " _G.rednet.lookup = rednet.lookup",
11479 " _G.rednet.host = rednet.host",
11480 " _G.rednet.unhost = rednet.unhost",
11481 " isLocked = true",
11482 " print(\"Modem communication is LOCKED.\")",
11483 " else",
11484 " rednet.send = oldRednetSend",
11485 " rednet.broadcast = oldRednetBroadcast",
11486 " peripheral.wrap = oldPeripheralWrap",
11487 " peripheral.find = oldPeripheralFind",
11488 " peripheral.call = oldPeripheralCall",
11489 " rednet.lookup = oldRednetLookup",
11490 " rednet.host = oldRednetHost",
11491 " rednet.unhost = oldRednetUnhost",
11492 " _G.peripheral.wrap = peripheral.wrap",
11493 " _G.peripheral.find = peripheral.find",
11494 " _G.peripheral.call = peripheral.call",
11495 " _G.rednet.send = rednet.send",
11496 " _G.rednet.broadcast = rednet.broadcast",
11497 " _G.rednet.lookup = rednet.lookup",
11498 " _G.rednet.host = rednet.host",
11499 " _G.rednet.unhost = rednet.unhost",
11500 " isLocked = false",
11501 " modem = peripheral.find(\"modem\")",
11502 " for a = 1, #oldOpenChannelList do",
11503 " modem.open(oldOpenChannelList[a])",
11504 " end",
11505 " modem = nil",
11506 " print(\"Modem communication is UNLOCKED.\")",
11507 " end",
11508 "elseif command == \"listen\" or command == \"receive\" then",
11509 " modem = peripheral.find(\"modem\")",
11510 " if not modem then",
11511 " error(\"No modem to listen from!\")",
11512 " end",
11513 " if not argument1 then",
11514 " argument1 = rednet.CHANNEL_BROADCAST",
11515 " end",
11516 " write(\"Listening on port \"..argument1)",
11517 " if tonumber(argument2) then",
11518 " print(\" for \"..argument2..\" sec...\")",
11519 " else",
11520 " print(\"...\")",
11521 " end",
11522 " if argument1 == \"rednet\" then",
11523 " modem.open(rednet.CHANNEL_BROADCAST)",
11524 " event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent(\"modem_message\")",
11525 " else",
11526 " modem.open(tonumber(argument1))",
11527 " event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent(\"modem_message\")",
11528 " end",
11529 " if event then",
11530 " print(\"msg: '\"..message..\"'\")",
11531 " print(\"senderID: \"..senderChannel)",
11532 " print(\"replyChannel: \"..replyChannel)",
11533 " print(\"distance: \"..senderDistance)",
11534 " else",
11535 " print(\"Nothing...\")",
11536 " end",
11537 "elseif command == \"send\" then",
11538 " modem = peripheral.find(\"modem\")",
11539 " if not modem then",
11540 " error(\"Get a modem!\")",
11541 " end",
11542 " if not argument1 then",
11543 " error(\"No message!\")",
11544 " end",
11545 " if not argument2 then",
11546 " argument2 = rednet.CHANNEL_BROADCAST",
11547 " end",
11548 " if not argument3 then",
11549 " argument3 = rednet.CHANNEL_REPEAT",
11550 " end",
11551 " modem.open(tonumber(argument2))",
11552 " modem.transmit(tonumber(argument2),tonumber(argument3),argument1)",
11553 " print(\"Sent '\"..argument1..\"' on channel \"..argument2..\" (reply:\"..argument3..\")\")",
11554 "else",
11555 " print(\"//ports// - modem tool\")",
11556 " print(\"Syntax:\")",
11557 " print(\" 'ports'\")",
11558 " print(\" 'ports [open/close] <sideName>'\")",
11559 " print(\" 'ports [open/close] <channelNum>'\")",
11560 " print(\" 'ports lock'\")",
11561 " print(\" 'ports send <message> [channel] [replyChannel]\")",
11562 " print(\" 'ports receive'\")",
11563 "end",
11564 },
11565}