YoYoYonnY

Game API

Dec 30th, 2013
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.03 KB | None | 0 0
  1. --[[            Game API
  2.             By: YoYoYonnY
  3.         First Release: 27/12/2013
  4.         Last Update: 27/12/2013
  5. ]]--
  6.  
  7.             --[[ SECTION: Local Variables ]]--
  8. local w, h = term.getSize()
  9. local path = "Games"
  10. local path_games = "Games/Games"
  11. local path_data = "Games/Data"
  12. local path_players = "Games/Players"
  13. local path_saves = "Games/Saves"
  14. local path_achievements = "Games/Achievements"
  15. local path_stats = "Games/Stats"
  16. local path_score = "Games/Score"
  17. local path_log = "log"
  18. local debug = false
  19.  
  20.             --[[ SECTION: Global Variables ]]--
  21.  
  22. player = {}
  23. game = {}
  24. achievement = {}
  25. stat = {}
  26. scoreboard = {}
  27. score = {}
  28.  
  29.             --[[ SECTION: Local Functions ]]--
  30.  
  31. local function log( s )
  32.     if debug then
  33.         if not fs.exists( path_log ) then
  34.             local f = fs.open( path_log, "w" )
  35.             f.close()
  36.         end
  37.         local f = fs.open( path_log, "a" )
  38.         f.write( tostring( "[" .. textutils.formatTime( os.time(), true ) .. "] " .. s .. "\n" ) )
  39.         f.close()
  40.     end
  41. end
  42. local function logstring( s )
  43.     if type( s ) == "table" then
  44.         return textutils.serialize( s )
  45.     elseif type( s ) == "function" then
  46.         return "function() end"
  47.     end
  48.     return tostring( s )
  49. end
  50. local function mkdir( path )
  51.     if not fs.exists( path ) then
  52.         log( "mkdir " .. path )
  53.         return fs.makeDir( path )
  54.     end
  55. end
  56. local function install()
  57.     fs.delete( path_log )
  58.     log( "Log opened" )
  59.     mkdir( path )
  60.     mkdir( path_games )
  61.     mkdir( path_data )
  62.     mkdir( path_players )
  63.     mkdir( path_saves )
  64.     mkdir( path_achievements )
  65.     mkdir( path_stats )
  66.     mkdir( path_score )
  67. end
  68. local function getGameData( game, key )
  69.     log( "gathering data for " .. game .. ": " .. key )
  70.     local path = fs.combine( path_data, game )
  71.     if not fs.isReadOnly( path ) and not fs.isDir( path ) then
  72.         local f = fs.open( path, "r" )
  73.         local s = f.readAll()
  74.         f.close()
  75.         return textutils.unserialize( s )[ key ]
  76.     end
  77.     return false
  78. end
  79. local function addGame( path, data )
  80.     local function setGameData( game, key, value )
  81.         local path = fs.combine( path_data, game )
  82.         if not fs.isReadOnly( path ) and not fs.isDir( path ) then
  83.             log( "setting data for " .. game .. ": " .. key .. " = " .. value )
  84.             if fs.exists( path ) then
  85.                 local f = fs.open( path, "r" )
  86.                 local s = f.readAll()
  87.                 local t = textutils.unserialize( s )
  88.                 f.close()
  89.             else
  90.                 t = {}
  91.             end
  92.             t[ key ] = value
  93.             s = textutils.serialize( t )
  94.             local f = fs.open( path, "w" )
  95.             f.write( s )
  96.             f.close()
  97.             return true
  98.         end
  99.         return false
  100.     end
  101.     local game = data[ "game" ]
  102.     local name = data[ "name" ] or data[ "game" ]
  103.     local path = data[ "path" ] or data[ "game" ]
  104.     local path_game = fs.combine( path_games, game )
  105.     mkdir( path_game )
  106.     setGameData( game, "name", name )
  107.     setGameData( game, "path", path )
  108.     if #data[ "run" ] == 8 then
  109.         if http then
  110.             f = http.get( "http://www.pastebin.com/" .. data[ "run" ] )
  111.             if f then
  112.                 run = f.readAll()
  113.                 f.close()
  114.             else
  115.                 run = data[ "run" ]
  116.             end
  117.         else
  118.             return false
  119.         end
  120.     else
  121.         run = data[ "run" ]
  122.     end
  123.     f = fs.open( fs.combine( path_game, "run" ), "w" )
  124.     f.write( run )
  125.     f.close()
  126.     for k in pairs( data ) do
  127.         if k ~= "game" and k ~= "name" and k ~= "path" and k ~= "run" then
  128.             folder = fs.combine( path_game, string.sub( k, 1, #k - #fs.getName( k ) - 1 ) )
  129.             mkdir( folder )
  130.             f = fs.open( fs.combine( path_game, k ), "w" )
  131.             f.write( data[ k ] )
  132.             f.close()
  133.         end
  134.     end
  135.     return true
  136. end
  137. local function valid( s )
  138.     tInvalid = {"\\","/",":",",","*","?","\"","<",">","|","%."}
  139.     for k, v in ipairs( tInvalid ) do
  140.         if string.find( s, v ) then
  141.             log( "invalid string: \"" .. s .. "\" (char " .. v .. " is invalid)" )
  142.             return false
  143.         end
  144.     end
  145.     return true
  146. end
  147. local function checkPlayer( username, password )
  148.     local path = fs.combine( path_players, username )
  149.     if fs.exists( path ) and not fs.isDir( path ) then
  150.         local f = fs.open( path, "r" )
  151.         local s = f.readAll()
  152.         local t = textutils.unserialize( s )
  153.         f.close()
  154.         if t[ "username" ] == username and t[ "password" ] == password then
  155.             return true
  156.         end
  157.     end
  158.     return false
  159. end
  160. local function playerData( username, key, value )
  161.     local path = fs.combine( path_players, username )
  162.     if fs.exists( path ) and not fs.isReadOnly( path ) then
  163.         local f = fs.open( path, "r" )
  164.         local s = f.readAll()
  165.         local t = textutils.unserialize( s )
  166.         f.close()
  167.         if not key then
  168.             return t
  169.         end
  170.         if value then
  171.             log( "editing " .. logstring( username ) .. "'s data. [\"" .. logstring( key ) .. "\"] = " .. logstring( value ) )
  172.             t[ key ] = value
  173.             f = fs.open( path, "w" )
  174.             s = textutils.serialize( t )
  175.             f.write( s )
  176.             f.close()
  177.             return t
  178.         else
  179.             log( "gathering " .. logstring( username ) .. "'s data. [\"" .. logstring( key ) .. "\"] = " .. logstring( t[ key ] ) )
  180.             return t[ key ]
  181.         end
  182.     end
  183.     return false
  184. end
  185.  
  186.             --[[ SECTION: Login System ]]--
  187.  
  188. function player.add( username, password, name )
  189.     local path = fs.combine( path_players, username )
  190.     if not fs.exists( path ) and not fs.isDir( path ) and not fs.isReadOnly( path ) and valid( username ) and valid( password ) then
  191.         local f = fs.open( path, "w" )
  192.         local t = {["username"]=username,["password"]=password,["path"]=path,["name"]=name or username,["achievement"]={},["stat"]={},["score"]={}}
  193.         f.write( textutils.serialize( t ) )
  194.         f.close()
  195.         return true
  196.     end
  197.     return false
  198. end
  199. function player.remove( username, password )
  200.     local path = fs.combine( path_players, username )
  201.     if fs.exists( path ) and not fs.isReadOnly( path ) and checkPlayer( username, password ) then
  202.         fs.delete( path )
  203.         return true
  204.     end
  205.     return false
  206. end
  207. function player.list()
  208.     local users = {}
  209.     if fs.exists( path_players ) then
  210.         local list = fs.list( path )
  211.         for k, v in ipairs( list ) do
  212.             local path = fs.combine( path_players, list[ k ] )
  213.             local f = fs.open( path, "r" )
  214.             local s = f.readAll()
  215.             local t = textutils.unserialize()
  216.             if type( t ) == "table" and t[ "username" ] and t[ "password" ] then
  217.                 table.insert( users, t[ "username" ] )
  218.             end
  219.             f.close()
  220.         end
  221.     end
  222.     return users
  223. end
  224. function player.current( username )
  225.     local path = fs.combine( path_players, ".current" )
  226.     if not fs.isDir( path ) and not fs.isReadOnly( path ) then
  227.         if not username then
  228.             if fs.exists( path ) then
  229.                 local f = fs.open( path, "r" )
  230.                 local current = f.readAll()
  231.                 f.close()
  232.                 return current
  233.             end
  234.             return
  235.         elseif username == "" then
  236.             fs.delete( path )
  237.         else
  238.             local f = fs.open( path, "w" )
  239.             f.write( username )
  240.             f.close()
  241.         end
  242.         return true
  243.     end
  244.     return false
  245. end
  246. function player.login( username, password, online )
  247.     if online then
  248.        
  249.     else
  250.         if checkPlayer( username, password ) then
  251.             player.current( username )
  252.             local t = {}
  253.             t.path = playerData( username, "path" )
  254.             t.name = playerData( username, "name" )
  255.             t.username = playerData( username, "username" )
  256.             t.password = playerData( username, "password" )
  257.             t.online = false
  258.             function t.achievements()
  259.                 return playerData( username, "achievement" )
  260.             end
  261.             function t.stats()
  262.                 return playerData( username, "stat" )
  263.             end
  264.             function t.score()
  265.                 return playerData( username, "score" )
  266.             end
  267.             function t:update( self )
  268.                 return self
  269.             end
  270.             function t.logout()
  271.                 player.current( "" )
  272.             end
  273.             return t
  274.         end
  275.         return
  276.     end
  277. end
  278.  
  279.             --[[ SECTION: Game Engine ]]--
  280.  
  281. function game.install( path )
  282.     if fs.exists( path ) and not fs.isDir( path ) then
  283.         log( "installing game from path " .. path )
  284.         local f = fs.open( path, "r" )
  285.         local s = f.readAll()
  286.         local data = textutils.unserialize( s )
  287.         f.close()
  288.         return addGame( path, data )
  289.     end
  290.     return false
  291. end
  292. function game.add( game, data )
  293.     local path = fs.combine( path_games, game )
  294.     log( "adding game from game data (" .. game .. ")" )
  295.     return addGame( game, data )
  296. end
  297. function game.remove( game )
  298.     local path = fs.combine( path_games, game )
  299.     log( "removing game " .. game )
  300.     fs.delete( game )
  301. end
  302. function game.start( game )
  303.     log( "starting game: " .. game )
  304.     local path = fs.combine( path_games, fs.combine( getGameData( game, "path" ), "run" ) )
  305.     local t = {}
  306.     t.game = game
  307.     t.path = path
  308.     function t.save( data, name )
  309.         local path = fs.combine( path_saves, fs.combine( getGameData( t.game, "path" ), name ) )
  310.         if not fs.isReadOnly( path ) and not fs.isDir( path ) then
  311.             local f = fs.open( path, "w" )
  312.             f.write( textutils.serialize( data ) )
  313.             f.close()
  314.             return true
  315.         end
  316.         return false
  317.     end
  318.     function t.load( name )
  319.         local path = fs.combine( path_saves, fs.combine( getGameData( t.game, "path" ), name ) )
  320.         if fs.exists( path ) and not fs.isReadOnly( path ) then
  321.             local f = fs.open( path, "r" )
  322.             local s = f.readAll()
  323.             f.close()
  324.             return textutils.unserialize( s )
  325.         end
  326.         return false
  327.     end
  328.     return t
  329. end
  330. function game.run( game )
  331.     log( "running game: " .. game )
  332.     path = fs.combine( path_games, fs.combine( getGameData( game, "path" ), "run" ) )
  333.     if fs.exists( path ) then
  334.         return shell.run( path )
  335.     end
  336.     return false
  337. end
  338.  
  339.             --[[ SECTION: Achievements ]]--
  340.  
  341. function achievement.add( achievement, desc, secret )
  342.     local path = fs.combine( path_achievements, achievement )
  343.     if not fs.exists( path ) and not fs.isDir( path ) and not fs.isReadOnly( path ) and valid( achievement ) then
  344.         log( "Adding achievement " .. achievement )
  345.         local f = fs.open( path, "w" )
  346.         local t = {["name"]=achievement,["desc"]=desc,["secret"]=secret or false}
  347.         f.write( textutils.serialize( t ) )
  348.         f.close()
  349.         return achievement
  350.     end
  351.     return false
  352. end
  353. function achievement.remove( achievement )
  354.     local path = fs.combine( path_achievements, achievement )
  355.     if fs.exists( path ) and not fs.isReadOnly( path ) then
  356.         log( "Removing achievement " .. achievement )
  357.         fs.delete( path )
  358.         return true
  359.     end
  360.     return false
  361. end
  362. function achievement.unlock( p, achievement )
  363.     log( "unlocking achievement " .. achievement .. " for player " .. p.name )
  364.     local achievements = playerData( p.username, "achievement" )
  365.     achievements[ achievement ] = true
  366.     playerData( p.username, "achievement", achievements )
  367.     return playerData( p.username )
  368. end
  369. function achievement.lock( p, achievement )
  370.     log( "locking achievement " .. achievement .. " for player " .. p.name )
  371.     local achievements = playerData( p.username, "achievement" )
  372.     achievements[ achievement ] = false
  373.     playerData( p.username, "achievement", achievements )
  374.     return playerData( p.username )
  375. end
  376. function achievement.list()
  377.     local achievements = {}
  378.     local path = path_achievements
  379.     if fs.exists( path ) then
  380.         log( "listing achievements" )
  381.         local list = fs.list( path )
  382.         for k, v in ipairs( list ) do
  383.             local f = fs.open( fs.combine, "r" )
  384.             local s = f.readAll()
  385.             local t = texutils.unserialize( s )
  386.             f.close()
  387.             table.insert( achievements, t[ "name" ] )
  388.         end
  389.     end
  390.     return achievements
  391. end
  392.  
  393.             --[[ SECTION: Stats ]]--
  394.  
  395. function stat.add( stat, desc, suffix )
  396.     local path = fs.combine( path_stats, stat )
  397.     if not fs.exists( path ) and not fs.isDir( path ) and not fs.isReadOnly( path ) and valid( stat ) then
  398.         log( "adding stat" .. stat )
  399.         local f = fs.open( path, "w" )
  400.         local t = {["name"]=stat,["desc"]=desc,["suffix"]=suffix}
  401.         f.write( t )
  402.         f.close()
  403.         return stat
  404.     end
  405.     return false
  406. end
  407. function stat.remove( stat )
  408.     local path = fs.combine( path_stats, stat )
  409.     if fs.exists( path ) and not fs.isReadOnly( path ) then
  410.         log( "removing stat" .. stat )
  411.         fs.delete( path )
  412.         return true
  413.     end
  414.     return false
  415. end
  416. function stat.set( p, stat, value )
  417.     log( "setting stat " .. stat .. " to " .. value .. " for player " .. p.name )
  418.     local stats = playerData( p.username, "stat" )
  419.     stats[ stat ] = value
  420.     return playerData( p.username )
  421. end
  422. function stat.list()
  423.     local stats = {}
  424.     local path = path_stats
  425.     if fs.exists( path ) then
  426.         log( "listing stats" )
  427.         local list = fs.list( path )
  428.         for k, v in ipairs( list ) do
  429.             local f = fs.open( fs.combine, "r" )
  430.             local s = f.readAll()
  431.             local t = texutils.unserialize( s )
  432.             f.close()
  433.             table.insert( stats, t[ "name" ] )
  434.         end
  435.     end
  436.     return stats
  437. end
  438.  
  439.             --[[ SECTION: Score ]]--
  440.  
  441. function scoreboard.add( objective, desc )
  442.     local path = fs.combine( path_score, objective )
  443.     if not fs.exists( path ) and not fs.isDir( path ) and not fs.isReadOnly( path ) and valid( objective ) then
  444.         log( "adding objective " .. objective )
  445.         local f = fs.open( path, "w" )
  446.         local t = {["name"]=objective,["desc"]=desc}
  447.         f.write( textutils.serialize( t ) )
  448.         f.close()
  449.         return objective
  450.     end
  451.     return false
  452. end
  453. function scoreboard.remove( objective )
  454.     local path = fs.combine( path_score, objective )
  455.     if fs.exists( path ) and not fs.isReadOnly( path ) then
  456.         log( "removing objective " .. objective )
  457.         fs.delete( path )
  458.         return true
  459.     end
  460.     return false
  461. end
  462. function scoreboard.list()
  463.     local scoreboard = {}
  464.     local path = fs.combine( path_score )
  465.     if fs.exists( path ) then
  466.         log( "listing objectives" )
  467.         local list = fs.list( path )
  468.         for k, v in ipairs( list ) do
  469.             local f = fs.open( fs.combine, "r" )
  470.             local s = f.readAll()
  471.             local t = texutils.unserialize( s )
  472.             f.close()
  473.             table.insert( scoreboard, t[ "name" ] )
  474.         end
  475.     end
  476.     return scoreboard
  477. end
  478. function score.set( p, objective, value )
  479.     log( "setting score " .. objective .. " to " .. value .. " for player " .. p.name )
  480.     local score = playerData( p.username, "score" )
  481.     score[ objective ] = value
  482.     playerData( p.username, "score", score )
  483.     return playerData( p.username )
  484. end
  485. function score.add( p, objective, value )
  486.     log( "adding score " .. objective .. " with " .. value .. " for player " .. p.name )
  487.     local score = playerData( p.username, "score" )
  488.     score[ objective ] = score[ objective ] + value
  489.     playerData( p.username, "score", score )
  490.     return playerData( p.username )
  491. end
  492. function score.remove( p, objective, value )
  493.     log( "removing score " .. objective .. " with " .. value .. " for player " .. p.name )
  494.     local score = playerData( p.username, "score" )
  495.     score[ objective ] = score[ objective ] - value
  496.     playerData( p.username, "score", score )
  497.     return playerData( p.username )
  498. end
  499.  
  500.             --[[ SECTION: Installation ]]--
  501.  
  502. install()
Advertisement
Add Comment
Please, Sign In to add comment