Advertisement
TheModerGuy

Minecraft .nbs player

Dec 21st, 2013
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.28 KB | None | 0 0
  1. function loadAPIS()
  2.  
  3.     --[[
  4.         Implementing apis
  5.         - TheModerGuy
  6.     --]]
  7.    
  8.     local function yield()
  9.         os.queueEvent("fake")
  10.         os.pullEvent("fake")
  11.     end
  12.  
  13.     -- read short integer (16-bit) from file
  14.     local function readShort(file)
  15.         return file.read() + file.read() * 256
  16.     end
  17.  
  18.     -- read integer (32-bit) from file
  19.     local function readInt(file)
  20.         return file.read() + file.read() * 256 + file.read() * 65536 + file.read() * 16777216
  21.     end
  22.  
  23.     -- read string from file
  24.     local function readString(file)
  25.         local s = ""
  26.         local len = readInt(file)
  27.         for i = 1, len do
  28.             local c = file.read()
  29.             if not c then
  30.                 break
  31.             end
  32.             s = s..string.char(c)
  33.         end
  34.         return s
  35.     end
  36.  
  37.     -- read nbs file header
  38.     local function readNBSHeader(file)
  39.         local header = {}
  40.         header.lenght = readShort(file)
  41.         header.height = readShort(file)
  42.         header.name = readString(file)
  43.         if header.name == "" then
  44.             header.name = "Untitled"
  45.         end
  46.         header.author = readString(file)
  47.         if header.author == "" then
  48.             header.author = "Unknown"
  49.         end
  50.         header.original_author = readString(file)
  51.         if header.original_author == "" then
  52.             header.original_author = "Unknown"
  53.         end
  54.         header.description = readString(file)
  55.         header.tempo = readShort(file) / 100
  56.         header.autosave = file.read()
  57.         header.autosave_duration = file.read()
  58.         header.time_signature = file.read()
  59.         header.minutes_spent = readInt(file)
  60.         header.left_clicks = readInt(file)
  61.         header.right_clicks = readInt(file)
  62.         header.blocks_added = readInt(file)
  63.         header.blocks_removed = readInt(file)
  64.         header.filename = readString(file)
  65.         return header
  66.     end
  67.  
  68.     -- jump to the next tick in the file
  69.     local function nextTick(file, tSong)
  70.         local jump = readShort(file)
  71.         for i = 1, jump - 1 do
  72.             table.insert(tSong, {})
  73.         end
  74.         return jump > 0
  75.     end
  76.  
  77.     -- read the notes in a tick
  78.     local function readTick(file)
  79.         local t = {}
  80.         local jump = readShort(file)
  81.         while jump > 0 do
  82.             local instrument = file.read() + 1
  83.             if instrument > 5 then
  84.                 return nil, "Can't convert custom instruments"
  85.             end
  86.             local note = file.read() - 33
  87.             if note < 0 or note > 24 then
  88.                 return nil, "Notes must be in Minecraft's 2 octaves"
  89.             end
  90.             if not t[instrument] then
  91.                 t[instrument] = {}
  92.             end
  93.             table.insert(t[instrument], note)
  94.             jump = readShort(file)
  95.         end
  96.         return t
  97.     end
  98.  
  99.     -- API functions
  100.  
  101.     -- save a converted song to a file
  102.     function nbsSaveSong(tSong, sPath)
  103.         local file = fs.open(sPath, "w")
  104.         if file then
  105.             file.write(textutils.serialize(tSong))
  106.             file.close()
  107.             return true
  108.         end
  109.         return false, "Error opening file "..sPath
  110.     end
  111.  
  112.     -- load and convert an .nbs file and save it
  113.     function nbsLoad(sPath, bVerbose)
  114.         local file = fs.open(sPath, "rb")
  115.         if file then
  116.             if bVerbose then
  117.                 print("Reading header...")
  118.             end
  119.             local tSong = {}
  120.             local header = readNBSHeader(file)
  121.             tSong.name = header.name
  122.             tSong.author = header.author
  123.             tSong.original_author = header.original_author
  124.             tSong.lenght = header.lenght / header.tempo
  125.             tSong.delay = 1 / header.tempo
  126.             if bVerbose then
  127.                 print("Reading ticks...")
  128.             end
  129.             while nextTick(file, tSong) do
  130.                 local tick, err = readTick(file, tSong)
  131.                 if tick then
  132.                     table.insert(tSong, tick)
  133.                 else
  134.                     file.close()
  135.                     return nil, err
  136.                 end
  137.                 yield()
  138.             end
  139.             file.close()
  140.             return tSong
  141.         end
  142.         return nil, "Error opening file "..sPath
  143.     end
  144.  
  145.     local total = 0;
  146.     local slept = 0;
  147.     local function _round(_i)
  148.       _i = _i * 20;
  149.       if _i >= 0 then
  150.         return math.floor(_i+.5) / 20
  151.       else
  152.         return math.ceil(_i-.5) / 20
  153.       end
  154.     end
  155.     function atsWait(_sleep)
  156.       if _sleep < 0 then return end
  157.       total = total + _sleep;
  158.       _sleep = _round(_sleep);
  159.       slept = slept + _sleep;
  160.       if (slept - total) >= 0.05 then
  161.         _sleep = _sleep - 0.05;
  162.         slept = slept - 0.05;
  163.       elseif (slept - total) < -0.05 then
  164.         _sleep = _sleep + 0.05;
  165.         slept = slept + 0.05;
  166.       end
  167.       sleep(_sleep);
  168.     end
  169. end
  170.  
  171. local args = {...} -- args table
  172.  
  173. if args[2]~= nil then
  174.     loop=args[2]
  175. end
  176.  
  177. loadAPIS()
  178.  
  179. local played,played2=true,true
  180. local delay,lenght
  181. local side,textColor,bgColor,notesPlayed,row=0,1,2,0,0
  182.  
  183. local notenames = {"F#3"," G3","G#3"," A3","A#3"," B3",
  184. " C4","C#4"," D4","D#4"," E4"," F4","F#4"," G4",
  185. "G#4"," A4","A#4"," B4"," C5","C#5"," D5","D#5",
  186. " E5"," F5","F#5"}
  187. local instnames = {"PIANO","BASS DRUM","SNARE","CLICKS",
  188. "BASS GUITAR"}
  189.  
  190. -- ID is the NoteBlock ID to use
  191. local id=1
  192. -- Modem stuff
  193. function getSide()
  194.     for n,side in pairs(rs.getSides()) do
  195.       if peripheral.getType( side )=="modem" then
  196.         return side
  197.       end
  198.     end
  199. end
  200. rednet.open(getSide())
  201. local MODEM = peripheral.wrap(getSide())
  202. local PERIPHERALS = MODEM.getNamesRemote()
  203. local maxId = #(MODEM.getNamesRemote())
  204.  
  205. local function play(inst,note)
  206.  
  207.   if inst==1 then
  208.     inst=0
  209.   elseif inst==2 then
  210.     inst=4
  211.   elseif inst==3 then
  212.     inst=1
  213.   elseif inst==4 then
  214.     inst=2
  215.   elseif inst==5 then
  216.     inst=3
  217.   end
  218.  
  219.   id = id > maxId and 1 or id
  220.  
  221.   textColor = textColor * (textColor == bgColor and 2 or 1)
  222.  
  223.   textColor = textColor >= colors.black and 1 or textColor
  224.  
  225.   MODEM.callRemote(PERIPHERALS[id],"playNote",inst,note)
  226.  
  227.   local str = instnames[inst+1] .." "..notenames[note+1]
  228.   local str = instnames[inst+1] .." "..notenames[note+1]
  229.  
  230.  
  231.   id = id + 1
  232.   notesPlayed = notesPlayed + 1
  233. end
  234.  
  235.  
  236. local function load(file)
  237.   local tSong = nbsLoad(file)
  238.   delay = tSong.delay
  239.   lenght = tSong.lenght
  240.   realLenght = lenght * (1/delay)
  241.  
  242.   for a,b in pairs(tSong) do
  243.     if type(b)=="table" then
  244.       for inst,d in pairs(b) do
  245.  
  246.         for e,note in pairs(d) do
  247.  
  248.           play(inst,note)
  249.         end
  250.  
  251.         played2=true
  252.       end
  253.  
  254.       if played2==true then
  255.         played=true
  256.         played2=false
  257.       end
  258.  
  259.       atsWait(delay)
  260.       row = row + 1
  261.  
  262.       if rs.getInput("front") then
  263.         return
  264.       end
  265.     end
  266.   end
  267. end
  268.  
  269. while true do
  270.    
  271.     id,msg,dist = rednet.receive()
  272.     data = string.gmatch(msg, "%S+")
  273.     if data(1) == "Player" then
  274.         print("Me")
  275.        
  276.         if data(2)== "Play" then
  277.            
  278.             InFile = data(3)
  279.             print("Play")
  280.             load(tostring(InFile))
  281.                
  282.             rednet.broadcast("DJ DONE")
  283.        
  284.         end
  285.        
  286.         if data(2)=="Util" then
  287.        
  288.         print("Util")
  289.        
  290.             shell.run(tostring(data(3)))
  291.            
  292.         end
  293.        
  294.     end
  295.  
  296. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement