Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/01/19 in all areas

  1. Discordo. Não acho útil criar outro banco de dados para colocar as contas dos jogadores. Não tem motivo algum pra fazer isso. É melhor usar o banco de dados nativo para isso.
    2 points
  2. @ytjuliocesar Tópico fechado, mas já tem esse que é duplicado e você pode postar lá: Quero enfatizar também para que respeite os membros do fórum e as regras, e, embora não tenha nenhuma restrição em pedir códigos, te aconselho a fazer ou, ao menos tentar criar o código você mesmo. É uma boa escolha se quiser aprender a programar até por que não faz sentido alguém querer ter um server mas ter zero de interesse em programar Lua.
    2 points
  3. getAccountsBySerial na verdade já funciona com um SELECT pra retornar as contas, então dizer que um sistema de contas que utiliza banco de dados é mais rápido pode ser um engano. Aqui está como a função é definida no código fonte do MTA: https://github.com/multitheftauto/mtasa-blue/blob/master/Server/mods/deathmatch/logic/CAccountManager.cpp#L903
    1 point
  4. Isso é acontece quando você segura SHIFT+TAB com o RaidCall aberto. A solução é desativar o overlay do RaidCall. Settings -> Overlay (dentro do RC). Aí em cada um dos campos que irá aparecer, você aperta CTRL + Espaço pra deixar vazio.
    1 point
  5. Só uma dica também, antes de querer criar essa limitação, seria adequado utilizar métodos eficazes de recuperação de senha, pois constantemente o pessoal acaba se esquecendo de suas senhas (usam o “salvar senha” e em algum tempo limpa o cache e se esquece) e caso não consigam jogar criando uma outra conta, a perda de players seria considerável. Exemplos recuperação de senha: Por e-mail (usando API, ex: https://www.mailgun.com, https://sendgrid.com, ou então um Servidor Web + Gmail) Por informações pessoais (data nascimento / nome do cachorro / da escola / da mãe ….)
    1 point
  6. 1 point
  7. Dá para fazer qualquer script no MTA, usando outras linguagens de programação. Como Java e C. Então essa parada de "impossível", na atual versão do MTA e toda a tecnologia que as linguagens nos proporcionam, não existe mais. É possível fazer qualquer coisa.
    1 point
  8. Ah, sim, tudo bem. Desculpe a minha má interpretação. É que eu costumo trabalhar com servidores vinculados à sites. Neste caso, para mim, é mais fácil. De qualquer forma; você está correto sobre criar coisas que já existem, não faz sentido. AHAUHAHUAUHA
    1 point
  9. Discordo de vc ter dito que é mais fácil criar um banco de dados pra salvar as contas. Isso é desnecessário, pois já existe um banco de dados nativo para salvar as contas, não há motivo para criar algo que já existe. Além disso todas as funções nativas de obter dados das contas deixariam de funcionar. No fim das contas é mais uma coisa pra ficar dando dores de cabeça mais tarde.
    1 point
  10. Wow, I wish I'd come up with such a simple solution easily. Thank you very much
    1 point
  11. O melhor a se fazer é criar um banco de dados com as contas dos jogadores. Sendo assim, com um SELECT (bem escrito), levaria menos de 1 segundo para realizar uma verificação.
    1 point
  12. Bom, eu uso esse painel de login que também só permite 1 conta por serial. Na parte de registrar contas, ele verifica se já existe uma conta com o serial do jogador que está tentando registrar uma conta. Se tiver, bloqueia o registro e pede para que ele logue nela. Em vez de você usar getAccountData que é um pouco pesado de processar, use a função getAccountsBySerial, que retorna todas as contas que possuem o serial específico. Se existe alguma, então cancela o registro do jogador e pede para que ele logue nela. local myAccounts = getAccountsBySerial (getPlayerSerial (client)) -- myAccounts é uma table com todas as contas que existem com o serial do jogador. if myAccounts[1] then -- Se existe o primeiro item da table, então: outputChatBox ("Você já tem uma conta registrada. Logue nela: "..getAccountName(myAccounts[1]), client) -- Manda isso no chat do jogador, informando o login da conta que já existe. end
    1 point
  13. 1 point
  14. @Abu-Solo - إداري ممتاز , أبو لوحة قوانين دي اكس .
    1 point
  15. function isElementOnGround ( Element ) assert ( Element , 'Bad Argument #1 , nil value' ) assert ( isElement ( Element ) , 'Bg Argument #1 , not element' ) local Ped = createPed ( 0 , 0 , 0 , 0 ) setElementAlpha ( Ped , 0 ) attachElements ( Element , Ped ) return isPedOnGround ( Ped ) , destroyElement ( Ped ) end -- Ex. addCommandHandler ( 'OnGround' , function ( Player ) local OnGround , Value = isElementOnGround ( Player ) -- Value always return true if ( OnGround == true ) and ( Value == true ) outputChatBox ( 'You On Ground' , Player ) end end )
    1 point
  16. You can change only the texture. You need a skin model wich have separated textures (face,hair,tshirt,etc...) and change only the face's texture
    1 point
  17. Hum. Claramente vc não está aqui pra aprender, só pra obter. Boa sorte amigo. Mas pra não dizer que não te dei nada, segue o link onde tem sua resposta: SetTimer Creio que vc deve conseguir fazer isso por conta própria, pois vc mesmo já sabe que é uma coisa simples.
    1 point
  18. A minha sugestão seria fechar esse tópico desnecessário para evitar mais brigas. Além de ter ocorrido diversas violações das regras do fórum por parte do autor neste mesmo post. Fica a seu critério @DNL291
    1 point
  19. Cara, por algo que parece simples por um setTimer, até hoje o @OverKILL me ajuda quando tenho dúvida. Então nem sempre o fórum vai ser a solução, então bro, te recomendo ler sobre a função; setTimer e após ler a função, por mais que seja díficil tente ler o código assim entendera aonde irá por o setTimer. Entendeu?
    1 point
  20. That would me sense. But the way you are using it now is very heavy work. Searching through all elements in the whole server. Would this not make more sense? (limiting to the resource only) for i, race in ipairs(getElementsByType('race', resourceRoot)) do -- do stuff here end This is even faster and has a better structure: -- server local raceContainer = createElement("raceContainer", "raceContainer") for i=1, 10 do setElementParent(createElement("race"), raceContainer) end (find one and access the rest) -- client local raceContainer = getElementByID("raceContainer") local raceElements = getElementsByType("race", raceContainer) -- search also through sub-elements -- or local raceElements = getElementChildren(raceContainer, "race") -- just the direct children (faster) for i, race in ipairs(raceElements) do -- do stuff here end Why bother making a race element? - You can let sub-elements hang on it. They will be deleted when you delete the parent. - Attach addEventHandlers to the parents of sub-elements. (which limits the event scope) - Limit the scope of element queries. (like: getElementsByType) - The benefit of having access to scoped propagation / inherits. -- server local raceContainer = createElement("raceContainer", "raceContainer") for i=1, 10 do setElementParent(createElement("race"), raceContainer) end setElementDimension(raceContainer, 50) (propagation / inherits is by default enabled: https://wiki.multitheftauto.com/wiki/SetElementCallPropagationEnabled)
    1 point
  21. بخير يالله لك الحمد , اخبارك انت .
    1 point
  22. I think it's unfair for the players if you have an Account Manager that shows their password which shows that you are not using proper encryption. You should try to work around that and add an encryption to passwords. Then you can match hashes to see if the passwords match and update their account the new password, or if you are the one managing the account, you can force new hashes; I still don't agree with admin's being able to see account passwords.
    1 point
  23. Tem alguns erros aí. Código: function Start_Id ( _, acc ) if eventName == "onPlayerLogin" then setElementData ( source, "ID", getAccountID(acc) or "N/A" ) outputChatBox ( "#00ff00✘ #ffffffLOGIN #00ff00✘➺ #ffffffNick: #00ff00 ( ".. getPlayerName(source) .." #00ff00) #ffffffID: #00ff00( "..(getAccountID(acc) or "N/A") .." )", root, 255,255,255,true) elseif eventName == "onPlayerLogout" then removeElementData( source, "ID" ) outputChatBox ( "#00ff00✘ #ffffffLOGIN #00ff00✘➺ #ffffffNick: #00ff00 ( ".. getPlayerName(source) .." #00ff00) #ffffffDeslogou.", root, 255,255,255,true) elseif eventName == "onResourceStart" then for _, player in pairs(getElementsByType("player")) do local acc = getPlayerAccount(player) if not isGuestAccount(acc) then setElementData( source, "ID", getAccountID(acc) or "N/A" ) end end end end addEventHandler("onResourceStart", resourceRoot, Start_Id) addEventHandler("onPlayerLogout", root, Start_Id) addEventHandler("onPlayerLogin", root, Start_Id) Exemplo no lado client: addCommandHandler("contaid", function() local id = getElementData( localPlayer, "ID" ) or false if id then outputChatBox( "O ID da sua conta é: "..(tostring(id) or "Erro desconhecido"), 0,230,0 ) else outputChatBox( "Você está deslogado!" ) end end )
    1 point
  24. Как я и обещал – публикую статью о некоторых возможностях шейдера и MTA. Речь пойдёт об изменении цвета нужных нам компонентов автомобиля (а точнее текстуры, которые наложены на полигоны этих компонентов) с помощью пиксельного и вершинного шейдеров. В качестве примера, я буду использовать стандартный автомобиль Sultan, а перекрашивать я ему буду диски на колёсах. На самом деле данный метод будет работать на любых объектах игры, будь-то это объекты ландшафта или же персонажи. Но так как сегодня мы будем работать с ZModeler 2, то их рассматривать мы не будем (так как ZM2 не умеет работать с костями персонажей и плохо экспортирует обычные объекты). Сразу оговорюсь – имеется ввиду, что вы уже владеете основами работы с ZModeler 2, поэтому детально рассматривать эту программу мы не будем. К счастью русскоязычных уроков по ZM2 очень много. Подготовка И так, мы имеем проект с уже готовым автомобилем, который без проблем работает в нашей любимой игре. Теперь можно приступать к делу. Для того чтобы MTA смогла найти с каким материалом ей работать — мы должны передать ей имя с помощью engineApplyShaderToWorldTexture. При экспорте модели из ZModeler 2 все материалы принимают название первой текстуры в самом материале. Т.е. если ваша текстура называется WHEELS.tga – то материал будет называться WHEELS. Это очень важно, так как если вы просто покрасите колёса и не установите текстуру (хотя бы в 1px), то материал в игре будет называться unnamed, как и все у которых нет текстур. Реализация Так уж случилось, что диски моего автомобиля имеют текстуру vehiclegeneric256, которая не является уникальной (ею окрашены ещё другие части автомобиля) – это не редкое явление. Чтобы решить эту проблему, придётся создать копию этой текстуры и назвать так как нам нужно. Далее мы создаём новый материал, называем его как нам удобно (я предпочитаю чтобы имена материалов и имена текстур совпадали), добавляем новую текстуру, выделяем нужные нам полигоны и применяем к ним наш материал. Экспортируем нашу модель.. и а этом наша работа с ZModeler2 закончена. Пишем шейдер Сам по себе шейдер будет очень простой, мы создадим одну переменную которой мы сможем задавать значения цвета из скрипта, все остальные данные нам предоставит MTA. Для загрузки шейдера я использовал следующий скрипт (он очень простой, поэтому отдельно его рассматривать мы не будем): addEventHandler( "onClientResourceStart", resourceRoot, function() local shader = dxCreateShader( "color.fx" ); if shader then dxSetShaderValue( shader, "color", { 1.0, 0.5, 0.0 } ); engineApplyShaderToWorldTexture( shader, "wheels256" ); end end ); Теперь займёмся написанием самого шейдера. Объявляем переменные: float4 color = 1; sampler Sampler0 : register( s0 ); В качестве цвета мы используем переменную color - её значение мы будем устанавливать с помощью engineApplyShaderToWorldTexture Теперь нам необходимо взять текущий цвет пикселя и «смешать» его с нашим цветом (color): struct PSInput { float2 TexCoord : TEXCOORD0; }; float4 PixelShaderFunction( PSInput PS ) : COLOR0 { float4 texColor = tex2D( Sampler0, PS.TexCoord ); texColor *= color; return texColor; } Всё что и делает этот шейдер – просто перекрашивает пиксели текстуры. Как видно мы не учитываем освещение из-за чего наши колёса будут светиться в темноте как огни. И тут на помощь к нам приходит mta-helper.fx написанный нашими любимыми The MTA Team =) Так же они для нас написали замечательную функцию которая просчитывает дифьюзный цвет автомобиля с учётом глобального затенения мира – MTACalcGTAVehicleDiffuse. Функция первым аргументом требует нормали вершин. Так как пиксельный шейдер работает непосредственно с изображением, информацию о нормалях мы не имеем. Для этого нам придётся написать вершинный шейдер. Исправленный код шейдера: #include "mta-helper.fx" float4 color = 1; sampler Sampler0 : register( s0 ); struct VSInput { float4 Position : POSITION0; float3 Normal : NORMAL0; float4 Diffuse : COLOR0; float2 TexCoord : TEXCOORD0; }; struct PSInput { float4 Position : POSITION0; float2 TexCoord : TEXCOORD0; float4 Diffuse : COLOR0; }; PSInput VertexShaderFunction( VSInput VS ) { PSInput PS = (PSInput)0; float4 worldPosition = mul( VS.Position, gWorld ); float4 viewPosition = mul( worldPosition, gView ); float4 position = mul( viewPosition, gProjection ); PS.Position = position; PS.TexCoord = VS.TexCoord; PS.Diffuse = MTACalcGTAVehicleDiffuse( VS.Normal, VS.Diffuse ); return PS; } float4 PixelShaderFunction( PSInput PS ) : COLOR0 { float4 texColor = tex2D( Sampler0, PS.TexCoord ); texColor *= PS.Diffuse * color; return texColor; } technique { pass P0 { VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } } В вершинном шейдере мы создаем новый объект типа PSInput, который будет подаваться на вход в нашу функцию PixelShaderFunction. Так как объект изначально не имеет никаких данных, наша задача передать их, как мы и сделали это с TexCoord, Diffuse и Position. Так как основной задачей вершинного шейдера является установка вершин, то он должен определить семантику POSITION для выходного параметра. В нашем случае это Position. Чтобы получить правильную позицию вершины для пиксельного шейдера, мы умножаем её на мировую матрицу объекта (gWorld), затем на матрицу вида камеры (gView), а затем и на матрицу проекции камеры (gProjection). Далее всё просто, с помощью функции написанной разработчиками MTA мы просчитываем новый цвет и передаём в Diffuse. В пиксельном шейдере мы просто умножаем полученный Diffuse на наш color, вот собственно вот и всё. Пишем скрипт для шейдера Скрипт который я использовал выше не подходит для работы на реальном сервере, так как не поддерживает работу с несколькими объектами, ибо шейдер глобальный, а значит цвет колёс у всех машин будет один. Для этого нам нужно для каждого автомобиля создавать новый объект шейдера, который будет иметь своё значение цвета. Хранить информацию о цвете колёс мы будем в ElementData в виде таблицы – это позволит устанавливать цвет с серверной стороны (для этого мы будем отслеживать событие onClientElementDataChange). Так же мы будем отслеживать события onClientElementStreamIn, onClientElementStreamOut и onClientElementDestroy. Событие onClientElementStreamIn необходимо нам для того чтобы создать шейдер когда автомобиль попадёт в стример клиента, остальные два – для удаления шейдера. Скрипт шейдера: local vehicles = {}; function CreateVehicleShader( vehicle ) local color = getElementData( vehicle, "WheelsColor" ); if color then local shader = dxCreateShader( "color.fx" ); if shader then vehicles[ vehicle ] = shader; dxSetShaderValue( shader, "color", color ); engineApplyShaderToWorldTexture( shader, "wheels256", vehicle ); return true; end end return false; end function CheckVehicleShader( element ) local vehicle = element or source; if vehicle and getElementType( vehicle ) == "vehicle" then if vehicles[ vehicle ] then return true; end return CreateVehicleShader( vehicle ); end return false; end function DestroyVehicleShader( element ) local vehicle = element or source; if vehicles[ vehicle ] then destroyElement( vehicles[ vehicle ] ); vehicles[ vehicle ] = NULL; end end addEventHandler( "onClientElementStreamIn", root, CheckVehicleShader ); addEventHandler( "onClientElementStreamOut", root, DestroyVehicleShader ); addEventHandler( "onClientElementDestroy", root, DestroyVehicleShader ); addEventHandler( "onClientElementDataChange", root, function( key, oldValue ) if key == "WheelsColor" and getElementType( source ) == "vehicle" and CheckVehicleShader( source ) then dxSetShaderValue( vehicle[ source ], "color", getElementData( source, "WheelsColor" ) ); end end ); addEventHandler( "onClientResourceStart", resourceRoot, function() for i, vehicle in ipairs( getElementsByType( "vehicle", root, true ) ) do CheckVehicleShader( vehicle ); end end ); Как можно было заметить, функция CreateVehicleShader создаёт шейдер для нашего автомобиля. В случае успеха возвращает true. Вызов функции происходит только из CheckVehicleShader - она проверяет наличие шейдера для автомобиля, если его нет - создаёт его. В случае успеха так же возвращает true. Так как при старте ресурса в стримере уже могут быть автомобили и они могут иметь информацию о цвете (WheelsColor), мы используем событие onClientResourceStart для проверки всех автомобилей, что находятся в стримере. onClientElementDataChange мы отслеживаем на случай изменения информации о цвете со стороны сервера. Так как изначально её может не быть, то шейдер не будет создан при старте ресурса или когда автомобиль попадёт в стример игрока - для этого у нас есть функция CheckVehicleShader.
    1 point
  25. قسم غلط حط الوظيفة هنا
    0 points
×
×
  • Create New...