Jump to content

IIYAMA

Moderators
  • Posts

    6,044
  • Joined

  • Last visited

  • Days Won

    207

Posts posted by IIYAMA

  1. 14 minutes ago, Dzsozi (h03) said:

    Thank you on that case very much, I will get back to it but I need this system finished first

    No worries take your time, just checking if you may have mist it. 👍

     

    4 minutes ago, Dzsozi (h03) said:

    So far I only noticed this issue inside shared and server side loadstrings.

    Serverside (as well as shared~serverside) are limited by the ACL, clientside is not.

     

    5 minutes ago, Dzsozi (h03) said:

    Is it possible that maybe I messed up something in my acl.xml settings?

    That is possible.

    You can double verify if the resource has access to loadstring using: https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo

    addEventHandler("onResourceStart",  resourceRoot, function (startedResource)
        if not hasObjectPermissionTo ( startedResource, "function.loadstring", true ) then
            local cancelReason = "Missing permission function.loadstring"
            outputDebugString(cancelReason, 2)
            cancelEvent(true, cancelReason) -- Something is wrong, stop startup
        end
    end, false)

     

    You could also make a copy of your current ACL and use the default one:

    https://github.com/multitheftauto/mtasa-blue/blob/master/Server/mods/deathmatch/acl.xml

     

     

     

  2. 2 hours ago, Dzsozi (h03) said:

    Are there any workarounds or fixes for this issue?

    In most cases it works by default. But in some cases you need to restart the server. I ran in to that issue myself, restarting did resolve the problem for me.

     

    For the following info, I used the resource runcode as example.

     

    Step 1A, check if the request is applied:

    aclrequest list runcode all

    image.png.e1168042704b968e4be03b9f84b42d26.png

    Step 1B, if not, run:

    aclrequest allow runcode all

    Step 2A

    Test if the error is gone.

    Step 2B, not working?

    Restart the server

    Step 2C

    Still not working?

    Give the resource temporary admin rights and resolve it later.

     


    btw. not to go offtopic, but a reminder that I replied on your other topic with `PointOfInterest`.

  3. 14 hours ago, framef318 said:

    If I can't know how many values to return, what do I do with local a, b?

     

    That is why you can capture those by surrounding the fromJSON with a table:

    local result = {fromJSON(data)}

     

    Although this solution might be more optimised:

    local result = fromJSON("[" .. data .. "]")

    It changes your data string to:

    [[
        {
            "id": 49,
            "username": "framef318",
            "email": "[email protected]"
        },
        {
            "id": 50,
            "username": "framef3188",
            "email": "[email protected]"
        }
    ]]

    Which helps returning everything inside of 1 variable, instead of multiple.

     

    • Like 1
  4. 7 hours ago, framef318 said:
    local result = fromJSON(data)

    And if you do:

    local result = {fromJSON(data)}

    ?

     

        {
            "id": 49,
            "username": "framef318",
            "email": "[email protected]"
        },

    This is one return value.

    local a, b = fromJSON(data)

     

        {
            "id": 50,
            "username": "framef3188",
            "email": "[email protected]"
        }

    And this is one return value.

    local a, b = fromJSON(data)

     

    Other way (untested):

    local result = fromJSON("[" .. data .. "]")

     

    • Like 1
  5. 17 hours ago, Dzsozi (h03) said:

    then eventually the id would reach massive numbers like 213821, which I would like to avoid for the sake of simplicity.

    17 hours ago, Dzsozi (h03) said:

    For some reason infinitely growing IDs seem unoptimized

    It is just an integer, 213821 nothing in terms of memory. No matter how long the number is, it will not use more memory than if it was a string.

    10000000000 consumes less memory than "10000000000".

    If you do not believe me, ask Chat GPT...

     

    Also, I asked Chat GPT the following:

    How many times can fit 10000000000 in 8gb of memory
    Quote
    Let's figure this out!  
    Understanding the Units 
    
    • 1 GB (Gigabyte) = 1,073,741,824 bytes
    • 8 GB = 8 * 1,073,741,824 bytes = 8,589,934,592 bytes
    • We're assuming 64-bit integers, which take 8 bytes each.

    Calculation

    1. Divide total memory by the size of each integer: 8,589,934,592 bytes / 8 bytes/integer = 1,073,741,824 integers.

    Answer: You can fit approximately 1,073,741,824 integers of the value 10000000000 into 8 GB of memory. Important Note: This calculation assumes you're only storing these integers. If you're using other data structures, variables, or running a program, the available space will be reduced.

    😛

     

    17 hours ago, Dzsozi (h03) said:

    (because it becomes id 2 if i use table.remove)

    table.remove is only useful when you want to use a table as an array. It is very useful if order matters, but in your case there is no need for maintaining an order. It might save some memory, but the look up speed will consumes (incremental) a lot more CPU(you need to loop) which is a big trade off.

    local temp = {1, 2, 3, 7, 10, 100} -- id's inside

     

     

    17 hours ago, Dzsozi (h03) said:

    Also I don't really get what do you mean by making it lookupable by using another table ?

     

    For example the table pointOfInterestCollection.

    do
    	local id = 0
    	---@return integer
    	function generateId ()
    		id = id + 1
    		return id
    	end
    end
    ---@type {[integer]: table|nil}
    local pointOfInterestCollection = {}
    
    ---@param poi table
    function savePointOfInterest (poi)
    	local id = generateId ()
    	poi.id = id
    	pointOfInterestCollection[id] = poi
    end
    
    ---@param id integer
    ---@return table|nil
    function loadPointOfInterest(id)
    	return pointOfInterestCollection[id]
    end
    
    ---@param id integer
    ---@return boolean
    function removePointOfInterest(id)
    	if not pointOfInterestCollection[id] then return false end
    	pointOfInterestCollection[id] = nil
    	return true
    end

     

     

     

  6. 4 hours ago, Dzsozi (h03) said:

    Clearly it is there, but why is it not when I use the key bind?

    When are using the following:

    • bindKey
    • timers
    • trigger(server/client)Event
    • (set/get)ElementData
    • etc...

    The data that you pass through these functions is being cloned. The reason behind that is: the data is leaving it's current Lua environment. With as goal to maintain the data, else it is lost.

    Unfortunately metatables and functions can't be cloned, which is why you did encounter data loss.

    Fortunately, because they can't be cloned you know that something is wrong. If they were be able to get cloned, you would have ended up with multiple clones of the same entity that do not share data. Which becomes really hard to debug.

     

    To resolve this issue, do not pass the element but use a self made id(integer). And make it look up able by using another table.

     

     

  7. 3 hours ago, Dzsozi (h03) said:

    What is the reason behind this behaviour? Why I can't store the function as a variable through a function exectuion? The strangest thing is that I shouldn't be able to create the POI object at the first place if the interactionFunction were not a function type parameter.

     

    I tested the following code with this compiler and it works.

    https://onecompiler.com/lua/42wdewngs

    Are you sure you are not synchronizing the data or exporting it(call/export)? Because in that case interactionFunction becomes nil.

     

     

    PointOfInterest = {}
    PointOfInterest.__index = PointOfInterest
    
    function PointOfInterest:create(x, y, z, interactionRadius, interactionFunction, visibleDistance, interior, dimension, renderOffsetX, renderOffsetY, renderOffsetZ, onFootOnly)
        if type(x) ~= "number" or type(y) ~= "number" or type(z) ~= "number" then error("Bad argument @ PointOfInterest:create [Expected number at argument 1, 2, 3, got "..type(x)..", "..type(y)..", "..type(z).."]", 2) end
        if type(interactionFunction) ~= "function" then error("Bad argument @ PointOfInterest:create [Expected function at argument 5, got "..type(interactionFunction).."]", 2) end
    
        local poi = {}
        setmetatable(poi, PointOfInterest)
        poi.x = x
        poi.y = y
        poi.z = z
        poi.interactionRadius = type(interactionRadius) == "number" and interactionRadius or 1
    
        -- [temp disabled] poi.collision = createColSphere(x, y, z, poi.interactionRadius)
        -- [temp disabled] poi.collision:setID("poi") -- Set the ID to "poi" to identify it as a point of interest
    
        poi.interactionFunction = interactionFunction -- [simplified]
    
        poi.visibleDistance = type(visibleDistance) == "number" and visibleDistance or 10
    
        poi.interior = type(interior) == "number" and interior or 0
        poi.dimension = type(dimension) == "number" and dimension or 0
    
    
        poi.renderOffsetX = type(renderOffsetX) == "number" and renderOffsetX or 0
        poi.renderOffsetY = type(renderOffsetY) == "number" and renderOffsetY or 0
        poi.renderOffsetZ = type(renderOffsetZ) == "number" and renderOffsetZ or 0
    
        poi.onFootOnly = (type(onFootOnly) == "boolean" and onFootOnly) or false
    
    
        -- [temp disabled] TBL_POIS[poi.collision] = poi
    
        return poi
    end
    
    function testfunc()
        print('You are near the point of interest!')
        return true
    end
    
    
    local test = PointOfInterest:create(195.00665283203, -141.83079528809, 1.5858917236328, 1, testfunc, 10, 0, 0, 0, 0, 1, true)
    
    print(test.interactionFunction())

     

    Output:
    
    You are near the point of interest!
    true
    

     

  8. 1 hour ago, ThanaReal said:

    And that has been sent to chatbox twice. Because it worked in server and client side, right?

    Correct!

     

    51 minutes ago, Laxante101 said:

    Todos os métodos de tratamento de eventos

    Please mind that the primary language of this section is English. It is fine to add additional translations for clarification.

  9. 10 minutes ago, Snow-Man2 said:

    then i got this error 

     

    And if you do not modify the JSON? (and use backticks)

    local testJSON = toJSON(leaderboardData)
    
    if isElement(initBrowser) then
    	local script = string.format("populateLeaderboard(`%s`);", testJSON)
    	outputChatBox("SCRIPT : " ..script)
    	executeBrowserJavascript(theBrowser, script)
    end

     

    const leaderboardStats = JSON.parse(leaderboardDataJSON);
    console.log("Parsed leaderboard data:", leaderboardStats);

     

  10. Additional context:

    • Serverside is code executed on the server.
      • The application all players are connected to.
         
    • Clientside is code executed on each client/player his game.
      • There are as many clientsides as there are players in the server. They all run a copy of all clientside scripts.
      • Each player downloads the clientside code from the server. When a player joins the server, in most cases the copy of the code will only run until the download is finished. (with an exception if priority is given to a specific resource)
         
    • Shared is code executed
      • On the server
      • And a copy of the code is executed on each client / player his game

        ⚠️
      • Nothing is shared between them, except for running the same copy of the code.

     

    • Thanks 1
  11. 3 hours ago, Snow-Man2 said:

    leaderboard data:

    It looks like you got some unparsed JSON in your JSON result.

    console.log(typeof(leaderboardStats))
    
    // If type is object:
    const result = JSON.parse(leaderboardStats[0])
    
    // or if the type is a string:
    const result = JSON.parse(leaderboardStats)

     

    To make things a bit easier, use back-ticks so you do not have to escape your own JSON:

    local script = string.format("populateLeaderboard(`%s`);", escapedTestJSON)

     

     

  12. 9 minutes ago, Perseus said:

    I recorded another video, this time trying to compensate the latency:

    What if you switch roles and film the one that gets hit? That way you can verify if it is a bug.

    Also:

    • Double check if bullet sync is active.

     

    16 minutes ago, Perseus said:

    Is there a way to code a resource for lag compensation?

    It is indeed possible to override the bullet/damage system, but lag compensation is very complex and often result in unexpected results.

     

  13. 1 hour ago, Perseus said:

    As you can see in the video, the player will not get damage from the sides while sprinting

    What is the ping of the other player?

    It is normal to compensate your aim for latency, when the damage is registered clientside. You should aim at the location where the player is moving to. The higher the ping. the more you need to compensate.

    If you shoot a player in the back/front, latency matters less, it just delays the inevitable.

     

    Having 0 recoil makes the latency issue even worse, because the spread normally makes sure that at least some bullets hit.

    I recommend to put the recoil not to 0. It is fine to put it very low, but if you put it to 0, some calculations might be miscalculated.

     

    1 hour ago, Perseus said:

    I tried changing player_sync_interval from 100 to 50 but nothing.

    Increasing the interval does reduce some of the extra latency. To be specific from 100 > 50 could potential update the player position 50ms faster. But that is only the case with a stable internet connection. In case of an unstable internet connection, it might even increase latency when the network is being blocked by too many unreceived position updates.

  14. 3 minutes ago, Spc said:

    Yes, i'm using addDebugHook for detecting and blocking client-side functions as a form of anti-cheat, for example:

    This function is able to mimic that behaviour you just mentioned. Just be aware.

     

     

    3 minutes ago, Spc said:

    Do you mean adding multiple addEvent functions with same event name? I use this event in multiple resources.

    It might be worthed to look in to it and test if it has any impact if any of those are restarted.

    Also double check if the remote access is disabled for all of them. (2e argument of addEvent)

  15. 3 hours ago, ChvjCieObchodzi said:

    do you have any methods of downloading an image by URL without using local files and using only the client side

    If:

    • clientside only
    • without local files

    It might be possible with:

    fetchRemote + requestBrowserDomains

    Quote

    Wiki:

    fetchRemote

    Note: Client side function only works with the server the player is connected to unless the domain has been accepted with requestBrowserDomains

    But only very small images because of JSON limitations. fetchRemote only accepts JSON format. I do not recommend this method unless it is only for small avatars.

    You also need an webserver/host where you save the images in JSON format and send it to the client.

  16. 20 hours ago, RekZ said:

    it's very difficult to know which event is being continuously executed

    There is not really a non expensive way except for the debughook, which is CPU expensive to use. From my perspective, the more complex you make this threshold mechanism, the faster your server will be downed.

     

    For sensitive events attached to for example a database, you want to have some kind of firewall, for example: 

    checkPassiveTimer (utility with clean-up)

     

    • Like 1
  17. 23 minutes ago, DarkStalker30 said:
            if x and y and z and world and dimension and rotation then
                player = client
                setElementData(player, "player.activeMarker", false)

     

            if x and y and z and world and dimension and rotation then
                local player = client -- < HERE
                setElementData(player, "player.activeMarker", false)

    Make `player` a local variable. Else all players will share the variable `player` for the (delayed) timer functions.

     

    You can also pass the predefined `client` variable like this:

    setTimer(function (player)
    
    end, 1500, 1, client)

     

    • Thanks 1
×
×
  • Create New...