Jump to content

IIYAMA

Moderators
  • Posts

    6,062
  • Joined

  • Last visited

  • Days Won

    208

Posts posted by IIYAMA

  1.  

    27 minutes ago, bravura said:

    Sorry, to be honest I don't know

    14 hours ago, bravura said:

    from the console I can do everything

    The Console has full access, so it might be possible that you currently have no access to begin with.

     

    Steps to add the initial admin account (later on you can add more admins ingame using the User Interface):

    1. Stop the server
       
    2. Open the ACL file: MTA San Andreas 1.6\server\mods\deathmatch\acl.xml
       
    3. Make a back up of this ACL file
       
    4. Scroll to (in the original one):
          <group name="Admin">
              <acl name="Moderator"></acl>
              <acl name="SuperModerator"></acl>
              <acl name="Admin"></acl>
              <acl name="RPC"></acl>
              <object name="resource.admin"></object>
              <object name="resource.webadmin"></object>
              <object name="resource.acpanel"></object>
          </group>

       

    5. Add an account looking like this:
              <object name="user.example"></object>
      Replace example with your username even if the account does not exist yet. (keep it simple)

      And add it like this:
          <group name="Admin">
              <acl name="Moderator"></acl>
              <acl name="SuperModerator"></acl>
              <acl name="Admin"></acl>
              <acl name="RPC"></acl>
              <object name="resource.admin"></object>
              <object name="resource.webadmin"></object>
              <object name="resource.acpanel"></object>
              <object name="user.example"></object>
          </group>
    6. Save the file
       
    7. Start the server again (if you broke the syntax of the file, the server will not start, that is why step 3 so you can start over)
       
    8. Go ingame
      1. Add the account if not exist: /register <example username> <new password>
      2. /login <example username> <current password>

     

     

     

  2. 12 hours ago, bravura said:

    from the console I can do everything

    There is a difference in the panel and command access.

    This is for example a part of the rights for Moderators.

    <acl name="Moderator">
            <right name="general.ModifyOtherObjects" access="false"></right>
            <right name="command.gamemode" access="true"></right>
            <right name="command.changemode" access="true"></right>
            <right name="command.changemap" access="true"></right>
            <right name="command.stopmode" access="true"></right>
            <right name="command.stopmap" access="true"></right>
            <right name="command.skipmap" access="true"></right>
            <right name="command.mute" access="true"></right>
            <right name="command.unmute" access="true"></right>
            <right name="command.whois" access="true"></right>
            <right name="command.whowas" access="true"></right>
            <right name="function.setPlayerMuted" access="true"></right>
            <right name="function.kickPlayer" access="true"></right>
            <right name="function.banPlayer" access="true"></right>
            <right name="function.getBans" access="true"></right>
            <right name="function.addBan" access="true"></right>
            <right name="function.startResource" access="true"></right>
            <right name="function.stopResource" access="true"></right>
            <right name="function.restartResource" access="true"></right>
            <right name="function.refreshResources" access="true"></right>
            <right name="function.redirectPlayer" access="true"></right>
            <right name="general.adminpanel" access="true"></right>
            <right name="general.tab_players" access="true"></right>
            <right name="general.tab_resources" access="false"></right>
            <right name="general.tab_maps" access="false"></right>
            <right name="general.tab_server" access="true"></right>
            <right name="general.tab_bans" access="false"></right>
            <right name="general.tab_adminchat" access="true"></right>

     

    <right name="command.mute" access="true"></right>
    <right name="general.tab_bans" access="false"></right>

    You can see that the moderator can mute a player using /mute, but does not have access to the ban tab.

     

    How did you grand yourself access rights?

  3. 12 minutes ago, Firespider said:
    function tp(player, cmd, ID)
    	if getElementData(player, "Player.AdminLevel") > 1 then
    		local players = getElementsByType ( "player" )
    		if tonumber(ID) then
    			for i, p in ipairs(players) do
                    print(getElementData(p, "Player.ID"))
    				if getElementData(p, "Player.ID") == tonumber(ID) then
    					local x, y, z = getElementPosition(p)
    					setElementPosition(player, x, y, z)
    					
    				else
    					outputChatBox("#000000<#910e07Wise#ffffffRolePlay#000000> #ffffff Rossz ID-t adtál meg.", player, 255, 255, 255, true)	
    					
    				end
                    
                    
    			end
                
    		end 
    	end	
    end	

     

     

    ---@param ID number
    ---@return player | nil
    function findPlayerByID(ID)
    	local players = getElementsByType ( "player" )
    	for i, p in ipairs(players) do
    		if getElementData(p, "Player.ID") == ID then
    			return p
    		end
    	end
    end
    
    ---@param player element
    ---@param cmd string
    ---@param rawID string | nil
    function tp(player, cmd, rawID)
    	-- Admin level check
    	if getElementData(player, "Player.AdminLevel") <= 1 then return end
    	local ID = tonumber(rawID)
    	if type(ID) ~= "number" then
    		outputChatBox("#000000<#910e07Wise#ffffffRolePlay#000000> #ffffff /gethere [ID]", player, 255, 255, 255, true)
    		return
    	end
    
    	local targetPlayer = findPlayerByID(ID)
    	if not targetPlayer then
    		outputChatBox("#000000<#910e07Wise#ffffffRolePlay#000000> #ffffff Rossz ID-t adtál meg.", player, 255, 255, 255, true)
    		return
    	end
    	local x, y, z = getElementPosition(targetPlayer)
    	setElementPosition(player, x, y, z)
    end	

     

  4.  

    1 minute ago, Firespider said:

    but it always says 3 times that I entered the wrong ID

    On 27/11/2024 at 21:41, Firespider said:
    if tonumber(ID) then

    You should move this condition before the loop

    and if it fails,

    do the outputChatBox + return statement.

     

     

     

  5. 23 minutes ago, Firespider said:

    Could you explain what this code does?

    It inserts a row into the database and returns the generated primary key.

    But most of it are just examples for you to apply in to your own code. (also not tested, I haven't combined insert + update with the multipleResults statement myself)

     

    If something is unclear, please be specific in which part or function you do not understand. Then I will explain how that part/function works.

     

  6. 25 minutes ago, Firespider said:

    MYSQL

     

    In that case you can try to work with the following building blocks. (untested)

     

    local userName = "root"
    local password = "root"
    local host = "127.0.0.1"
    local db = dbConnect( "mysql", host, userName, password,
        "multi_statements=1"  -- optional
    )
    
    -- ...
    
    local player -- = ???
    local serial = 1234567890
    if db then
        
        dbQuery(onRegisterPlayer, {player}, db, [[
            INSERT INTO characters (serial) VALUES (?) 
            ON DUPLICATE KEY UPDATE id=VALUES(id);
        ]], serial)
    end
    
    -- ...
    
    ---@param queryHandle userdata
    ---@param player userdata
    function onRegisterPlayer(queryHandle, player)
        if not isElement(player) then return end
        local multipleResults = true -- return the id of the inserted row
        local result = dbPoll(queryHandle, -1, multipleResults)
        if not result then
            --- Something went wrong
            error("Failed to register player")
            return
        end
        iprint("Table", result[1])
        iprint("Affected rows", result[2])
        iprint("Last insert id", result[3])
    end

     

  7. 8 hours ago, Firespider said:

    At each entry, you set a SetElementData for the value of the ID table

    And at what point do you save the character?

    After filling in info of some sort?

     

    8 hours ago, Firespider said:
    local dq = dbQuery(db, "SELECT * FROM characters WHERE serial=?", serial)

    Are you using SQLite or MySQL?

  8. 2 hours ago, Firespider said:

    So I have the problem that every player gets an ID with setElementData when, for example, ID 1 appears based on the primary row of the SQL table But when the command is entered on the server, the system only works with a player with a specific ID, e.g. we can TP the player with a specific ID, etc.

     

     

    So you mean the user case when no ID is assigned to a new player?

    Based on what criteria are you assigning the ID?

  9. 1 hour ago, Firespider said:

    Yes, but does it need a name argument? However, I would like to solve it with ID

    It does indeed

     

    In that case, could you explain the following with some more context?

    3 hours ago, Firespider said:

    problem is that the players have an ID, but the system only detects the individual ID

    It is unclear what an `individual ID` is in the current context.

     

  10. 6 minutes ago, Firespider said:

    But that returns a name, doesn't it?

    No, it returns a player<element> or nil

    function getPlayerFromPartialName(name)
        local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil
        if name then
            for _, player in ipairs(getElementsByType("player")) do
                local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower()
                if name_:find(name, 1, true) then
                    return player
                end
            end
        end
    end
    
    local name = "IIYAMA"
    local player = getPlayerFromPartialName ( name )
    if player then
    	-- Found
    else
    	-- Not found
    end

     

  11. 1 hour ago, Firespider said:

    Hello, there is a small problem: the code does not break out of the cycle when I write the word break, here is the code (But what is before the break is executed, only after the break does not end the cycle)

    When use the keyword break, it jumps from:

    			for i, p in ipairs(players) do
    				if getElementData(p, "Player.ID") == tonumber(ID) then
                      
    					local x, y, z = getElementPosition(player)
    					setElementPosition(p, x, y, z)
    					break -- FROM HERE
    				else
    					outputChatBox("#000000<#910e07Wise#ffffffRolePlay#000000> #ffffff Rossz ID-t adtál meg.", player, 255, 255, 255, true)
    								
    				end	
    			end 
    			-- TO HERE
    		

     

    The following code prints: A, D

    for i=1, 10 do
      if true then
        print("A")
        break
        print("B")
      else
        print("C")
      end
    end
    print("D")

    Run here to test: https://onecompiler.com/lua/42zdspdkb

     

    Not sure what exactly the problem is that you are facing, but in your current code you could also use the return keyword to immediately stop the function.

    • Like 1
  12. 2 hours ago, scolen said:
    ---Why does the FPS drop when this anticheat resource is put on the server? What is the reason for that? please help

    If this code is ran clientside, it will create a lot of lag (because of setElementData).

    If ran serverside, it will have impact but consistent. (If the problem is purely located here and not created somewhere else)

    For now I consider this code to be ran serverside, because that would be the most logic place for this code to be used.

     

    The following components can be considered an impact multiplier on clientside:

     

    Does the pass have to be refreshed every 1 second? Can't it be refreshed every 10sec/1 min?

     

     

    2 hours ago, scolen said:
     local NewPass = ""
      for i = 1, character do
        local PassWordNew = string.char( math.random(97, 122) )
        NewPass = NewPass..PassWordNew
      end

    A small improvement, make the value of NewPass an integer. Which helps with the transfer speed.

     

  13. 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

     

     

     

  14. 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`.

  15. 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
  16. 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
  17. 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

     

     

     

  18. 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.

     

     

×
×
  • Create New...