Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 15/02/24 in all areas

  1. Lua Language Server - Definition files The Lua language server is a powerful tool that enhances the development experience for Lua programming. It provides a comprehensive set of code editing features, including suggestions, auto-completion, and error checking. With the Lua language server, developers can effortlessly navigate through their resource files, access documentation easily, and ensure code correctness by giving warnings. Why should you care? The language server will inform you about all sorts of problems: type mismatches, missing function arguments, missing variables, etc. You have access to a lot of MTA syntax/autocomplete out of the box. The syntax information will remain while writing. You do not have to restart your resource so often in order to validate if everything is working. Type validation Having value type validation in your code editor is one of the main key features of the Lua Language Server. When working with variables, parameters, and arguments in Lua, you are not restricted to specific value types. This flexibility can make mistakes more likely to happen. However, being able to validate those mistakes instantly saves you a lot of time and frustration. Type annotations for your own functions Adding type annotations to your own functions can help improve validation and catch logic mistakes. It is particularly useful when calling functions from different parts of your code, as the annotations provide clarity on the expected input (arguments) and output (return values). Additionally, comments that are placed above or adjacent to a variable or function are visible when hovering over them in another file or line. This can provide helpful information and context when working with the code. How that looks like: How can I quickly add annotations in less than a second? Open the spoiler: AddEventHandler auto-complete Most MTA addEventHandler functions have full eventName autocompletion. And the attached anonymous function is fully autocompleted and typed as well. Navigation features of Lua Language Server It can be time consuming to find out where a (global) function or variable is located. Being able to jump right to it, saves you a lot of time. Other information which you can find in the readme Installation for the Lua Language Server How to use the definition files? Known issues Make sure to always have an empty new line at the end of your files, as recommended in this issue. Currently, the Lua server language definition files do not have a clear separation between serverside functions/events and clientside functions/events. However, it is possible to enforce this separation for specific functions if needed. outputChatBox--[[@as outputChatBox_server]]("Serverside", player) In certain cases, certain functions in the Lua server language definition files may return multiple types, even if you have selected a different syntax. To handle this situation, you can use the `cast` or `as` notation to explicitly specify the desired type or adjust the returned type. See `Casting and as` syntax below. Casting and as In certain situations, you may have a strong understanding of the type(s) that a variable or expression will have. This is where the keywords "cast" and "as" come into play. These keywords enable you to explicitly specify the intended type, ensuring proper type handling. local varName = exampleFunc() ---@cast varName string local varName = exampleFunc() ---@cast varName string | number local varName = exampleFunc() --[[@as string]] local varName = exampleFunc() --[[@as string | number]] Download The definition files can be downloaded here.
    3 points
  2. Bro, apologies for my stupidity, but I have another question. When I type text in the fields "FirstName, LastName...", pressing the "T" key opens the in-game chat. How can I get rid of this? The "T" key is set to open the in-game chat, but this is very inconvenient.
    1 point
  3. Yes, that is indeed the case. (Sublime)
    1 point
  4. I assume both annotations and go to definition (particularly variable, because you can already go to function definition) works for Sublime Text 4 as well?
    1 point
  5. Okey, helped me. Last question Please help me find out how to call the "window" menu panel (passport registration) when in contact with a marker. I assume I need to write a function and addEventHendler. local playerPassportEdit = createMarker(-712.9, 962.5, 12.3-1.7,"cylinder",2.0,255,0,0,104) addEvent("playerPassportEdit",true) addEventHandler("playerPassportEdit",getRootElement(),function() if source == playerPassportEdit then dgs:dgsSetVisible(window,true) showCursor(true) end end) Please forgive my silly questions, but I really don't understand.
    1 point
  6. Thank`s I do not need to change the data when opening this panel But at the moment, it can be done. How to remove it? How to make the data received from the DB (name, age, country) unchangeable? So they are static.
    1 point
  7. Thank's man! Two more question 1. How can I retrieve and display data from the database without the ability to edit it? 2. How can I close this panel with the "Close" button? I added your server-side part and based on your client-side, I wrote my own library for DGS. Client local dgs = exports.dgs local sw,sh = guiGetScreenSize() -- разрешение экрана игрока local px,py = sw/1920,sh/1080 -- адаптация экрана local window = dgs:dgsCreateWindow(((sw-800)/2)*px,((sh-600)/2)*py,800*px,600*py,"Паспорт",false) local buttonExecute = dgs:dgsCreateButton(325*px,530*py,150*px,40*py,"Подтвердить",false,window,nil,nil,nil,nil,nil,nil,tocolor(255,0,0),tocolor(100,0,0),tocolor(255,0,0)) local labelFirstName = dgs:dgsCreateLabel(200*px,200*py,400*px,30*py," Имя: ",false,window) local editFirstName = dgs:dgsCreateEdit(200*px,220*py,400*px,30*py,"",false,window,tocolor(255,255,255),nil,nil,nil) dgs:dgsSetProperty(labelFirstName,"alignment",{"center"}, {"center"}) dgs:dgsSetProperty(editFirstName,"alignment",{"center"}, {"center"}) local labelLastName = dgs:dgsCreateLabel(200*px,270*py,400*px,30*py," Фамилия: ",false,window) local editLastName = dgs:dgsCreateEdit(200*px,290*py,400*px,30*py,"",false,window,tocolor(255,255,255),nil,nil,nil) dgs:dgsSetProperty(labelLastName,"alignment",{"center"}, {"center"}) dgs:dgsSetProperty(editLastName,"alignment",{"center"}, {"center"}) local labelAge = dgs:dgsCreateLabel(200*px,340*py,400*px,30*py," Возраст: ",false,window,tocolor(255,255,255),nil,nil,nil) local editAge = dgs:dgsCreateEdit(200*px,360*py,400*px,30*py,"",false,window) dgs:dgsSetProperty(labelAge,"alignment",{"center"}, {"center"}) dgs:dgsSetProperty(editAge,"alignment",{"center"}, {"center"}) local labelCountry = dgs:dgsCreateLabel(200*px,410*py,400*px,30*py," Страна: ",false,window,tocolor(255,255,255),nil,nil,nil,tocolor(100,100,100,100)) local editCountry = dgs:dgsCreateEdit(200*px,430*py,400*px,30*py,"",false,window) dgs:dgsSetProperty(labelCountry,"alignment",{"center"}, {"center"}) dgs:dgsSetProperty(editCountry,"alignment",{"center"}, {"center"}) dgs:dgsWindowSetMovable(window,false) dgs:dgsWindowSetSizable(window,false) dgs:dgsWindowSetCloseButtonEnabled(window,false) dgs:dgsSetVisible(window,true) dgs:dgsSetVisible(window,false) showCursor(false) function openPanel() dgs:dgsSetVisible(window,true) showCursor(true) end function colsePanel() dgs:dgsSetVisible(window,false) showCursor(false) end local currentChose = "register" addEventHandler("onDgsMouseClick",root,function(btn,state) if btn == "left" and state == "down" then if source == buttonExecute then local firstName = dgs:dgsGetText(editFirstName) local lastName = dgs:dgsGetText(editLastName) local age = dgs:dgsGetText(editAge) local country = dgs:dgsGetText(editCountry) if not string.find(firstName,"%S") then outputChatBox("Name") return end if not string.find(lastName,"%S") then outputChatBox("LastName") return end if not string.find(age,"%d") then outputChatBox("Age") return end if not string.find(country,"%S") then outputChatBox("Country") return end triggerServerEvent("playerPassportEnter",localPlayer,firstName,lastName,age,country) end end end) local on = 0 addEvent("viewPassport",true) addEventHandler("viewPassport",getRootElement(),function(rezult) if on == 1 then return outputChatBox("[PASSPORT] Your passport window is open already!",104,250,104) end on = 1 local passport_info = dgs:dgsCreateWindow(((sw-800)/2)*px,((sh-600)/2)*py,800*px,600*py,"Паспорт",false) local closeButton = dgs:dgsCreateButton(325*px,530*py,150*px,40*py,"Close",false,passport_info,nil,nil,nil,nil,nil,nil,tocolor(255,0,0),tocolor(100,0,0),tocolor(255,0,0)) local firstNameInfo = dgs:dgsCreateMemo(10,20,150,25,"Имя: "..rezult[1]['FirstName'].."",false,passport_info) local lirstNameInfo = dgs:dgsCreateMemo(10,40,150,25,"Фамилия: "..rezult[1]['LastName'].."",false,passport_info) local ageInfo = dgs:dgsCreateMemo(10,60,150,25,"Возраст: "..rezult[1]['Age'].."",false,passport_info) local CountryInfo = dgs:dgsCreateMemo(10,100,150,25,"Страна: "..rezult[1]['Country'].."",false,passport_info) showCursor(true) dgs:dgsWindowSetMovable(passport_info,false) dgs:dgsWindowSetSizable(passport_info,false) end) Server local connect = dbConnect("sqlite","db.db") -- we create the db -- then we create a table -- we add the server side event addEvent("playerPassportEnter",true) addEventHandler("playerPassportEnter",getRootElement(),function(firstname,lastname,age,country) if client then -- check if data is from client you use always client when you bring data from clinet local acc_name = getAccountName(getPlayerAccount(client)) -- get the player account name local query = dbQuery(connect,"SELECT * FROM Users WHERE firstname=? OR lastname=? OR accountName=?",tostring(firstname),tostring(lastname),acc_name) local rezult = dbPoll(query,-1) -- we select the data and then get the rezult if #rezult > 0 then -- we check if the rezult table has some data with this player account outputChatBox("[PASSPORT] This firstname or lastname is used or you already created a passport!",client,104,255,104) else -- if we dont have any data with this player we add a passport! dbExec(connect,"INSERT INTO Users (accountName,firstname,lastname,age,country) VALUES(?,?,?,?,?)",acc_name,firstname,lastname,age,country) outputChatBox("[PASSPORT] New passport has been created successfully!",client,104,255,104) end end end) -- you put your x,y,z coordinates where your marker is or where you want to create the marker -- local viewPassport = createMarker(-713.0, 955.0, 12.3-1.7,"cylinder",2.0,104,255,104,104) addEventHandler('onMarkerHit',getResourceRootElement(),function(hitElement,matchingDimension) if getElementType(hitElement) == 'player' then -- check if the element which hits the marker is a player if source == viewPassport then -- we check if we hit our marker and not another marker local acc_name = getAccountName(getPlayerAccount(hitElement)) local query = dbQuery(connect,"SELECT * FROM Users WHERE accountName=?",acc_name) -- we select the data from db local #rezult = dbPoll(query,-1) if #rezult > 0 then -- if we have data we sent it to client triggerClientEvent("viewPassport",hitElement,rezult) else -- if we do not have data we write a message to player outputChatBox("[PASSPORT] You dont have a passport, to see a passport you need to create one first!",hitElement,104,255,104) end end end end) My DB CREATE TABLE "Users" ( "ID" INTEGER NOT NULL UNIQUE, "accountName" TEXT, "FirstName" TEXT NOT NULL, "LastName" TEXT NOT NULL, "Age" TEXT NOT NULL, "Country" TEXT NOT NULL, PRIMARY KEY("ID" AUTOINCREMENT) );
    1 point
  8. 1 point
×
×
  • Create New...