corona sdks - Why ain't my database updating count? - lua

I seem to be having an issue with my database in corona sdk. I want to store the play counts every time a player plays the game. my project doesn't have a gamescene and plays only through menu.lua. I have set up a highscore database (which is separate from the other one but exactly the same) and it works fine and updates/loads data fine. My play count data base however doesn't work.
At first the play count increases by 1 when the game returns to menu again once its removed. But tries after that doesn't increase the value, it's like it has reset.
Globals.lua
M.plays = 0
--------------------------
local function setupDatabase2()
local dbPath = system.pathForFile("appInfo.db3", system.DocumentsDirectory)
local db = sqlite3.open( dbPath )
local tablesetup1 = [[
CREATE TABLE played (id INTEGER PRIMARY KEY, plays);
INSERT INTO played VALUES (NULL, '0');
]]
db:exec( tablesetup1 ) --Create it now.
db:close() --Then close the database
end
setupDatabase2()
M.loadAppInfo = function()
local dbPath = system.pathForFile("appInfo.db3", system.DocumentsDirectory)
local db = sqlite3.open(dbPath)
for row in db:nrows("SELECT * FROM played WHERE id = 1") do
M.plays = tonumber(row.plays)
end
db:close()
end
M.saveAppInfo = function()
local dbPath = system.pathForFile("appInfo.db3", system.DocumentsDirectory)
local db = sqlite3.open(dbPath)
local update = "UPDATE played SET plays='" .. M.plays .."' WHERE id=1"
db:exec(update)
db:close()
end
return M
menu.lua
local utils = require("helpers.globals")
local play = 0
----------------------------------------
function scene:createScene( event )
local group = self.view
utils.loadHighscoreInfo() -- Separate db which is working fine
utils.loadAppInfo()
function beginGame( event )
timerSrc = timer.performWithDelay(400, createBlock, -1)
Runtime:addEventListener("enterFrame", gameLoop)
play = play +1
utils.plays = play
utils.saveAppInfo()
end

Your SQL statement is doing all of that. Your current sql creates a table everytime it is called. Try this:
local tablesetup1 = [[
CREATE TABLE IF NOT EXISTS played (id INTEGER PRIMARY KEY, plays);
INSERT INTO played VALUES (NULL, '0');]]
I guess that statement is pretty much self explanatory :)

Related

Can't get to a value inside a player in lua

Code I Tried
game.Workspace.burgerclick.OnServerEvent:Connect(function()
local playername = game.Workspace.ClickPlayer.Value
local player = game.Players:FindFirstChild(playername)
local playaname = player.Name
local fpval = game.Players[playaname].FP.Value
fpval = fpval + 1
end)
I am making a game and I wanted to have a button that updates the value of something called FP, in the workspace I have a stringvalue called ClickPLayer which updates to the player clicking the button. that works. I made a variable that is the value the stringvalue, but when I put the variable inside the line when I update the FP Value it says the variable is not a valid member of players. I'm not sure what to do.
I think the correct code should be something like:
game.Players[playaname].FP.Value = game.Players[playaname].FP.Value + 1
Because, when you do:
local fpval = game.Players[playaname].FP.Value
fpval = fpval + 1
You are copying the value of game.Players[playaname].FP.Valueto fpval and incrementing the copy (fpval = fpval + 1), not the value held by game.Players[playaname].FP.
The most correct and efficient code would be
local Players = game:GetService("Players")
local fpval
local plr
workspace.burgerclick.Activated:Connect(function()
plr = workspace.ClickPlayer.Value
fpval = Players[plr].FP
fpval.Value = fpval.Value + 1
end)
In the documentation of TextButtons and ImageButtons, there is an Activated event that can be used for this, instead of firing a server from a LocalScript which is what your script aims to do now. However, if the button is in the PlayerGui and you have an activation LocalScript for it, you probably want to use this code instead:
local fpval
workspace.burgerclick.OnServerEvent:Connect(function(plr)
fpval = plr.FP
fpval.Value = fpval.Value + 1
end)

How can I skip back a few seconds after pause in VLC Media Player?

