Jump to content

[HELP] How can i remove a data from my table?


Turbesz

Recommended Posts

  • Moderators
Posted (edited)
5 minutes ago, Turbesz said:

uh that's true, my bad!

now i don't get any errors or warnings, and the file was created, but does not insert the script any data to that file, i just get only "<root></root>" as a result in my .xml file

You also have to apply my feedback from before that:

 

9 hours ago, IIYAMA said:

That is why I gave you a function for reformatting:




xml:xmlSaveData("save", reformatToArray(menteshez), false, true) 

 

(don't forget to modify the key)

 

And after that it is variable debugging time.

 

----

+

And you might also need to encode the account name, so that all special characters are escaped:

https://wiki.multitheftauto.com/wiki/Base64Encode

 

Edited by IIYAMA
Posted
7 minutes ago, IIYAMA said:

You also have to apply my feedback from before that:

 

(don't forget to modify the key)

 

And after that it is variable debugging time.

 

----

+

And you might also need to encode the account name, so that all special characters are escaped:

https://wiki.multitheftauto.com/wiki/Base64Encode

 

i tried to modify 'menteshez' to 'reformatToArray(menteshez)' but then i get this error: bad argument #1 to 'pairs' (table expected got nil)

the error refers to this loop in 'reformatToArray' func:  

	for k, data in pairs(theTable) do
		table.insert(array, data)
	end

 

  • Moderators
Posted
1 minute ago, Turbesz said:

the error refers to this loop in 'reformatToArray' func:  

The input has to be a table:

reformatToArray(menteshez)

 

Not something else.

 

 

Posted
1 minute ago, IIYAMA said:

The input has to be a table:

reformatToArray(menteshez)

 

Not something else.

 

 

 

that's how I added:

xml:xmlSaveData("save" .. accountName, reformatToArray(menteshez), false, true)

but i get the error :/ 

  • Moderators
Posted
1 minute ago, Turbesz said:

but i get the error :/ 

Are you 100000% sure that `menteshez`contains a table?

Posted
11 minutes ago, IIYAMA said:

Are you 100000% sure that `menteshez`contains a table?

Um, yes(?)

This is my current code of save func: 

local menteshez = {}
local xml = exports.xmldata

function teszt(thePlayer)
    local object=getElementsByType("object")
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    
    local menteshez = xml:xmlLoadData("save" .. accname, true)
    if not menteshez then
        xml:xmlSaveData("save" .. accname, {}, false, true)  
        return
    end

    for k, v in ipairs(object) do
        if getElementData(v,"owner") == accname then
            local x,y,z = getElementPosition(v)
            local id = getElementModel(v)
            local owner = getElementData(v,"owner") or getAccountName(theAcc)
            local int = getElementInterior(v)
            local dim = getElementDimension(v)
            local Rx,Ry,Rz = getElementRotation ( v )
            outputChatBox("mentve")
            menteshez[v] = {x,y,z,id,owner,int,dim,Rx,Ry,Rz}
            setCustomData(thePlayer, "menteshez", menteshez, true)
        end
    end
    local menteshez = getCustomData(thePlayer, "menteshez", true) 

    local account = getPlayerAccount(thePlayer)
    local accountName = getAccountName(account)
    
    xml:xmlSaveData("save" .. accountName, reformatToArray(menteshez), false, true)

end

addCommandHandler("save",teszt)

 

  • Moderators
Posted
1 minute ago, Turbesz said:

Um, yes(?)

Nope it did not.

 

Let me simplify it a bit, remove all tools that you are currently not using, since we get no-were otherwise.

 

local xml = exports.xmldata

function teszt(thePlayer)
    local object=getElementsByType("object")
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    local menteshez = {} -- reset and fill up again

    for k, v in ipairs(object) do
        if getElementData(v,"owner") == accname then
            local x,y,z = getElementPosition(v)
            local id = getElementModel(v)
            local owner = getElementData(v,"owner") or accname
            local int = getElementInterior(v)
            local dim = getElementDimension(v)
            local Rx,Ry,Rz = getElementRotation ( v )

            menteshez[#menteshez + 1] = {x,y,z,id,owner,int,dim,Rx,Ry,Rz}
            
        end
    end
    
    xml:xmlSaveData("save" .. base64Encode(accname), menteshez, false, true)

end

addCommandHandler("save",teszt)

 

 

 

 

Posted
10 hours ago, IIYAMA said:

Nope it did not.

 

Let me simplify it a bit, remove all tools that you are currently not using, since we get no-were otherwise.

 


local xml = exports.xmldata

function teszt(thePlayer)
    local object=getElementsByType("object")
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    local menteshez = {} -- reset and fill up again

    for k, v in ipairs(object) do
        if getElementData(v,"owner") == accname then
            local x,y,z = getElementPosition(v)
            local id = getElementModel(v)
            local owner = getElementData(v,"owner") or accname
            local int = getElementInterior(v)
            local dim = getElementDimension(v)
            local Rx,Ry,Rz = getElementRotation ( v )

            menteshez[#menteshez + 1] = {x,y,z,id,owner,int,dim,Rx,Ry,Rz}
            
        end
    end
    
    xml:xmlSaveData("save" .. base64Encode(accname), menteshez, false, true)

end

addCommandHandler("save",teszt)

 

 

 

 

Thank you, save and load working fine now :D 

Btw, can't that cause some issues that it's saving the XML file on the server and not on the players PC? Because over time it can be up to more than 1000, or 2000 XML file (if we look at that my server has ~4000 registered account, and every player can register only one)

  • Moderators
Posted (edited)
1 hour ago, Turbesz said:

Btw, can't that cause some issues that it's saving the XML file on the server and not on the players PC? Because over time it can be up to more than 1000, or 2000 XML file (if we look at that my server has ~4000 registered account, and every player can register only one)

That can become an issue, here is a list that current method is lacking:

- Not able to use a-sync + queueing

- Not able to saving/loading data by using a different thread.

- XML uses more filespace

- There is no cleaner for older account data / There is no archive system that moves account data that isn't used for a while to a separated environment.

 

You can also decide to backup the data on to the clients their pc's. That way you can freely clean data on the server when accounts aren't used for more than a year.

The client has a copy of the data and can upload it back to the server when the server has deleted it. (but more sure that it can't be abused, by encrypting the file)

 

Clientside only datastorage would be a better a better solution to be honest, but then again if the client crashes... auto save might be recommended.

 

 

 

 

 

 

Edited by IIYAMA
Posted
7 minutes ago, IIYAMA said:

You can also decide to backup the data on to the clients their pc's.

How can this be done? 

Or how can i easily move the save and load funcs to client side?

  • Moderators
Posted
2 minutes ago, Turbesz said:

Or how can i easily move the save and load funcs to client side?

There is no `easy` in doing that.

 

For the example code, I will be using my library, so that I do not have to write so much code. Feel free to replace them with trigger events.

Note: I did not test this, but it will at least give you an idea how it could be done.

 

Server

local xml = exports.xmldata

function teszt(thePlayer)
    local object=getElementsByType("object")
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    local menteshez = {} -- reset and fill up again

    for k, v in ipairs(object) do
        if getElementData(v,"owner") == accname then
            local x,y,z = getElementPosition(v)
            local id = getElementModel(v)
            local owner = getElementData(v,"owner") or accname
            local int = getElementInterior(v)
            local dim = getElementDimension(v)
            local Rx,Ry,Rz = getElementRotation ( v )

            menteshez[#menteshez + 1] = {x,y,z,id,owner,int,dim,Rx,Ry,Rz}
            
        end
    end
    callClientAwait(thePlayer, "saveMapData", "save" .. base64Encode(accname), menteshez, 
    function (successState) 
		outputChatBox(client, "Map data has been saved.")
    end)
    

end

addCommandHandler("save",teszt)

	

 

 

function testLoad (thePlayer)
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)
    callClientAwait(thePlayer, "loadMapData", "save" .. base64Encode(accname), menteshez, 
    function (data) 
		outputChatBox(client, "Map data is here available, if it has been saved before")
    end)
end
addCommandHandler("load",testLoad)

 

Client

local xml = exports.xmldata
function saveMapData (fileName, data)
	return xml:xmlSaveData(fileName, data, true, false, true)
end
function loadMapData (fileName)
	return xml:xmlLoadData ( fileName, true,  true)
end

 

 

 

 

Posted
24 minutes ago, IIYAMA said:

There is no `easy` in doing that.

 

For the example code, I will be using my library, so that I do not have to write so much code. Feel free to replace them with trigger events.

Note: I did not test this, but it will at least give you an idea how it could be done.

 

Server


local xml = exports.xmldata

function teszt(thePlayer)
    local object=getElementsByType("object")
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    local menteshez = {} -- reset and fill up again

    for k, v in ipairs(object) do
        if getElementData(v,"owner") == accname then
            local x,y,z = getElementPosition(v)
            local id = getElementModel(v)
            local owner = getElementData(v,"owner") or accname
            local int = getElementInterior(v)
            local dim = getElementDimension(v)
            local Rx,Ry,Rz = getElementRotation ( v )

            menteshez[#menteshez + 1] = {x,y,z,id,owner,int,dim,Rx,Ry,Rz}
            
        end
    end
    callClientAwait(thePlayer, "saveMapData", "save" .. base64Encode(accname), menteshez, 
    function (successState) 
		outputChatBox(client, "Map data has been saved.")
    end)
    

end

addCommandHandler("save",teszt)

	

 

 


function testLoad (thePlayer)
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)
    callClientAwait(thePlayer, "loadMapData", "save" .. base64Encode(accname), menteshez, 
    function (data) 
		outputChatBox(client, "Map data is here available, if it has been saved before")
    end)
end
addCommandHandler("load",testLoad)

 

Client


local xml = exports.xmldata

function saveMapData (fileName, data)
	return xml:xmlSaveData(fileName, data, true, false, true)
end

function loadMapData (fileName)
	return xml:xmlLoadData ( fileName, true,  true)
end

 

 

 

 

okay, i replaced them with trigger events, and triggers are working fine

but how can i get datas in load func?

function testLoad (thePlayer)
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    triggerClientEvent(thePlayer,"sbetolt", thePlayer, "save"..base64Encode(accname), menteshez)

end
addCommandHandler("load",testLoad)

 

  • Moderators
Posted
2 minutes ago, Turbesz said:

but how can i get datas in load func?

By keeping a function alive within the testLoad function, until the message is send back.

And how do you do that? Well, you can look at the source code of my library and see if you could replicate a part of it. Or just use the library.

 

Or you can also not do it and return it in to a different function, that would be the easiest way without library.

 

Posted
37 minutes ago, IIYAMA said:

By keeping a function alive within the testLoad function, until the message is send back.

And how do you do that? Well, you can look at the source code of my library and see if you could replicate a part of it. Or just use the library.

 

Or you can also not do it and return it in to a different function, that would be the easiest way without library.

 

i tried make a new trigger to load from client to server, and then create the objects, but does not work

server:

function testLoad (thePlayer)
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    triggerClientEvent(thePlayer,"sbetolt", thePlayer, "save"..base64Encode(accname), menteshez)

end
addCommandHandler("load",testLoad)

function teszt2(thePlayer,x,y,z,id,owner,int,dim,Rx,Ry,Rz)

    local object=getElementsByType("object")
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    for i,v in ipairs(getElementsByType("object")) do 
        if getElementData(v,"owner") == owner then
        destroyElement(v)
        end
    end
        if owner == accname then
        id = id+1
        
            local x, y, z = getElementPosition(thePlayer)
            local theAcc = getPlayerAccount(thePlayer)
            local accname = getAccountName(theAcc)
        
        targy = createObject(id, x, y,z)
        
        setElementData(targy, "owner", accname)
        setElementData(targy,"id",id)
        setElementInterior(targy,int)
        setElementDimension(targy,dim)
        setElementRotation(targy,Rx,Ry,Rz)
        setElementData(thePlayer,"torles",getElementData(targy,"id") or 0)
        outputChatBox("betöltve")

        end
end

addEvent("load2",true)
addEventHandler("load2",root,teszt2)

client:

function loadMapData (fileName)
	local menteshez = xml:xmlLoadData ( fileName, true,  true)

	for k, v in ipairs(menteshez) do
		--outputChatBox(v[1])
		local x = v[1]
		local y = v[2]
		local z = v[3]
		local id = v[4]
		local owner = v[5]
		local int = v[6]
		local dim = v[7]
		local Rx = v[8]
		local Ry = v[9]
		local Rz = v[10]
		triggerServerEvent("load2",localPlayer,playerSource,x,y,z,id,owner,int,dim,Rx,Ry,Rz)
	end
end
addEvent("sbetolt",true)
addEventHandler("sbetolt",root,loadMapData)

what wrong?

  • Moderators
Posted (edited)
8 minutes ago, Turbesz said:

what wrong?

Your code does this:

  • Loop
    1. send over 1 object (network)
    2. delete all objects
    3. create 1 object
       
    4. send over 1 object (network)
    5. delete all objects (included the one you just created)
    6. create 1 object
       
    7. send over 1 object (network)
    8. delete all objects
    9. create 1 object

      etc. etc. etc.

 

Just send over the whole menteshez table > loop, else you will also kill your network.

 

 

Edited by IIYAMA
Posted (edited)
7 minutes ago, IIYAMA said:

Your code does this:

  • Loop
    1. send over 1 object
    2. delete all objects
    3. create 1 object
       
    4. send over 1 object
    5. delete all objects (included the one you just created)
    6. create 1 object
       
    7. send over 1 object
    8. delete all objects
    9. create 1 object

      etc. etc. etc.

 

Just send over the whole menteshez table > loop, else you will also kill your network.

 

 

Um i send now the whole table, and i get these warnings:
Bad argument @ 'getPlayerAccount' [Expected element at argument 1, got nil]
Bad argument @ 'getAccountName' [Expected element at argument 1, got nil]

client:

function loadMapData (fileName)
	local menteshez = xml:xmlLoadData ( fileName, true,  true)


		triggerServerEvent("load2",localPlayer,playerSource,menteshez)
end
addEvent("sbetolt",true)
addEventHandler("sbetolt",root,loadMapData)

server:

function teszt2(thePlayer,menteshez)
    local account = getPlayerAccount(thePlayer)
    local accountName = getAccountName(account)
    
    local object=getElementsByType("object")
    local theAcc = getPlayerAccount(thePlayer)
    local accname = getAccountName(theAcc)

    for i,v in ipairs(getElementsByType("object")) do 
        if getElementData(v,"owner") == accname then
        destroyElement(v)
        end
    end
    setTimer(function()
    for k, v in ipairs(menteshez) do
        if v[5] == accname then
        id = id+1
        
            local x, y, z = getElementPosition(thePlayer)
            local theAcc = getPlayerAccount(thePlayer)
            local accname = getAccountName(theAcc)
        
        targy = createObject(v[4], v[1], v[2], v[3])
        
        setElementData(targy, "owner", accname)
        setElementData(targy,"id",id)
        setElementInterior(targy,v[6])
        setElementDimension(targy,v[7])
        setElementRotation(targy,v[8],v[9],v[10])
        setElementData(thePlayer,"torles",getElementData(targy,"id") or 0)
        outputChatBox("betöltve")

        end
    end
end,500,1)
end

addEvent("load2",true)
addEventHandler("load2",root,teszt2)

why do i get those warnings?

Edited by Turbesz
  • Moderators
Posted
1 minute ago, Turbesz said:

playerSource

playerSource does not exist.

Use localPlayer instead.

 

 

Posted
1 hour ago, IIYAMA said:

playerSource does not exist.

Use localPlayer instead.

 

 

if i use localPlayer, then the objects are visible to the local player only?

  • Moderators
Posted (edited)
33 minutes ago, Turbesz said:

if i use localPlayer, then the objects are visible to the local player only?

no,


If you only want to see your objects, I recommend to set all objects to another dimension than the players.

And for every object you create:

triggerClientEvent > Clientside: setElementDimension (to your own dimension)

Edited by IIYAMA
  • Thanks 1
Posted
18 hours ago, IIYAMA said:

no,


If you only want to see your objects, I recommend to set all objects to another dimension than the players.

And for every object you create:

triggerClientEvent > Clientside: setElementDimension (to your own dimension)

thank you very much for all the help, and your patience :D 

at least I just learned something new :D 

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...