This commit is contained in:
Paul Liverman
2015-03-07 12:21:59 -08:00
parent 16abd571a7
commit 556695535f
5 changed files with 1021 additions and 28 deletions

View File

@@ -0,0 +1,248 @@
love.math.setRandomSeed(os.time())
local input = require "util.input"
-- Gamestates
--local won = require "gamestates.won" --TODO MAKE THIS
local lost = require "gamestates.lost"
local paused = require "gamestates.paused"
-- This Gamestate
local game = {}
-- Locals
local boxes = {}
local score, totalScore = 0, 0
local level, time, startingTime = 0, 0, 0
local previousState, gameSettings, controls
local pingTimer, session = 0, false
--these are defined on each entry to this gamestate
local screenWidth, screenHeight --defines where things are rendered
local boxColumns, boxRows --defines how many boxes
--these are loaded from values passed on entry to this gamestate
local boxSize, colorStep, timeLimit = 20, 80, 60 --default values just in case
local function nextLevel()
log("Creating the next level!")
totalScore = totalScore + score
score = 0
level = level + 1
time = time + timeLimit --your remaining time is added on to the next level
startingTime = time --save where you started on this level for scoring
-- (re)create black boxes
boxes = {}
for i=0,boxColumns do
boxes[i] = {}
for j=0,boxRows do
boxes[i][j] = {0, 0, 0}
end
end
-- assign a random set of boxes random colors
for i=1,math.floor(math.pow(level, 1.07) * 1.03 + 2) do --(level * 1.5 + 2)
local x, y = love.math.random(0, #boxes), love.math.random(0, #boxes[1])
boxes[x][y] = {love.math.random(0, 255), love.math.random(0, 255), love.math.random(0, 255)}
boxes[x][y][1] = boxes[x][y][1] - boxes[x][y][1] % colorStep --is this right?
boxes[x][y][2] = boxes[x][y][2] - boxes[x][y][2] % colorStep
boxes[x][y][3] = boxes[x][y][3] - boxes[x][y][3] % colorStep
end
log("Done!")
end
local function colorsEqual(A, B)
if A[1] == B[1] and A[2] == B[2] and A[3] == B[3] then
return true
end
return false
end
local function copyColor(A)
return {A[1], A[2], A[3]}
end
function game:enter(previous, settings, gameControls, gamejoltSession)
log("Entering game...")
-- save the state we came from
previousState = previous
-- set locals based on screen size
screenWidth = love.graphics.getWidth()
screenHeight = love.graphics.getHeight()
boxColumns = math.floor(screenWidth / boxSize) - 1
boxRows = math.floor(screenHeight / boxSize) - 5
-- save the settings for later use
if settings then
gameSettings = settings
end
--gameSettings = settings or gameSettings
controls = gameControls or controls
session = gamejoltSession
-- ping our active state immediately
if session then
local pingSuccess = Gamejolt.pingSession(true)
if not pingSuccess then
log("Couldn't ping Game Jolt session. Session may close.")
end
end
-- set how to play the game based on settings
boxSize = gameSettings.boxSize
colorStep = gameSettings.colorStep
timeLimit = gameSettings.timeLimit
-- set the font we're going to use
love.graphics.setNewFont(28)
-- this is nextLevel shit
nextLevel()
end
function game:resume(previous, action)
if action == "LOST" then
log("Game restarted.")
game:enter(previousState) --we want to keep the old values
totalScore = 0 --this should have happened in game:leave() but does not for an unknown reason
end
if action == "UNPAUSED" then
log("Game resumed.")
love.graphics.setNewFont(28) -- fix our font!
end
end
function game:update(dt)
-- ping every 30 seconds if we are in a session
pingTimer = pingTimer + dt
if pingTimer >= 30 then
if session then
local pingSuccess = Gamejolt.pingSession(true)
if not pingSuccess then
log("Couldn't ping Game Jolt session. Session may close.") --this is lazy but I don't care
end
end
pingTimer = pingTimer - 30
end
-- check if level complete
local coloredBoxes = {}
for i=0,#boxes do
for j=0,#boxes[i] do
if not colorsEqual(boxes[i][j], {0, 0, 0}) then
table.insert(coloredBoxes, boxes[i][j])
end
end
end
local won, color
if #coloredBoxes >= 2 then
won = true
color = copyColor(coloredBoxes[1])
for i=2,#coloredBoxes do
if not colorsEqual(color, coloredBoxes[i]) then
won = false
end
end
end
if won then
log("Level beat!")
-- TODO we need a brief push/pop of gamestate to display a winning message
nextLevel()
end
-- else decrement time, and check if out of time
time = time - dt
if time <= 0 then
-- TODO we need to pass an image of the screen and data about time of losing
Gamestate.push(lost, love.graphics.newScreenshot(), totalScore + score, controls, session)
-- call leave to clean up the gamestate
game:leave()
end
-- update the current score
score = #coloredBoxes / math.pow(startingTime - time, 0.02) * colorStep
end
function game:draw()
--boxes
for i=0,#boxes do
for j=0,#boxes[i] do
love.graphics.setColor(boxes[i][j])
love.graphics.rectangle("fill", i * boxSize, j * boxSize + boxSize * 2, boxSize, boxSize)
end
end
--lines
-- vertical
love.graphics.setColor(255, 255, 255)
for i=0,boxColumns+1 do
love.graphics.line(i * boxSize, 0 + boxSize * 2, i * boxSize, screenHeight - boxSize * 2)
end
-- horizontal
for j=0,boxRows+1 do
love.graphics.line(0, j * boxSize + boxSize * 2, screenWidth, j * boxSize + boxSize * 2)
end
-- Info Overlays
--love.graphics.setNewFont(28) --purposely stays same no matter screen res
love.graphics.setColor(255, 255, 255)
-- top of screen stuff
love.graphics.printf(string.format("Total Score: %.1f", totalScore), 0, 3, screenWidth / 2, "center")
--love.graphics.printf(string.format("Best Score: %.1f", bestScore), screenWidth / 2, 3, screenWidth / 2, "center")
-- bottom of screen stuff
love.graphics.printf(string.format("Time: %.1f", time), 0, screenWidth / 2 + 25, screenWidth / 2, "center")
love.graphics.printf("Level: "..level, 0, screenWidth / 2 + 25, screenWidth, "center")
love.graphics.printf(string.format("Current Score: %.1f", score), screenWidth / 2, screenWidth / 2 + 25, screenWidth / 2, "center")
end
function game:mousepressed(x, y, button)
-- new x/y adjusted for where boxes actually are
local nx = math.floor(x / boxSize)
local ny = math.floor((y - boxSize * 2) / boxSize)
-- check if we are actually over a box first
if boxes[nx][ny] then
-- left, red
if input(button, controls.red) then
boxes[nx][ny][1] = boxes[nx][ny][1] + colorStep
if boxes[nx][ny][1] > 255 then
boxes[nx][ny][1] = 0
end
-- middle, green
elseif input(button, controls.green) then
boxes[nx][ny][2] = boxes[nx][ny][2] + colorStep
if boxes[nx][ny][2] > 255 then
boxes[nx][ny][2] = 0
end
-- right, blue
elseif input(button, controls.blue) then
boxes[nx][ny][3] = boxes[nx][ny][3] + colorStep
if boxes[nx][ny][3] > 255 then
boxes[nx][ny][3] = 0
end
end
end
end
function game:keypressed(key, unicode)
if input(key, controls.back) then
log("Leaving game...")
Gamestate.switch(previousState)
elseif input(key, controls.pause) then
Gamestate.push(paused, love.graphics.newScreenshot(), controls, session)
end
end
function game:focus(isFocused)
if not isFocused then
Gamestate.push(paused, love.graphics.newScreenshot(), controls, session)
end
end
function game:leave()
-- clear the game upon any exit (except pause)
level = 0
score = 0
totalScore = 0
time = 0
startingTime = 0
end
return game

View File

@@ -0,0 +1,137 @@
local input = require "util.input"
local inifile = require "lib.inifile"
local ser = require "lib.ser"
local Gamestate = require "lib.gamestate"
local game = require "gamestates.game"
local menu = {}
local screenWidth, screenHeight
local settings, controls
local pingTimer, session = 0, false
function menu:init()
log("Initializing menu...")
-- load or create settings
if love.filesystem.isFile("settings.ini") then
log("Loading settings (again)...")
settings = inifile.parse("settings.ini")
else
log("Creating settings...")
settings = {
display = {
width = love.graphics.getWidth(),
height = love.graphics.getHeight(),
fullscreen = false,
borderless = true,
},
gamejolt = {
username = false,
usertoken = false
},
sound = {
music = 0,
sfx = 0
},
difficulty = {
preset = "normal",
timeLimit = 60,
colorStep = 80,
boxSize = 20
}
}
-- TODO WRITE TO FILE
end
-- load or create controls
if love.filesystem.isFile("controls.lua") then
log("Loading controls...")
controls = require "controls"
else
log("Creating controls...")
controls = {
select = {
clicks = {"l"},
buttons = {}
},
back = {
clicks = {},
buttons = {"escape"}
},
pause = {
clicks = {},
buttons = {" ", "escape"}
},
red = {
clicks = {"l"},
buttons = {}
},
green = {
clicks = {"wd", "wu", "m"},
buttons = {}
},
blue = {
clicks = {"r"},
buttons = {}
}
}
-- TODO WRITE THE CONTROLS TO FILE
end
end
function menu:enter(previous, gamejoltSession)
log("Entering menu...")
session = gamejoltSession
-- ping our idle state immediately
if session then
local idleSuccess = Gamejolt.pingSession(false)
if not idleSuccess then
log("Couldn't ping Game Jolt session. Session may close.")
end
end
screenWidth = love.graphics.getWidth()
screenHeight = love.graphics.getHeight()
end
function menu:update(dt)
-- we want to ping every 30 seconds if connected
pingTimer = pingTimer + dt
if pingTimer >= 30 then
if session then
local idleSuccess = Gamejolt.pingSession(false)
if not idleSuccess then
log("Couldn't ping Game Jolt session. Session may close.") --this is lazy but I don't care
end
end
pingTimer = pingTimer - 30
end
end
function menu:draw()
love.graphics.setNewFont(30 * screenWidth / 800)
love.graphics.printf("RGB - The Color Chooser", 0, screenHeight / 7, screenWidth, "center")
love.graphics.setNewFont(16 * screenWidth / 800)
love.graphics.printf("1. Left click to cycle red.\n2. Middle click or scroll to cycle green.\n3. Right click to cycle blue.", 0, screenHeight / 3, screenWidth, "center")
love.graphics.printf("Your goal is to get every panel that is not black to be the same color.", 0, screenHeight / 1.75, screenWidth, "center")
love.graphics.printf("Click to begin.", 0, screenHeight / 1.3, screenWidth, "center")
love.graphics.setNewFont(12 * screenWidth / 800)
love.graphics.printf("(Esc exits the game.)", 0, screenHeight - 20 * screenHeight / 400, screenWidth, "center")
end
function menu:mousepressed(x, y, button)
if input(button, controls.select) then
Gamestate.switch(game, difficulty, controls, session)
end
end
function menu:keypressed(key, unicode)
if input(key, controls.back) then
log("Quitting.")
if session then
Gamejolt.closeSession()
end
love.event.quit()
end
end
return menu

View File

@@ -0,0 +1,224 @@
local folder = (...):gsub('%.init$', '')
local md5 = require(folder .. ".md5" )
local http = require("socket.http")
local GJ = {
gameID, gameKey,
isLoggedIn = false,
username, userToken
}
local BASE_URL = "http://gamejolt.com/api/game/v1/"
local function req(s, f, pu, pt)
local url = BASE_URL .. s .. "&game_id=" .. tostring(GJ.gameID) .. "&format=" .. f
if pu then url = url .. "&username=" .. GJ.username end
if pt then url = url .. "&user_token=" .. GJ.userToken end
local b = md5.sumhexa(url .. GJ.gameKey)
url = url .. "&signature=" .. b
local r, e = http.request(url)
return r
end
local function parseKeypair(s, on)
local c, len = 0, string.len(s)
local b, k, v
while c < len do
b = string.find(s, ":", c)
if b == nil then break end
k = string.sub(s, c, b - 1)
c = b + 2
b = string.find(s, '"', c)
v = string.sub(s, c, b - 1)
c = b + 3
on(k, v)
end
end
local function handleTrophies(str)
local d = req("trophies/?" .. str, "keypair", true, true)
local t, f = {}
parseKeypair(d, function(k, v)
if k ~= "success" then
if k == "id" then
f = {}
table.insert(t, f)
end
f[k] = v
end
end)
return t
end
function GJ.init(id, key)
GJ.gameID = id
GJ.gameKey = key
end
-- users
function GJ.authUser(name, token)
GJ.username = name
GJ.userToken = token
local s = string.find(req("users/auth/?", "dump", true, true), "SUCCESS") ~= nil
GJ.isLoggedIn = s
return s
end
function GJ.fetchUserByName(name)
local r = req("users/?username=" .. name, "keypair", false, false)
local t = {}
parseKeypair(r, function(k, v)
t[k] = v
end)
return t
end
function GJ.fetchUserByID(id)
local r = req("users/?user_id=" .. id, "keypair", false, false)
local t = {}
parseKeypair(r, function(k, v)
t[k] = v
end)
return t
end
-- sessions
function GJ.openSession()
return string.find(req("sessions/open/?", "dump", true, true), "SUCCESS") ~= nil
end
function GJ.pingSession(active)
local status = "idle"
if active then status = "active" end
return string.find(req("sessions/open/?status=" .. status, "dump", true, true), "SUCCESS") ~= nil
end
function GJ.closeSession()
return string.find(req("sessions/close/?", "dump", true, true), "SUCCESS") ~= nil
end
-- data store
function GJ.fetchData(key, isGlobal)
local pu, pt = true, true
if isGlobal then pu, pt = false, false end
local d = req("data-store/?key=" .. key, "dump", pu, pt)
return string.sub(d, string.find(d, "\n"), string.len(d))
end
function GJ.setData(key, data, isGlobal)
local pu, pt = true, true
if isGlobal then pu, pt = false, false end
return string.find(req("data-store/set/?key=" .. key .. "&data=" .. tostring(data), "dump", pu, pt), "SUCCESS") ~= nil
end
function GJ.updateData(key, value, operation, isGlobal)
local pu, pt = true, true
if isGlobal then pu, pt = false, false end
local d = req("data-store/update/?key=" .. key .. "&operation=" .. operation .. "&value=" .. tostring(value), "dump", pu, pt)
return string.sub(d, string.find(d, "\n"), string.len(d))
end
function GJ.removeData(key, isGlobal)
local pu, pt = true, true
if isGlobal then pu, pt = false, false end
return string.find(req("data-store/remove/?key=" .. key, "dump", pu, pt), "SUCCESS") ~= nil
end
function GJ.fetchStorageKeys(isGlobal)
local pu, pt = true, true
if isGlobal then pu, pt = false, false end
local d = req("data-store/get-keys/?", "keypair", pu, pt)
local t = {}
parseKeypair(d, function(k, v)
if k ~= "success" then table.insert(t, v) end
end)
return t
end
-- trophies
function GJ.giveTrophy(id)
return string.find(req("trophies/add-achieved/?trophy_id=" .. tostring(id), "dump", true, true), "SUCCESS") ~= nil
end
function GJ.fetchTrophy(id)
local d = req("trophies/?trophy_id=" .. tostring(id), "keypair", true, true)
local t = {}
parseKeypair(d, function(k, v)
if k ~= "success" then t[k] = v end
end)
return t
end
function GJ.fetchTrophiesByStatus(achieved)
return handleTrophies("achieved=" .. tostring(achieved))
end
function GJ.fetchAllTrophies()
return handleTrophies("")
end
-- scores
function GJ.addScore(score, desc, tableID, guestName, extraData)
local pu, pt, s = true, true, ""
if guestName then pu, pt = false, false, s .. "&guest=" .. guestName end
if extraData then s = s .. "&extra_data=" .. tostring(extraData) end
if tableID then s = s .. "&table_id=" .. tostring(tableID) end
return string.find(req("scores/add/?score=" .. tostring(desc) .. "&sort=" .. score .. s, "dump", pu, pt), "SUCCESS") ~= nil
end
function GJ.fetchScores(limit, tableID)
local pu, pt, s = true, true, ""
if tableID then pu, pt, s = false, false, "&table_id=" .. tostring(tableID) end
local d = req("scores/?limit=" .. tostring(limit) .. s, "keypair", pu, pt)
local t, f = {}
parseKeypair(d, function(k, v)
if k ~= "success" then
if k == "score" then
f = {}
table.insert(t, f)
end
f[k] = v
end
end)
return t
end
function GJ.fetchTables()
local d = req("scores/tables/?", "keypair", false, false)
local t, f = {}
parseKeypair(d, function(k, v)
if k ~= "success" then
if k == "id" then
f = {}
table.insert(t, f)
end
f[k] = v
end
end)
return t
end
return GJ

View File

@@ -0,0 +1,384 @@
local md5 = {
_VERSION = "md5.lua 0.5.0",
_DESCRIPTION = "MD5 computation in Lua (5.1)",
_URL = "https://github.com/kikito/md5.lua",
_LICENSE = [[
MIT LICENSE
Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
}
-- bit lib implementions
local floor, abs, max = math.floor, math.abs, math.max
local char, byte, format, rep, sub =
string.char, string.byte, string.format, string.rep, string.sub
local function check_int(n)
-- checking not float
if(n - floor(n) > 0) then
error("trying to use bitwise operation on non-integer!")
end
end
local function tbl2number(tbl)
local n = #tbl
local rslt = 0
local power = 1
for i = 1, n do
rslt = rslt + tbl[i]*power
power = power*2
end
return rslt
end
local function expand(tbl_m, tbl_n)
local big = {}
local small = {}
if(#tbl_m > #tbl_n) then
big = tbl_m
small = tbl_n
else
big = tbl_n
small = tbl_m
end
-- expand small
for i = #small + 1, #big do
small[i] = 0
end
end
local to_bits -- needs to be declared before bit_not
local function bit_not(n)
local tbl = to_bits(n)
local size = max(#tbl, 32)
for i = 1, size do
if(tbl[i] == 1) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
-- defined as local above
to_bits = function (n)
check_int(n)
if(n < 0) then
-- negative
return to_bits(bit_not(abs(n)) + 1)
end
-- to bits table
local tbl = {}
local cnt = 1
while (n > 0) do
local last = math.mod(n,2)
if(last == 1) then
tbl[cnt] = 1
else
tbl[cnt] = 0
end
n = (n-last)/2
cnt = cnt + 1
end
return tbl
end
local function bit_or(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = max(#tbl_m, #tbl_n)
for i = 1, rslt do
if(tbl_m[i]== 0 and tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
local function bit_and(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = max(#tbl_m, #tbl_n)
for i = 1, rslt do
if(tbl_m[i]== 0 or tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
local function bit_xor(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
local rslt = max(#tbl_m, #tbl_n)
for i = 1, rslt do
if(tbl_m[i] ~= tbl_n[i]) then
tbl[i] = 1
else
tbl[i] = 0
end
end
return tbl2number(tbl)
end
local function bit_rshift(n, bits)
check_int(n)
local high_bit = 0
if(n < 0) then
-- negative
n = bit_not(abs(n)) + 1
high_bit = 2147483648 -- 0x80000000
end
for i=1, bits do
n = n/2
n = bit_or(floor(n), high_bit)
end
return floor(n)
end
local function bit_lshift(n, bits)
check_int(n)
if(n < 0) then
-- negative
n = bit_not(abs(n)) + 1
end
for i=1, bits do
n = n*2
end
return bit_and(n, 4294967295) -- 0xFFFFFFFF
end
-- convert little-endian 32-bit int to a 4-char string
local function lei2str(i)
local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
return f(0)..f(8)..f(16)..f(24)
end
-- convert raw string to big-endian int
local function str2bei(s)
local v=0
for i=1, #s do
v = v * 256 + byte(s, i)
end
return v
end
-- convert raw string to little-endian int
local function str2lei(s)
local v=0
for i = #s,1,-1 do
v = v*256 + byte(s, i)
end
return v
end
-- cut up a string in little-endian ints of given size
local function cut_le_str(s,...)
local o, r = 1, {}
local args = {...}
for i=1, #args do
table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
o = o + args[i]
end
return r
end
local swap = function (w) return str2bei(lei2str(w)) end
local function hex2binaryaux(hexval)
return char(tonumber(hexval, 16))
end
local function hex2binary(hex)
local result, _ = hex:gsub('..', hex2binaryaux)
return result
end
-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
-- 10/02/2001 jcw@equi4.com
local FF = 0xffffffff
local CONSTS = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
}
local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
local z=function (f,a,b,c,d,x,s,ac)
a=bit_and(a+f(b,c,d)+x+ac,FF)
-- be *very* careful that left shift does not cause rounding!
return bit_or(bit_lshift(bit_and(a,bit_rshift(FF,s)),s),bit_rshift(a,32-s))+b
end
local function transform(A,B,C,D,X)
local a,b,c,d=A,B,C,D
local t=CONSTS
a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
d=z(f,d,a,b,c,X[ 1],12,t[ 2])
c=z(f,c,d,a,b,X[ 2],17,t[ 3])
b=z(f,b,c,d,a,X[ 3],22,t[ 4])
a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
d=z(f,d,a,b,c,X[ 5],12,t[ 6])
c=z(f,c,d,a,b,X[ 6],17,t[ 7])
b=z(f,b,c,d,a,X[ 7],22,t[ 8])
a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
d=z(f,d,a,b,c,X[ 9],12,t[10])
c=z(f,c,d,a,b,X[10],17,t[11])
b=z(f,b,c,d,a,X[11],22,t[12])
a=z(f,a,b,c,d,X[12], 7,t[13])
d=z(f,d,a,b,c,X[13],12,t[14])
c=z(f,c,d,a,b,X[14],17,t[15])
b=z(f,b,c,d,a,X[15],22,t[16])
a=z(g,a,b,c,d,X[ 1], 5,t[17])
d=z(g,d,a,b,c,X[ 6], 9,t[18])
c=z(g,c,d,a,b,X[11],14,t[19])
b=z(g,b,c,d,a,X[ 0],20,t[20])
a=z(g,a,b,c,d,X[ 5], 5,t[21])
d=z(g,d,a,b,c,X[10], 9,t[22])
c=z(g,c,d,a,b,X[15],14,t[23])
b=z(g,b,c,d,a,X[ 4],20,t[24])
a=z(g,a,b,c,d,X[ 9], 5,t[25])
d=z(g,d,a,b,c,X[14], 9,t[26])
c=z(g,c,d,a,b,X[ 3],14,t[27])
b=z(g,b,c,d,a,X[ 8],20,t[28])
a=z(g,a,b,c,d,X[13], 5,t[29])
d=z(g,d,a,b,c,X[ 2], 9,t[30])
c=z(g,c,d,a,b,X[ 7],14,t[31])
b=z(g,b,c,d,a,X[12],20,t[32])
a=z(h,a,b,c,d,X[ 5], 4,t[33])
d=z(h,d,a,b,c,X[ 8],11,t[34])
c=z(h,c,d,a,b,X[11],16,t[35])
b=z(h,b,c,d,a,X[14],23,t[36])
a=z(h,a,b,c,d,X[ 1], 4,t[37])
d=z(h,d,a,b,c,X[ 4],11,t[38])
c=z(h,c,d,a,b,X[ 7],16,t[39])
b=z(h,b,c,d,a,X[10],23,t[40])
a=z(h,a,b,c,d,X[13], 4,t[41])
d=z(h,d,a,b,c,X[ 0],11,t[42])
c=z(h,c,d,a,b,X[ 3],16,t[43])
b=z(h,b,c,d,a,X[ 6],23,t[44])
a=z(h,a,b,c,d,X[ 9], 4,t[45])
d=z(h,d,a,b,c,X[12],11,t[46])
c=z(h,c,d,a,b,X[15],16,t[47])
b=z(h,b,c,d,a,X[ 2],23,t[48])
a=z(i,a,b,c,d,X[ 0], 6,t[49])
d=z(i,d,a,b,c,X[ 7],10,t[50])
c=z(i,c,d,a,b,X[14],15,t[51])
b=z(i,b,c,d,a,X[ 5],21,t[52])
a=z(i,a,b,c,d,X[12], 6,t[53])
d=z(i,d,a,b,c,X[ 3],10,t[54])
c=z(i,c,d,a,b,X[10],15,t[55])
b=z(i,b,c,d,a,X[ 1],21,t[56])
a=z(i,a,b,c,d,X[ 8], 6,t[57])
d=z(i,d,a,b,c,X[15],10,t[58])
c=z(i,c,d,a,b,X[ 6],15,t[59])
b=z(i,b,c,d,a,X[13],21,t[60])
a=z(i,a,b,c,d,X[ 4], 6,t[61])
d=z(i,d,a,b,c,X[11],10,t[62])
c=z(i,c,d,a,b,X[ 2],15,t[63])
b=z(i,b,c,d,a,X[ 9],21,t[64])
return A+a,B+b,C+c,D+d
end
----------------------------------------------------------------
function md5.sumhexa(s)
local msgLen = #s
local padLen = 56 - msgLen % 64
if msgLen % 64 > 56 then padLen = padLen + 64 end
if padLen == 0 then padLen = 64 end
s = s .. char(128) .. rep(char(0),padLen-1) .. lei2str(8*msgLen) .. lei2str(0)
assert(#s % 64 == 0)
local t = CONSTS
local a,b,c,d = t[65],t[66],t[67],t[68]
for i=1,#s,64 do
local X = cut_le_str(sub(s,i,i+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
assert(#X == 16)
X[0] = table.remove(X,1) -- zero based!
a,b,c,d = transform(a,b,c,d,X)
end
return format("%08x%08x%08x%08x",swap(a),swap(b),swap(c),swap(d))
end
function md5.sum(s)
return hex2binary(md5.sumhexa(s))
end
return md5

View File

@@ -5,15 +5,16 @@ debug = require "conf" -- a bit redundant but makes it obvious what is global
local startDate = os.date("*t", os.time()) local startDate = os.date("*t", os.time())
local logFile = "logs/" .. startDate.year .. "." .. startDate.month .. "." .. startDate.day .. "-" .. startDate.hour .. "." .. startDate.min .. ".log" local logFile = "logs/" .. startDate.year .. "." .. startDate.month .. "." .. startDate.day .. "-" .. startDate.hour .. "." .. startDate.min .. ".log"
function log(...) function log(...)
--[[ ---[[
local strings = "" local strings = ""
if type(arg) == "table" then if type(arg) == "table" then
for _,v in pairs(arg) do for _,v in ipairs(arg) do
strings = strings .. v strings = strings .. v
end end
else else
strings = arg strings = arg
end end
-- make sure logs exists
if love.filesystem.exists("logs") then if love.filesystem.exists("logs") then
if not love.filesystem.isDirectory("logs") then if not love.filesystem.isDirectory("logs") then
love.filesystem.remove() love.filesystem.remove()
@@ -22,6 +23,7 @@ end
else else
love.filesystem.createDirectory("logs") love.filesystem.createDirectory("logs")
end end
-- append new data to logFile
local success, errorMsg = love.filesystem.append(logFile, strings) local success, errorMsg = love.filesystem.append(logFile, strings)
if not success then if not success then
print("Failed to write to log file.", errorMsg) print("Failed to write to log file.", errorMsg)
@@ -36,14 +38,12 @@ local menu = require "gamestates.menu"
function love.load() function love.load()
log("Loading...") log("Loading...")
-- set custom window icon love.window.setIcon(love.image.newImageData("icon.png"))
local icon = love.image.newImageData("icon.png")
love.window.setIcon(icon)
log("Window icon set.") log("Window icon set.")
-- initialize Game Jolt -- initialize Game Jolt
local initSuccess = GameJolt.init(48728, "b8e4a0eae1509d3edef3d8451bae1842") GameJolt.init(48728, "b8e4a0eae1509d3edef3d8451bae1842")
if initSuccess then log("Game Jolt initialized.") end log("Game Jolt initialized.")
-- load settings and change if needed -- load settings and change if needed
local gamejoltSessionOpen = false --set true if we get a session open local gamejoltSessionOpen = false --set true if we get a session open
@@ -65,12 +65,12 @@ function love.load()
inifile.save("settings.ini", settings) inifile.save("settings.ini", settings)
error("You have been banned from Game Jolt. Your login data has been deleted, re-open RGB to continue playing without Game Jolt account integration.") error("You have been banned from Game Jolt. Your login data has been deleted, re-open RGB to continue playing without Game Jolt account integration.")
end end
gamejoltSessionOpen = GameJolt.openSession() -- tell Game Jolt the user is playing if GameJolt.openSession() then -- tell Game Jolt the user is playing
if sessionSuccess then
-- we don't ping immediately, also the menu DOES ping immediately -- we don't ping immediately, also the menu DOES ping immediately
gamejoltSessionOpen = true gamejoltSessionOpen = true
log("Game Jolt session opened.") log("Game Jolt session opened.")
else else
gamejoltSessionOpen = false
-- TODO make this known to user -- TODO make this known to user
log("Couldn't open a session with Game Jolt.") log("Couldn't open a session with Game Jolt.")
end end