I've searched this on the internet, but can't seem to find anything. I know there are hotkeys to skip back a few seconds, and I know there are hotkeys to to pause and play audio/video in VLC Media Player. However, I am using a single foot pedal for transcription and essentially need it to do both. I would like the pedal tap to pause the audio. Then, after tapping again, I would like it to play the audio, but skipping a few seconds back when doing so. Is this possible?
Save this code as rollback.lua and place it in Program Files\VideoLAN\VLC\lua\extensions folder. Then activate it through View > Rollback X Seconds.
function descriptor()
return {
title = "Rollback X Seconds",
capabilities = {"input-listener", "playing-listener"}
}
end
function activate()
end
function close()
end
function deactivate()
end
function input_changed()
end
function playing_changed()
local TIME_DELTA = -3
if vlc.playlist.status()=="paused" then
local timePassed = vlc.var.get(vlc.object.input(), "time")
local newTime = timePassed + TIME_DELTA
vlc.osd.message(TIME_DELTA, vlc.osd.channel_register(), "top-left", 1400000)
vlc.var.set(vlc.object.input(), "time", newTime)
end
end
Change the variable TIME_DELTA to whatever time change you want on pause
I expanded on the code provided by Tee by adding a GUI.
I would also like to add a few details of how to get it working.
Create a empty file, name it rollback.lua.
Copy the code provided underneath this list, paste into the file and save.
Move the file to VLCs folder for lua extensions, it should look something like this:
c:/Program Files/VideoLAN/VLC/lua/extensions
Restart VLC player.
Activate the script by going to (Note! Needs to be done each time you start VLC to use the plugin)
view > Rollback X Seconds
Select time in seconds you want to rollback and hit save (or save and close).
In order to get your pedal working with this script, simply configure the hotkey in VLC for play/pause toggle.
VLC > Tools > Preferences > Hotkeys > Set "Play/Pause" Global value to be your pedal.
(After you change a Global hotkey, you need to restart VLC in order to get it working...)
The code:
micro_second_unit = 1000000
TIME_DELTA = 1 --Default,
SHOW_OUTPUT = true
TIME_TO_DISPLAY = 1.5 --Default
function descriptor()
return {
title = "Rollback X Seconds",
capabilities = {"input-listener", "playing-listener"}
}
end
function activate()
dlg = vlc.dialog("Rollback X Seconds")
rollback_input = dlg:add_text_input("1", 2, 1 )
rollback_input_label = dlg:add_label("Seconds to back", 1, 1)
checkBox = dlg:add_check_box("Show output time ", wasChecked, 3, 3 )
timeTo_display_box = dlg:add_text_input(1.5, 2 ,3)
timeTo_display_box_label = dlg:add_label("Seconds To Display", 1, 3)
w2 = dlg:add_button("Save settings", change_step, 3, 4, 1, 1)
w2 = dlg:add_button("Save and close", updateAndClose, 3, 5, 1, 1)
done = dlg:add_label( "" , 3, 6)
end
function close()
end
function deactivate()
vlc.deactivate()
end
function input_changed()
end
function playing_changed()
if vlc.playlist.status()=="paused" then
local timePassed = tonumber(vlc.var.get(vlc.object.input(), "time"))
local newTime = timePassed - seconds_to_microsecond(TIME_DELTA)
local newTime_inSeconds = (newTime/1000000)
local newTime_inMinutes = (newTime_inSeconds/60)
local newTime_inSeconds_restOfMin = math.fmod(newTime_inSeconds,60)
local newTime_str = math.floor(newTime_inMinutes) .. "min " .. round(newTime_inSeconds_restOfMin,1) .."sec"
local timePassed_inSeconds = (timePassed/1000000)
local timePassed_inMinutes = (timePassed_inSeconds/60)
local timePassed_inSeconds_restOfMin = math.fmod(timePassed_inSeconds,60)
local timePassed_str = math.floor(timePassed_inMinutes) .. "min " .. round(timePassed_inSeconds_restOfMin,1) .."sec"
if SHOW_OUTPUT == true then
vlc.osd.message("Seconds to Back:" .. TIME_DELTA .. "sec", vlc.osd.channel_register(), "top-right", seconds_to_microsecond(TIME_TO_DISPLAY))
vlc.osd.message("New time:" .. newTime_str, vlc.osd.channel_register(), "top-left", seconds_to_microsecond(TIME_TO_DISPLAY))
vlc.osd.message("Old time:" .. timePassed_str, vlc.osd.channel_register(), "bottom-left", seconds_to_microsecond(TIME_TO_DISPLAY))
end
vlc.var.set(vlc.object.input(), "time", newTime)
end
end
function updateAndClose()
change_step()
dlg:delete()
end
function change_step()
done:set_text("Saved")
TIME_DELTA = tonumber(rollback_input:get_text())
SHOW_OUTPUT = checkBox:get_checked()
if SHOW_OUTPUT == true then
TIME_TO_DISPLAY = tonumber(timeTo_display_box:get_text())
end
end
function round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end
function microsecond_to_seconds(timeToConvert)
return timeToConvert / micro_second_unit;
end
function seconds_to_microsecond(timeToConvert)
return timeToConvert * micro_second_unit;
end
This will work just like Tee's script, the video will jump back each time it's paused.
Only difference is that you can set the amount of time to jump back each time you start the script.
The amount is given in seconds, however you can use decimals for more control...
There's also a checkbox you can tick if you want to display information about the jump.
I also want to thank Tee for his answer!
This is the first lua code I've written (or rather, modified) and it's a bit messy, but it works and I have used it every day since so I thought I might as well share it.

