-- by PixelToast aka infinikiller64 -- all downloads must be linked directly to the forum post -- unless its distributed privatly (in a modpack or such) or with permission -- use of the updater is granted without permission if false then -- change to true if you are evil and use tekkit function term.isColor() return false end end if not term.isColor then error("tekkit not supported") end local modemmode=false if rednet.CHANNEL_BROADCAST then modemmode=true end function plyd(data) local d=true while d do d=false if data[1]=="rednet_message" and not modemmode then data={"modem_message"} elseif data[1]=="modem_message" then elseif data[1]=="monitor_touch" then plyd[1]="mouse_click" plyd[2]=3 end end end local sel={} local tSel={} local tArgs=tArgs or {...} local doupdate=false local function update() if fs.exists("diskplayer_temp") then fs.delete("diskplayer_temp") end local cdir=shell.getRunningProgram() if fs.isReadOnly(cdir) then cdir="/diskplayer" end local update_temp=[[ local file=fs.open(arg1,"w") file.write(arg2) file.close() fs.delete("diskplayer_temp") ]] http.request("https://raw.github.com/infinikiller64/ComputerCraft/master/diskplayer") while true do local p={os.pullEvent()} if p[1]=="http_success" then local file=fs.open("diskplayer_temp","w") file.write(update_temp) file.close() os.run({arg1=cdir,arg2=p[3].readAll()},"diskplayer_temp") break elseif p[1]=="http_failure" then error("Oh noes! my site is down.") end end term.clear() term.setCursorPos(1,1) end if tArgs[1]=="update" then local a,b=pcall(update) if not a then print(b) end error("Update complete.") end -- function ports from infutil / snet: local sides={"right","left","front","back","top","bottom"} do local side local sides={"right","left","front","back","top","bottom"} for l1=1,6 do if peripheral.getType(sides[l1])=="modem" then rednet.open(sides[l1]) side=sides[l1] end end if not side then error("No modem attached.") end end local function compress( ... ) -- serializes all of its arguments into a table and catches errors local tArgs={ ... } local E,D=pcall(textutils.serialize,tArgs) if E then return D else return false end end function decompress(S) -- convert a serialized table into a normal one and catches errors local E,D,C=pcall(textutils.unserialize,S) if C or not E then return false else return type(D)=="table" and D end end local function savePrefs(name,data,tf) -- saves data to a file local file=io.open(name,"w") if tf then file:write(data) else file:write(textutils.serialize(data)) end file:close() end local function readPrefs(name,tf) -- reads data from a file local file=fs.open(name,"r") if not file then return false end local dat if tf then dat=file.readAll() else dat=textutils.unserialize(file.readAll()) end file.close() return dat end -- end ports local mon for k,v in pairs(sides) do if peripheral.getType(v)=="monitor" then mon=peripheral.wrap(v) end end local termsize=1 if tArgs[1]=="-m" then termsize=tonumber(tArgs[2]) else termsize=1 end disk={ ["C418 - 11"]={ len=70, artist="C418", short="11" }, ["C418 - 13"]={ len=180, artist="C418", short="13" }, ["C418 - cat"]={ len=186, artist="C418", short="cat" }, ["C418 - blocks"]={ len=347, artist="C418", short="blocks" }, ["C418 - chirp"]={ len=186, artist="C418", short="chirp" }, ["C418 - far"]={ len=172, artist="C418", short="far" }, ["C418 - mall"]={ len=197, artist="C418", short="mall" }, ["C418 - mellohi"]={ len=98, artist="C418", short="mellohi" }, ["C418 - stal"]={ len=151, artist="C418", short="stal" }, ["C418 - strad"]={ len=191, artist="C418", short="strad" }, ["C418 - ward"]={ len=250, artist="C418", short="ward" }, ["C418 - wait"]={ len=210, artist="C418", short="wait" }, ["wait"]={ len=235, real="C418 - wait", artist="C418", short="wait" }, ["Valve - Want You Gone"]={ len=130, artist="Jonathan Coulton", short="gone" }, ["Valve - Still Alive"]={ len=170, artist="Jonathan Coulton", short="alive" }, ["Valve - Radio Loop"]={ len=22, artist="Valve", short="radio" }, ["pg.wantyougone"]={ len=130, real="Valve - Want You Gone", artist="Jonathan Coulton", short="gone" }, ["pg.stillalive"]={ len=170, real="Valve - Still Alive", artist="Jonathan Coulton", short="alive" }, ["pg.radioloop"]={ len=22, real="Valve - Radio Loop", artist="Valve", short="radio" }, } local list={} setmetatable(disk,{__index=function(s,n) return {artist="Error",short="",len=0} end}) rednet.broadcast(compress("reqdisks")) if mon then if mon.setTextScale then mon.setTextScale(termsize) end end local isMon=false local function mrender(func) if mon then isMon=true term.redirect(mon) func() term.restore() isMon=false end end local function renderdswait() term.clear() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) local txt="Waiting for disks." term.setCursorPos(Cx-math.floor(#txt/2),Cy) term.write(txt) end renderdswait() mrender(renderdswait) local timer while true do local p={os.pullEvent()} local p2=decompress(p[3]) if p[1]=="rednet_message" and p2 then if p2[1]=="gotdisks" then for k,v in pairs(p2[2]) do table.insert(list,v) end if not timer then timer=os.startTimer(1) end end elseif p[1]=="timer" and p[2]==timer then break end end function reformat() diskcnt=0 ms=0 for k,v in pairs(list) do diskcnt=diskcnt+1 if (#disk[v].short)>ms then ms=string.len(disk[v].short) end end end reformat() function cRate(N) if N==nil then return "N/A" end sum=0 for k,v in pairs(N) do sum=sum+v end return (math.floor((sum/#N)*20)/2).."/10" end chs=math.random(1,diskcnt) chs2=1 local renderchoices local renderborder local renderPd local function arender() local function a() if term.isColor() then term.setBackgroundColor(colors.black) end end a() mrender(a) term.clear() mrender(term.clear) renderborder() mrender(renderborder) renderPl() end local function brender() renderchoices() mrender(renderchoices) end function renderchoices() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) for l1=1,Mx do local choice=disk[list[l1+chs-Cy]].short or "Error" term.setCursorPos(1,l1) term.write(string.rep(" ",ms+6)) if l1==Cy then if term.isColor() then term.setTextColor(colors.lime) end choice="["..choice..string.rep(" ",ms-string.len(choice)).."]" else if term.isColor() then term.setTextColor(colors.green) end choice=" "..choice..string.rep(" ",ms-string.len(choice)) end term.setCursorPos(3,l1) write(choice) if tSel[l1+chs-Cy] then term.setCursorPos(1,l1) if term.isColor() then term.setTextColor(colors.blue) end term.write("*") end if term.isColor() then term.setTextColor(colors.white) end end term.setCursorPos(9+ms,1) term.write(string.rep(" ",Mx-(7+ms))) term.setCursorPos(9+ms,1) local full if not list[chs] then full="Unknown" elseif disk[list[chs]].real then full=disk[list[chs]].real else full=list[chs] end if term.isColor() then term.setTextColor(colors.blue) end term.write("Full name: ") if term.isColor() then term.setTextColor(colors.lime) end term.write(full) term.setCursorPos(9+ms,3) term.write(string.rep(" ",Mx-(7+ms))) term.setCursorPos(9+ms,3) if term.isColor() then term.setTextColor(colors.blue) end term.write("Artist: ") if term.isColor() then term.setTextColor(colors.lime) end term.write(disk[list[chs]].artist) if term.isColor() then term.setTextColor(colors.white) end end function renderborder() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) for l1=1,My do term.setCursorPos(ms+7,l1) if term.isColor() then term.setTextColor(colors.lightBlue) end term.write("|") end term.setCursorPos(8+ms,7) term.write(string.rep("-",Mx-(ms+7))) if term.isColor() then term.setCursorPos(9+ms,5) for k,v in pairs({"Stop","Play","Select"}) do term.setTextColor(colors.blue) term.write(v) if k~=3 then term.setTextColor(colors.lime) term.write(" | ") end end end if term.isColor() then term.setTextColor(colors.lightBlue) end term.setCursorPos(8+ms,My-1) term.write(string.rep("-",Mx-(ms+7))) if term.isColor() then term.setCursorPos(9+ms,My) for k,v in pairs({"Update","Info","Settings"}) do term.setTextColor(colors.blue) if not (isMon and k==3) then term.write(v) end if (k~=3 and isMon) or (not isMon) then term.setTextColor(colors.lightBlue) term.write(" | ") end end end term.setTextColor(colors.white) end function renderPd(nm,dtr) if disk[nm].short=="" then return end term.clear() mrender(term.clear) local udtimer=os.startTimer(1) local progress=0 local progress=0 local function render() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) if term.isColor() then term.setTextColor(colors.lightBlue) end for l1=1,4 do term.setCursorPos(4,Cy+l1-2) term.write("|"..string.rep(" ",Mx-8).."|") end term.setCursorPos(4,Cy-2) term.write(","..string.rep("-",Mx-8)..",") term.setCursorPos(4,Cy+2) term.write("'"..string.rep("-",Mx-8).."'") local full if disk[nm].real then full=disk[nm].real else full=nm end local txt="Now playing: "..full term.setCursorPos(Cx-math.floor(#txt/2),Cy-1) if term.isColor() then term.setTextColor(colors.green) end term.write("Now playing: ") if term.isColor() then term.setTextColor(colors.lime) end term.write(full) if term.isColor() then term.setTextColor(colors.blue) end term.setCursorPos(5,Cy+1) term.write(string.rep("=",math.floor((Mx-11)*(progress/(disk[nm].len))))) if term.isColor() then term.setTextColor(colors.cyan) end term.write("|-|") if term.isColor() then term.setTextColor(colors.blue) end term.write(string.rep("=",Mx-(math.floor((Mx-11)*(progress/(disk[nm].len)))+11))) if term.isColor() then term.setCursorPos(Mx-8,Cy-2) term.setTextColor(colors.blue) term.write("Back") term.setCursorPos(Mx-13,Cy-2) if dtr then term.write("Next") else term.write("Stop") end term.setTextColor(colors.cyan) end local remaning=(disk[nm].len)-progress local secs=remaning-(math.floor(remaning/60)*60) if secs<10 then secs="0"..secs end local text=" ["..math.floor(remaning/60)..":"..secs.."] " term.setCursorPos(Cx-math.floor((#text)/2),Cy) term.write(text) if term.isColor() then term.setTextColor(colors.white) end end render() mrender(render) while true do local p={os.pullEvent()} local p2=decompress(p[3]) if p[2]==udtimer then if math.floor(progress/(disk[nm].len))>=1 then break end udtimer=os.startTimer(1) progress=progress+1 render() mrender(render) elseif p[1]=="key" and p[2]==28 then if not dtr then arender() brender() end return "menu" elseif p[1]=="key" and p[2]==14 then rednet.broadcast(compress("diskstop")) if not dtr then arender() brender() end return "next" elseif p[1]=="monitor_touch" then os.queueEvent("mouse_click",3,p[3],p[4]) elseif p[1]=="mouse_click" and (p[2]==1 or p[2]==3) then local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) if p[2]==3 then mrender(function() Mx,My=term.getSize() Cx,Cy=math.floor(Mx/2),math.floor(My/2) end) end if (p[3]<=Mx-5 and p[3]>=Mx-8) and p[4]==Cy-2 then os.queueEvent("key",28) elseif (p[3]<=Mx-9 and p[3]>=Mx-13) and p[4]==Cy-2 then os.queueEvent("key",14) end end if p2 and p[1]=="rednet_message" then if p2[1]=="diskstop" then return elseif p2[1]=="diskplay" and not dtr then if disk[p2[2]].short~="" then udtimer=os.startTimer(1) progress=0 nm=p2[2] end end end end if not dtr then arender() brender() end end playlist={shf=0,rep=1,tme=0} function nxtup(nm) if playlist.tme==0 then return end local tLeft=playlist.tme local function rtop() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) term.clear() local text="Next up:" local text2 if disk[nm].real then text2=disk[nm].real else text2=nm end term.setTextColor(colors.green) term.setCursorPos(Cx-math.floor((#text)/2),Cy-1) term.write(text) term.setTextColor(colors.lime) term.setCursorPos(Cx-math.floor((#text2)/2),Cy) term.write(text2) end local function render() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) local secs=tLeft-(math.floor(tLeft/60)*60) if secs<10 then secs="0"..secs end local text=" ["..math.floor(tLeft/60)..":"..secs.."] " term.setTextColor(colors.cyan) term.setCursorPos(Cx-math.floor((#text)/2),Cy+1) term.write(text) end rtop() mrender(rtop) local tm=os.startTimer(0) while true do local p={os.pullEvent()} local p2=decompress(p[3]) if p[1]=="timer" then if p[2]==tm then tLeft=tLeft-1 render() mrender(render) tm=os.startTimer(1) if tLeft==0 then sleep(1) return end end elseif p[1]=="rednet_message" and p2 then if p2[1]=="diskstop" then break elseif p2[1]=="diskplay" then renderPd(p2[2]) end elseif p[1]=="mouse_click" and (p[2] == 1 or p[2] == 3) then local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) if p[2]==3 then mrender(function() Mx,My=term.getSize() Cx,Cy=math.floor(Mx/2),math.floor(My/2) end) end local text if disk[nm].real then text=disk[nm].real else text=nm end local x,y=p[3],p[4] if x>=(Cx-math.floor((#text)/2)) and x<=((Cx-math.floor((#text)/2))+(#text)-1) and y==Cy then break end elseif p[1]=="monitor_touch" then os.queueEvent("mouse_click",3,p[3],p[4]) end end end function openWn(nm) local function tRender() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) if term.isColor() then term.setTextColor(colors.lightBlue) end term.clear() term.setCursorPos(2,2) term.write(","..string.rep("-",Mx-4)..",") term.setCursorPos(2,My-1) term.write("'"..string.rep("-",Mx-4).."'") for l1=3,My-2 do term.setCursorPos(2,l1) term.write("|"..string.rep(" ",Mx-4).."|") end if term.isColor() then term.setTextColor(colors.blue) end local names={"Info","Settings"} term.setCursorPos(Cx-math.floor((#names[nm])/2),2) term.write(names[nm]) --if term.isColor() then -- term.setTextColor(colors.blue) --end --term.setCursorPos(Mx-6,2) --term.write("Back") local credits={ code={"PixelToast"}, } if nm==1 then term.setCursorPos(Cx-4,3) term.write("v1.1.0b2") if term.isColor() then term.setTextColor(colors.green) end term.setCursorPos(Cx-4,5) term.write("Credits: ") local cnt=0 for k,v in pairs(credits) do for j,l in pairs(v) do term.setCursorPos(4,6+cnt) cnt=cnt+1 if term.isColor() then term.setTextColor(colors.lime) end term.write(l) if term.isColor() then term.setTextColor(colors.green) end term.write(" - ") if term.isColor() then term.setTextColor(colors.blue) end term.write(k) end end end end tRender() mrender(tRender) while true do local p={os.pullEvent()} if p[1]=="monitor_touch" or p[1]=="mouse_click" then break end end arender() brender() end function renderPl() local function render() local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) if term.isColor() then playlist.tme=math.max(0,playlist.tme) term.setTextColor(colors.blue) term.setCursorPos(ms+9,9) term.write("Shuffle: ") playlist.shf=playlist.shf%2 if playlist.shf==1 then term.setTextColor(colors.lime) term.write("ON ") else term.setTextColor(colors.red) term.write("OFF") end term.setTextColor(colors.blue) term.setCursorPos(ms+9,10) term.write("Repeat: ") playlist.rep=playlist.rep%2 if playlist.rep==1 then term.setTextColor(colors.lime) term.write("ON ") else term.setTextColor(colors.red) term.write("OFF") end term.setCursorPos(ms+9,11) term.setTextColor(colors.blue) term.write("Time: ") term.setTextColor(colors.lime) local secs=playlist.tme-(math.floor(playlist.tme/60)*60) if secs<10 then secs="0"..secs end local text=math.floor(playlist.tme/60)..":"..secs term.write(text..string.rep(" ",Mx-(ms+14+(#text)))) term.setCursorPos(ms+9,12) term.setTextColor(colors.blue) term.write("< << >> >") end end render() mrender(render) end local function playPl() playlist.dat={} while true do local sSel if playlist.shf==1 then while sSel==nil or playlist.dat[sSel] do sSel=math.random(1,#sel) end else sSel=#playlist.dat+1 end nxtup(list[sel[sSel]]) rednet.broadcast(compress("diskplay",list[sel[sSel]])) local xtcde=renderPd(list[sel[sSel]],true) if xtcde=="menu" then break elseif xtcde=="next" then sleep(1) end playlist.dat[sSel]=true if #playlist.dat==#sel then if playlist.rep==0 then break end playlist.dat={} end end arender() brender() end arender() brender() local function wrap() if chs>diskcnt then chs=1 elseif chs<1 then chs=diskcnt end end local function flopSel(nm) if tSel[nm] then tSel[nm]=false for k,v in pairs(sel) do if v==(nm) then table.remove(sel,k) break end end else tSel[nm]=true table.insert(sel,nm) end end local function main() while true do local typ,key,dat,ext=os.pullEventRaw() if typ=="key" then if key==28 then if #sel>0 then playPl() else rednet.broadcast(compress("diskplay",list[chs])) renderPd(list[chs]) end elseif key==208 then chs=chs+1 wrap() brender() elseif key==200 then chs=chs-1 wrap() brender() elseif key==14 then rednet.broadcast(compress("diskstop")) end elseif typ=="rednet_message" then local c=decompress(dat) if c then if c[1]=="diskplay" and disk[c[2]].len>0 then renderPd(c[2]) end elseif c[1]=="gotdisks" then for k,v in pairs(c[2]) do local exists=false for k,v2 in pairs(list) do if v==v2 then exists=true end end if not exists then table.insert(list,v) end end reformat() brender() end elseif typ=="mouse_scroll" then chs=chs+key wrap() brender() elseif typ=="mouse_click" and (key == 1 or key == 3) then local Mx,My=term.getSize() local Cx,Cy=math.floor(Mx/2),math.floor(My/2) if key==3 then mrender(function() Mx,My=term.getSize() Cx,Cy=math.floor(Mx/2),math.floor(My/2) end) end local x,y=dat,ext if x<ms+4 and x>=4 and list[y+chs-Cy] then if chs==y+chs-Cy then os.queueEvent("key",28) else chs=y+chs-Cy wrap() brender() end elseif (x==1 or x==2) and list[y+chs-Cy] then flopSel(y+chs-Cy) brender() elseif (x<=12+ms and x>=9+ms) and y==5 then -- Stop os.queueEvent("key",14) elseif (x<=19+ms and x>=16+ms) and y==5 then -- Play os.queueEvent("key",28) elseif (x<=28+ms and x>=23+ms) and y==5 then -- Select flopSel(chs) brender() elseif (x<=15+ms and x>=9+ms) and y==9 then -- Shuffle playlist.shf=playlist.shf+1 renderPl() elseif (x<=14+ms and x>=9+ms) and y==10 then -- Repeat playlist.rep=playlist.rep+1 renderPl() elseif (x<=17+ms and x>=9+ms) and y==12 then -- < << >> > if x==9+ms then -- < playlist.tme=playlist.tme-5 -- << elseif x==11+ms or x==12+ms then playlist.tme=playlist.tme-60 elseif x==14+ms or x==15+ms then -- >> playlist.tme=playlist.tme+60 elseif x==17+ms then -- > playlist.tme=playlist.tme+5 end renderPl() elseif (x<=14+ms and x>=9+ms) and y==My then -- Update update() doupdate=true break elseif (x<=21+ms and x>=18+ms) and y==My then -- Info openWn(1) elseif (x<=32+ms and x>=25+ms) and y==My and key~=3 then -- Settings openWn(2) end elseif typ=="monitor_touch" then os.queueEvent("mouse_click",3,dat,ext) elseif typ=="terminate" then break end end end local a,b=pcall(main) term.setCursorPos(1,1) term.clear() mrender(function() term.setCursorPos(1,1) term.clear() end) if not a then sleep(0) print("Error!") print(b) mrender(function() print(b) end) while true do local p=os.pullEvent() if p=="monitor_touch" or p=="mouse_click" or "key" or "char" then break end end os.reboot() end if doupdate then setfenv(loadfile(shell.getRunningProgram()),setmetatable({tArgs=tArgs},{__index=getfenv()}))() end