Saving Player Data in RLua

Is there a reason why these do not work?
Player joining script:
local DataStore = game:GetService("DataStoreService"):GetDataStore("GeneralStats")
game.Players.PlayerAdded:connect(function(player)
local stats = Instance.new("IntValue", player)
stats.Name = "leaderstats"
local points = Instance.new("IntValue", stats)
points.Name = "Points"
local credits = Instance.new("IntValue", stats)
credits.Name = "Credits"
local key = "player-"..player.userId
local savedValues = DataStore:GetAsync(key)
if savedValues then
--Save format: (points, credits)
points.Value = savedValues[1]
credits.Value = savedValues[2]
else
local ValuesToSave = {points.Value, credits.Value}
DataStore:SetAsync(key, ValuesToSave)
end
end)
And this other script for when the player leaves.
local DataStore = game:GetService("DataStoreService"):GetDataStore("GeneralStats")
game.Players.PlayerRemoving:connect(function(player)
local key = "player-"..player.userId
--Save key: {points, credits}
local valuesToSave = {player.leaderstats.Points.Values, player.leaderstats.Credits.Values}
DataStore:SetAsync(key, valuesToSave)
end)
This is for a game I am working on, justify (RLua is Roblox Lua, if you didn't know).
Yes, more than likely the leaderstat is being removed before you have a chance to extract data.
I would suggest not using leaderstats as reference for data. It's better to store data on the script directly.
However, if you truly must use leaderstats, parent it to somewhere else, extract data, then remove it.
local lead = player.leaderstats
lead.Parent = game
-- extract data
lead:Destroy()
Or you could define all those objects in a variable before they get reparented.
But again, I highly suggest not to use leaderstats for data saving. Exploiters can change that data easily and change the value to a high number.

How to use Lua field extractor in Wireshark?

I have a protocol like this
"Packet" - A sequence of messages
{Head}{Content}{Head}{Content}...
"Head" - 1 byte
bit 1-7 : msg length
bit 8 : true msg or not
It is a udp communication, I have to use that bit 8 to determine if I need to skip the message.
Following is my toy parser, the Problem I am facing is how to extract the bool value helping me to make the decision.
TOY_proto = Proto("TOY", "TOY Protocol")
local isSkip = ProtoField.new("Is Skip?", "mytoy.isSkip", ftypes.BOOLEAN, {"Yes", "No"}, 8, 0x01)
local msgLen = ProroField.new("Message Length", "mytoy.msgLen", ftypes.UINT8, nil, base.DEC, 0xFE)
TOY_proto.fields = {isSkip, msgLen}
local isSkip_Field = Field.new("mytoy.isSkip")
local function getIsSkip()
return isSkip_Field()()
end
local msgLen_Field = Field.new("mytoy.msgLen")
local function getMsgLen()
return msgLen_Field()()
end
function TOY_proto.dissector(tvbuf, pktinfo, root)
pktinfo.cols.protocol = "TOY"
local pktlen = tvbuf:reported_length_remaining()
local pos = 0
while pos < pktlen do
local headTree = tree:add("Head")
headTree:add_le(isSkip, tvbuf:range(pos,1))
headTree:add_le(msgLen, tvbuf:range(pos,1))
if getIsSkip() then
pos = pos + getMsgLen()
else
-- do something else
end
end
end
udp_table = DissectorTable.get("udp.port")
udp_table:add(6628, TOY_proto)
The Problem is that in the first loop, every variable is doing right, but after the first loop, the value returned from getIsSkip() and getMsgLen() are always unchanged.
When you do this:
return isSkip_Field()()
What you're really doing is logically equivalent to this:
-- extract the FieldInfo object using the Field object "isSkip_Field"
local tempFieldInfo = isSkip_Field()
-- get the Lua boolean value of the FieldInfo object
local tempValue = tempFieldInfo()
-- return it
return tempValue
I mention the above to explain why you're getting what you're getting later in this answer...
When you invoke a field extractor (i.e., you call a Field object to get a FieldInfo object), you actually get back every FieldInfo object of that Field's type that exists in that packet at the time the extractor is invoked. Your packet contains multiple "messages" of your protocol, so in each loop you get back the previous loops' FieldInfo objects as well as the current one, for the same packet.
In other words, when your script executed this:
return isSkip_Field()()
...the first time for a packet, it got back one FieldInfo object, called that, and got the boolean. When it ran the second time, the call to isSkip_Field() actually returned two FieldInfo objects, but it discarded the second one because the code is logically equivalent to the code I wrote at the top of this answer, and instead only called the first instance, which of course rteturns the same boolean value as the first loop iteration; and when it ran a third time for the same packet it returned three FieldInfo objects, discarded the second two, called the first one, etc.
So what you really want to do is select the correct FieldInfo object each loop iteration - namely the most recent (last) one. You can do that one of two ways: (1) using the Lua select() function, or (2) put the returned FieldInfo objects into a table and retrieve the last entry.
For example, do this:
local isSkip_Field = Field.new("mytoy.isSkip")
local function getIsSkip(num)
return select(num, isSkip_Field())()
end
local msgLen_Field = Field.new("mytoy.msgLen")
local function getMsgLen(num)
return select(num, msgLen_Field())()
end
function TOY_proto.dissector(tvbuf, pktinfo, root)
pktinfo.cols.protocol = "TOY"
local pktlen = tvbuf:reported_length_remaining()
local pos = 0
local num = 1
while pos < pktlen do
local headTree = tree:add("Head")
headTree:add_le(isSkip, tvbuf:range(pos,1))
headTree:add_le(msgLen, tvbuf:range(pos,1))
if getIsSkip(num) then
pos = pos + getMsgLen(num)
else
-- do something else
end
num = num + 1
end
end
...or this:
local isSkip_Field = Field.new("mytoy.isSkip")
local function getIsSkip()
local tbl = { isSkip_Field() }
return tbl[#tbl]()
end
local msgLen_Field = Field.new("mytoy.msgLen")
local function getMsgLen()
local tbl = { msgLen_Field() }
return tbl[#tbl]()
end
function TOY_proto.dissector(tvbuf, pktinfo, root)
pktinfo.cols.protocol = "TOY"
local pktlen = tvbuf:reported_length_remaining()
local pos = 0
while pos < pktlen do
local headTree = tree:add("Head")
headTree:add_le(isSkip, tvbuf:range(pos,1))
headTree:add_le(msgLen, tvbuf:range(pos,1))
if getIsSkip() then
pos = pos + getMsgLen()
else
-- do something else
end
end
end
...or if there are going to be lots of Fields, this might be nicer:
local isSkip_Field = Field.new("mytoy.isSkip")
local msgLen_Field = Field.new("mytoy.msgLen")
local function getFieldValue(field)
local tbl = { field() }
return tbl[#tbl]()
end
function TOY_proto.dissector(tvbuf, pktinfo, root)
pktinfo.cols.protocol = "TOY"
local pktlen = tvbuf:reported_length_remaining()
local pos = 0
while pos < pktlen do
local headTree = tree:add("Head")
headTree:add_le(isSkip, tvbuf:range(pos,1))
headTree:add_le(msgLen, tvbuf:range(pos,1))
if getFieldValue(isSkip_Field) then
pos = pos + getFieldValue(msgLen_Field)
else
-- do something else
end
end
end

Update parse column

I'm new to parse and I have a problem with the score column on my parse.com table called User.
Here is have my login function and after the users log in successfully, I have this function that is supposed to update the score while the user plays.
local parse = require( "mod_parse" )
local ego = require "ego"
local saveFile = ego.saveFile
local loadFile = ego.loadFile
--------------------------------------------------------------------
--------------------------------------------------------------------
_G.score = 1
_G.highscore = loadFile ("highscores.txt")
local function checkForFile ()
if highscore == "empty" then
highscore = 0
saveFile("highscores.txt", highscore)
end
end
checkForFile()
--Print the current highscore
print ("Highscore is", highscore)
-----------------------------------------------
dataTable = { ["score"] = tonumber(highscore) }
function onSystemEvent (event)
if _G.score > tonumber(_G.highscore) then --We use tonumber as highscore is a string when loaded
saveFile("highscores.txt", _G.score)
parse:updateObject( "objectId", dataTable, onSystemEvent )
end
end
_G.timer1=timer.performWithDelay(100, addToScore, 0)
The functions compare the score with the highscore and if score is higher than the highscore updates highscore with the new value.
I'm having trouble with the parse:updateObject function. I have a column called score on parse that I'm trying to update with the new highscore. What am I doing wrong?
You're trying to save the object by calling the updateObject method, which I think requires you to know the objectID of the object you wish to save. I'm guessing that you tried to use "objectId", but that is certainly not the correct objectID. Farther than this, I can not help you as I do not know LUA.
I'm guessing you need some sort of ParseObject that you can save a new row. I recommend that you take a look at the Parse SDKs, they explain it very well.

Resources