Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/08/21 in all areas

  1. Eai pessoal blz? Então venho por meio desta compartilhar um pouco de conhecimento, fiz uma apresentação de slides sobre a lógica de programação para facilitar o conhecimento para qualquer um interessado, com exemplos fáceis e alguns exercicios. Você pode visualizar pelo site: http://pt.slideshare.net/Manawydan/logica-programar Criticas são bem vindas, e bom estudos para todos!
    1 point
  2. IP SERVER: mtasa://54.39.131.120:22003 ¡Welcome to ZOMBIE EVOLUTION! Zombie Evolution is a server for 2 game modes such as PvP and PvE, where you must survive and level up within the San Andreas map. Starting with a level system where everyone can level up and unlocking new spawns to use better weapons allowed within the server. Play alone and complete missions or join / create a clan to work as a team on the missions and objectives that the server has. On the server you will find different threats, both players and infected. Survive however you can ... or die trying and if you are sick of humanity, fight as a zombie and eliminate any player you see or infect them to join the zombie horde. Good luck, survivor. OPEN WORLD ► Spawn system CIVILLIANS civilians are the new members of the server who enter the world of Zombie Evolution. They have a spawn and base in Los Santos to be closer to the main missions and objectives of the server and have greater contact with the infected. ARMY The Army is located in area 51, where it is their main base of operations against the resistance and terrorists. They are responsible for maintaining order on the server rescuing civilians in danger and in constant war with both terrorists and clans allied with them. They have powerful weapons of war that only few can reach. RESISTANCE / TERRORIST The resistance or terrorists are an organization that works in conjunction with Umbrella, in charge of spreading terror and evil in the state of San Andreas, kidnap and murder civilians in order to test the new bio-weapons that the organization secretly works. Together with the gangs, they are an imminent danger in the state of San Andreas and they maintain their war with great constancy against Army than with S.W.A.T S.W.A.T The S.W.A.T or the San Andreas Police Station are combat experts who, together with the help of the S.T.A.R.S and the Special Military Unit, manage to rescue a hundred people after the infection of the state of San Andreas. Its constant fighting against the Resistance causes the San Andreas government to lose power, being under the protection of the Army's in San Andreas, but its mission to protect the people and rescue them continues at all times. INFECTATES The infected are players who fell into the clutches of zombies and now live roaming the state of San Andreas infecting more people. Unlike the common infected, infected players are faster and with the power to use vehicles and melee weapons. The army's, resistance and S.W.A.T try to contain as best they can to this class of infected, resulting in the majority of combats as defeats. Civilians ironically consider themselves the only ones capable of fighting these threats GANGS (you need or join a clan) Gangs are clans formed with the purpose of being a nuisance to both the army and the squads. These aim to be mercenaries or assassins in charge of higher levels, these being blamed in the lore of zombie evolution for the majority of infections in the state of San Andreas. They are considered the strongest groups along with the squads of the state of San Andreas due to the number of members within these groups, and having a greater influence within the resistance and terrorists, even leading to the recruitment of civilians by deceiving them with good pay SQUADS (you need or join a clan) The military squads are groups or clans in charge of maintaining order and are considered the most prepared in terms of the defense of the State of San Andreas as well as in the attack. These Elite groups are constantly facing off against gangs as well as resistance or terrorists with the aim of returning peace to the state of San Andreas. ► MENU LOGIN ► HUD system The "HUD" system found on the server is optimized for the comfort of low-resource computers, where you can admire both your ping, fps, level, experience, and personalized map. Etc. RADAR The radar is designed so that you can observe the map of San Andreas in a good way, with the difference that if you require a greater range of vision, press the "z" to increase the size of this. You also have an ideal F11 to search the missions, hives, RC and other things on the map. Thanks to the descriptions that this contains on the left side of f11. HUD The "NO" system is designed for a comfortable and charming interface for the user, giving it a refreshing look during gameplay, with the following features WEAPONS NAMETAG LIFE PERCENTAGE ARMOUR PERCENTAGE INFECTION PERCENTAGE MONEY LEVEL EXPERIENCIE (obtained - total) There is also a hud in the name of ZE with information on your current FPS and PING. ► MISIONS In Zombie Evolutions there are all kinds of missions and jobs. Rescue Civilians, survive in wave survival, deliver packages, enter hives, among others. Next, we will show you the different missions in Zombie Evolution There are 2 types of armor. The civil armored vehicle: It is an exclusive mission for civilians where only they can operate this type of truck. It is a simple and comfortable mission to get to know the server. The special armor: The special armor is exclusive to army and resistance that are considered rivals for obtaining resources. The reward varies, but that of special armor is unique because if a group manages to make this armor, they can have the use of the bunker in Las Venturas in their hands. The mission "the hive" is a mission with the characteristics of the Resident Evil game where we present the model in flesh and life from the first Resident Evil movie, the hive has different bosses inside it, passwords, secret rooms, etc. It is a labyrinth to discover and therefore, it is a place that few would like to know and many would like to tread. ► BOSSES Zombie Evolution bosses are infected special enemies that have their own zones with different weapons and that can only be defeated by specific weapons. Some of these are made up of the following bosses. NEMESIS With his RPG, this enemy is an unprecedented killing machine, considered the best bio-organic weapon of Umbrella, not only is it in a room, if not, it appears on the streets of the State of San Andreas to annihilate anyone with their minigun. EX-USS He was a member of a clan called USS until he was cast for being very bloodthirsty He was infected with the T virus due to zombies He asked for help but his former clan turned their back on him Instead he was locked up by those who were once his comrades Now thirsty for revenge which keeps him in control of the T virus He will kill anyone who enters his aposintos COMBINE It is an experiment called super soldier which sought to increase the resistance and strength of the soldiers But it turned out relatively badly, they went crazy wanting to kill whoever they saw on the other side achieved their goal, they had great resistance and above all, enough strength to break your neck with one hand. For that reason it is locked in ls to avoid more casualties. LEATHERACE His real name is Jedidiah Sawyer was someone who got violent easily and the infection was what made him detonate Injecting himself with a dose of the g virus, he took his favorite weapon and began a massacre. Now he is locked up in sf to prevent him from continuing to kill civilians TOP MISSIONS Every day there are missions to fulfill, reaching the chasm is what some need and require. In Zombie Evolution, there is a TOP where, for completing missions, you get special prizes and you will have to go through the server little by little to be able to complete said missions. So completing them will be an easy or difficult task, also depending on the mission. ► SURVIVAL MODE Survive, annihilate, but above all, don't die. Survival mode is in Zombie Evolution, and it brings a lot of hordes after you, where they will try to kill you. There will be 3 special maps where each one will be different, also depending on the enemies. BONE COUNTRY It is the town where the cattle live and worship saddler. These will always attack with weapons of sticks, branches and shovels in order to finish off the enemy that invaded them, like you, Leon. S. Kennedy LOS SANTOS The city of saints is a perfect setting for zombies, try to avoid them. These are slow, but if they catch you, they will bite you and try to finish you off as soon as possible. For one they are weak, but together, they are a threat that will try to finish off Jill Valentine. EPSILON FARM House of the Enlightened. The monks, believers and other members of this dangerous organization are in this place, commanded by the dangerous executioner, they will try to kill you as a hunk. Each map has 3 difficulties and 4 climates, where you can obtain a special bonus depending on the climate and difficulty. The reward varies by map. FOR MORE DESCRIPTION, WATCH THIS: SURVIVOR ► MODE HISTORY The story mode is found in Zombie Evolution. Lion. S. Kennedy is on an important mission, where duty calls again after the loss of connection of Los Santos with the rest of the state. What Leon will find in the city of Los Santos is a disgrace and horror. Deaths, agony, are words that fall short of what happened in Los Santos. Help Leon find out what happened, while facing zombies, umbrella agents, special infected and above all ... A powerful threat like a corporation. ► TURFS SYSTEM THE TURFS are areas of conquest for both the clans and the armies and resistance that require capturing them and dominating the area and the state of San Andreas. The advantage of the TURFS are high. From the instantaneous recovery of 15% of life for each kill of the group that has mastered it, to the absolute title of "dominator of the server" to be known within the server. It is important in pre-event warfare and clan wars that staffs organize within the server. ► CAR SHOP A NEW MAPPING FOR THE VISUALIZATION OF THE PLAYERS WAS DESIGNED, GIVING MORE FOCUS TO THE IMPORTANT VEHICLES AS BASICS OF ALWAYS SHOWN AT FIRST SIGHT, NOT TO MENTION THAT THE VEHICLES OF THE MONTH WILL NOW STAND OUT IN A BETTER WAY THE TUNING ZONE HAS A FIRST CONFORMED VISUALIZATION TO BE ABLE TO SHOW THE PLAYER THE DIFFERENT IMPROVEMENTS THAT CAN BE MADE TO THE VEHICLE, FOR EXAMPLE: shield Increases the durability of the vehicle against bumps, shots, etc Engine Increases speed, acceleration and improves vehicle brakes Color Principal Change the color of the vehicle with the RGB panel according to the user's taste Secondary Color [Change the color of the vehicle's wheels according to the user's taste] Color Faros Change the color of the lights according to the user's taste Color Effect Change the appearance of your vehicle to a variety of colors Neon Add neon to your vehicle where you can change color Nitro Add turbines capable of increasing the speed of your vehicle, this also affects the chosen engine Horn Choose the horn sound you want your vehicle to integrate, including sounds of well-known melodies Vehicle Time Selection of increasing the time of the vehicle or keeping it unlimited ENTER AND ENJOY OUR SERVER. YOU WILL NOT REGRET. IP SERVER: mtasa://54.39.131.120:22003 ¡Welcome to ZOMBIE EVOLUTION!
    1 point
  3. Introdução O conteúdo deste tópico será separado por seções, ensinando passo-a-passo cada detalhe - desde criar um BOT no site do Discord Developers, até finalmente ligá-lo e executar os comandos, que serão enviados para o seu servidor MTA. Siga todos os passos para que tudo dê certo. Configurando o ambiente Bom, para que nós possamos iniciar, é necessário instalar duas coisas no seu computador: Node.js e Visual Studio Code. Só um adendo: não é estritamente necessário usar o VSCode, estou apenas sugerindo-o, e também é a IDE que irei utilizar neste tutorial. Após instalá-los, seguiremos a próxima seção. Como criar um BOT no Discord Developers Acesse este link: https://discord.com/developers/applications - se você não estiver com uma sessão do Discord aberta no navegador, faça o login para que você possa acessar as funcionalidades desse site. Provavelmente, após entrar numa sessão, uma página como esta irá surgir: Ignore as minhas aplicações. O seu estará vazio - eu acho. Para iniciarmos a criação de uma nova aplicação, clique no botão que está no canto superior direito: Escolha o nome que desejar, isso não importa muito para este tutorial. Uma vez criada, uma outra página aparecerá, com mais informações. Primeiramente, vá até a aba Bot. O botão fica ao lado esquerdo: Agora, para que criemos de fato o BOT, clique no botão ao lado direito: Um pop-up irá aparecer, basta clicar em Yes, do it! Mais uma vez, irá carregar, na mesma aba, mais informações, agora sobre o seu BOT. Não compartilhe nada do que estiver escrito na página, com ênfase no seu token, que faz o seu BOT ficar online. Agora, voltemos para a aba principal: Nessa aba, você possui o Client ID da sua aplicação. Esse ID não é o token, você não precisa se preocupar caso compartilhe com alguém: Copie-o e acesse este link para que possamos dar continuidade: https://discordapi.com/permissions.html. Nesse site, nós podemos gerar o link de convite, no qual você irá precisar para adicionar o BOT no seu servidor do Discord. Cole o ID que você copiou neste campo: Também, selecione a permissão de administrador, que fica logo acima: Feito todos os passos, copie o link, abra uma nova aba no seu navegador e acesse o link gerado. Ele é parecido com este: Assim que você acessar, selecione o servidor no qual você quer adicionar o BOT e confirme tudo o que é pedido. Caso você tenha feito corretamente, o seu BOT já está no seu servidor. Vamos a próxima seção. Clonando o repositório do BOT Optei por criar um repositório no GitHub para que fique mais fácil este tutorial. Se você não sabe o que é clonar, apenas clique no botão de baixar, ao invés de clonar. Ele é assim: Clique em Download ZIP. Uma vez que temos o repositório no computador, descompacte-o na área de trabalho mesmo. Feito isso, uma pasta será criada. Agora, abriremos o VSCode. Siga estas instruções: Você irá selecionar a sub-pasta, que está dentro do pasta descompactada. Preste atenção ao selecionar. Há uma outra pasta dentro daquela que extraímos, abra a pasta correta. O resultado deve ser este: Ignore os ícones, fonte, cor de fundo. São extensões que eu uso. Vamos a próxima seção. Como instalar os pacotes da aplicação Ainda no VSCode, pressione CTRL + ' (aspas simples). O terminal irá abrir. Com ele aberto, digite o comando npm install. Os pacotes serão instalados - uma nova pasta e arquivo serão gerados. Não se preocupe com isso, não faz parte deste tutorial. Próxima seção! Como habilitar o Modo Desenvolvedor no Discord Para que nós possamos avançar a próxima seção, nós precisamos habilitar o modo desenvolvedor, para obter os IDs de canais, servidor, usuário, cargos e outros. É simples. Acesse as configurações da sua conta, clique na aba Aparência, desça tudo e irá se deparar com isto: O meu já está ativado. Caso o seu não esteja, ative-o. Next... Configurando as variáveis do BOT Agora que nós já podemos copiar o ID de alguns elementos do Discord, iremos configurar os arquivos que estão dentro da pasta config, abra-a. Os arquivos são estes: Primeiramente, crie um canal no seu servidor do Discord e copie o ID dele. Basta clicar com o botão direito em cima e copiá-lo. Abra o arquivo channel.js e apenas altere o valor que está lá. Salve o arquivo e abra o próximo, guild.js. Para eu não me estender muito, você fará os mesmos passos acima, copiando o ID e substituindo. Para copiar o ID do seu servidor, basta clicar com o botão direito em cima do nome dele. Já no arquivo mta.js, você deve alterar as informações de acordo com o seu servidor. Veja a explicação abaixo. ip - do seu servidor. httpPort - a porta HTTP do seu servidor, você pode consultá-la aqui neste site. username - crie um usuário no seu servidor e dê permissões administrativas para ele. password - a senha que você colocou no usuário. ATENÇÃO: USE UM USUÁRIO E SENHA QUE NÃO SEJA FÁCIL DE DESCOBRIR, LOGO NÃO COMPARTILHE COM NINGUÉM. Em relação ao outro arquivo, prefix.js, é apenas o prefixo que você usará nos comandos, altere se quiser. O arquivo token.js fala por si só, você irá pegar o token de acesso do seu BOT, lá no site do Discord Developers e substituir dentro do arquivo. Acompanhe na imagem abaixo. Bom, já disse na seção passada que você não deve compartilhar o token. Seguiremos a próxima. Clonando o repositório do resource Assim como no repositório do BOT, o resource também está no GitHub. Baixe-o, da mesma forma do BOT, mas agora adicione no seu servidor MTA, na pasta resources. Lembrando que deve-se extrair e colocar a pasta correta, verifique bem a sub-pasta. Uma vez adicionado no seu servidor, use o comando refresh para atualizar a lista de resources e inicie-o. Ah, e também dê permissões administrativas para ele! Pronto. Já podemos prosseguir. Iniciando o BOT Estamos quase ao ponto de executar os comandos. Vamos iniciar o BOT. Agora no VSCode, naquele mesmo terminal, use o comando npm start. Se tudo foi feito corretamente, ele irá se iniciar sem erros e uma mensagem dizendo que o BOT foi ligado deve aparecer. Testando os comandos Lembra que nós criamos um canal para executar os comandos? Pois é agora que iremos utilizá-lo. Lembre-se: o seu servidor deve estar ligado - entre nele também para que você possa ver as mensagens no chat. Alguns comandos que eu fiz, apenas para exemplificar. Você pode adicionar mais comandos se quiser. Se você não alterou o prefixo, aqui estão os comandos que fiz. (Você deve ser ADMINISTRADOR do seu servidor para executá-los) $settime <hora> <minuto> - $settime 12 00 | Irá alterar o clima no servidor. $text <mensagem> - $text opa, jogadores, tudo bem? | A mensagem será enviada no chat do servidor. $status | Mostrará algumas informações do servidor no chat do Discord. $mute <jogador> - $mute andr0xy | O jogador ficará mutado até se reconectar. $givemoney <jogador> <quantia> - $givemoney andr0xy 15000 | Dá dinheiro ao jogador. $cgroup <nome> - $cgroup VIP | Cria um grupo na ACL. Apenas uma observação: é possível sim, nos comandos que envolvem jogadores, executá-los pelo ID. Basta você editar o resource - não irei explicar como faz isso, pois não tem relação ao tutorial. Agradecimento & Informações Muito obrigado por seguir o tutorial. Fiz com o ❤ para toda a comunidade. Espero que vocês evoluam ambos códigos e que isso se torne muito maior dentro do servidor de vocês. Lembre-se que tudo é possível no MTA, contribuam sempre de alguma forma para que outros também possam evoluir. A união é importante nessa área. Busquem conhecimento! Crédito ao autor da SDK, o que faz ser possível conectar-se ao servidor MTA. 4O4 - GitHub Edições neste tutorial 28.01.2021 - AVISO: renomeie o resource para discordapp. 29.01.2021 - CORREÇÃO: texto confuso na seção Clonando o repositório do BOT. 29.01.2021 - AVISO: código do resource refatorado, sendo mais fácil adicionar novos comandos.
    1 point
  4. https://github.com/multitheftauto/mtasa-blue/tree/master/Client/launch
    1 point
  5. can you please remove this invisible wall? https://youtu.be/RNjvrCZ4ogs
    1 point
  6. add some small bridge. this hole is located on 2 baze https://youtu.be/NfeMEpVnrQ0
    1 point
  7. Olá pessoal, hoje vamos falar de algo que destrói a cabeça de novatos no MTA: Quando e onde devo usar source? Então vamos a primeira pergunta que surge, mas o que diabos é source no MTA? source nada mais é do que: parâmetro determinado por uma função ou evento. Você agora você deve estar perguntando o que é parâmetro. É muito simples, pense comigo na função addCommandHandler. Ela tem 2 parâmetros predeterminados que são (Quem_Executou, Nome_Do_Comando), como na imagem abaixo: Como você pode ver na imagem, ela tem os 2 parâmetros citados acima. Lembrando que: a própria wiki fala sobre os parâmetros. playerSource: O jogador que acionou o comando ou o console do servidor. Se não for acionado por um jogador (por exemplo, por administrador) ou console de servidor, isso será falso. commandName: O nome do comando que foi acionado. Isso é útil se vários comandos passarem por uma mesma função. Mesmo o parâmetro sendo predeterminado, você pode botar o nome que você quiser, por ex: O parâmetro de quem executou o comando é playerSource, mas você pode botar qualquer nome como: p, player, sujeito, shuppinga e etc.... da mesma maneira o commandName (nome do comando), você pode botar (nome_do_comando, comando). Como você prefere. (mas é claro, siga um padrão a qual os outros programadores possam entender seu código !!) _____________________________________________________________ Mas quando devo usar source então? Simples, quando não existe o parâmetro que indique o sujeito. Por exemplo, o evento onPlayerWasted. O evento onPlayerWasted tem o seguintes parâmetros: totalAmmo - A munição total que a vitima tinha quando morreu, killer - O assassino que matou a vitima, killerWeapon - O id da arma do assassino, bodyPart - A parte do corpo da vítima que foi atingida quando ela morreu, stealth - Um valor booleano representando se esta foi ou não uma morte furtiva. Note que não existe o parâmetro vítima. Então aqui que entra o source. Mas como saber o que é o source? A própria wiki diz, basta ler A source deste evento é o jogador que morreu ou foi morto. Então o tutorial fica por aqui :), bye bye. (lembrando que essas fontes são próprias, então pode ser um conteúdo incorreto, mas espero ter ajudado a tirar a dúvida, lembrando que ela pode ser corrigida por alguém de bom conhecimento sobre do conteúdo.)
    1 point
  8. Fala, galera. Pra quem sempre quis saber como escrever os próprios scripts para MTA, mas nunca conseguiu se organizar para começar, eu trago a solução. Estou construindo uma playlist de vídeos relacionados a script para MTA. O foco principal é ensinar a API do MTA e não necessariamente programação em Lua, portanto, para aqueles que desejam acompanhar melhor é recomendado que já saiba programar em Lua. Por outro lado, não sinta-se incapaz de seguir a playlist mesmo não sabendo Lua. Você pode tentar entrar de cabeça, sem ter esse background muito sólido. Vai ser mais difícil, mas não é impossível. Eu já vi alguns gringos fazendo um post numa espécie de thread para seus próprios vídeos, mas não sei se é contra as regras. Se for, desculpe. Eu vou ir mantendo o vídeo mais atualizado no topo. Mas a playlist pode ser conferida aqui. MTA SCRIPT #22: Sistema de Exports MTA SCRIPT #21: Introdução à tabelas e OOP MTA SCRIPT #20: DX Scripting - Exibindo imagens na tela MTA SCRIPT #19: DX Scripting - Animações com InterpolateBetween MTA SCRIPT #18: DX Scripting - OnClientCursorMove MTA SCRIPT #17: DX Scripting - OnClientClick MTA SCRIPT #16: DX Scripting - Posição e Escala pt.2 MTA SCRIPT #15: DX Scripting - Posição e Escala pt.1 MTA SCRIPT #14: DX Scripting - Introdução MTA SCRIPT #13: Solucionando problemas de código MTA SCRIPT #12: Controle de Acesso (ACL) MTA SCRIPT #11: Pickups MTA SCRIPT #10: Markers MTA SCRIPT #09: Bind de teclas MTA SCRIPT #08: Manipulando eventos pt.2 MTA SCRIPT #07: Manipulando eventos pt.1 MTA SCRIPT #06: Variáveis globais predefinidas e Árvore de elementos MTA SCRIPT #05: Introdução aos comandos MTA SCRIPT #04: Script de Cliente x Servidor x Compartilhado MTA SCRIPT #03: Escrevendo seu primeiro resource MTA SCRIPT #02: Administrando o servidor MTA SCRIPT #01: Preparando o ambiente
    1 point
  9. O que é? Pra que serve? Um banco de dados é onde ficam salvos diversos tipos de dados que são usados entre as sessões dos jogadores e do servidor, isto significa que mesmo se o jogador relogar no servidor ou até mesmo o servidor reiniciar, os dados salvos no banco de dados não são perdidos. (se o script que salvou lá foi feito corretamente). O que posso salvar neles? O MTA já cria 2 bancos de dados padrão quando vc cria seu servidor, são eles: internal.db - Onde são salvos todos os dados das contas dos jogadores, login, senha, grana do bolso, posição do jogador quando deslogou, vida, colete, skin, armas, munição, etc. registry.db - Onde são salvos todos os dados que são utilizados pelos resources, como por exemplo melhores pontuações das corridas (race gamemode), proprietários das casas, dados bancários dos jogadores, saldo bancário dos jogadores, carros comprados pelos jogadores, roupas compradas pelos jogadores, empresas adquiridas pelos jogadores, etc. Onde eles estão? Estes dois bancos de dados estão na pasta deathmatch do seu servidor, estão na linguagem SQLite. Você ainda pode criar outros bancos de dados externos, para serem usados pelos resources, mas na minha opinião isso não é recomendável, uma vez que vc usaria MySQL, que é mais complexo e exige certos cuidados de acesso e domínio, mas alguns servidores profissionais precisam fazer assim pois fizeram os bancos de dados ficarem fora do servidor em outro IP por segurança, dai é necessário ter bancos de dados externos. Nesse tutorial vamos tratar somente dos bancos de dados nativos do MTA, por serem mais fáceis de entender. Como mexo neles? Para salvar alguma coisa na conta do jogador, isto é, no internal.db, você usa setAccountData, e para obter esses dados depois, use getAccountData. É extremamente simples, funciona da mesma forma que um setElementData, mas em vez de salvar uma data temporária em um elemento, salva uma data permanente numa conta. Porém, para salvar alguma coisa no registry.db, é um pouco mais complicado, uma vez que vc vai precisar criar uma tabela nova para cada resource. Por exemplo, vc acabou de criar um resource de ranking por kills/deaths e você deseja salvar esse ranking no banco de dados para que ao reiniciar o resource ou o servidor, o ranking não seja perdido. Para isso vc vai precisar primeiramente criar uma tabela no banco de dados registry.db, essa tabela será acessada pelo resource, que irá salvar os dados dele lá. Para fazer qualquer coisa neste banco de dados (criar tabelas, inserir, alterar, remover, deletar, inserir colunas em determinada tabela, etc) vc vai precisar usar isso: executeSQLQuery. Aqui, será necessário conhecimento em SQL para fazer isso, mas é mais fácil do que aprender uma linguagem de programação nova, pois suas opções e sintaxes são menores do que uma linguagem inteira de programação, você não vai inventar nenhum sistema novo aqui, apenas criar e gerenciar tabelas e dados. Criar tabela nova no banco de dados: (o Caps Lock não é uma regra, mas é melhor para entender o que é código e o que é nome) [Os seguintes códigos só funcionam server-side] executeSQLQuery ("CREATE TABLE IF NOT EXISTS nomedatabela (nomecoluna1 TEXT, nomecoluna2 REAL, nomecoluna3 INTEGER)") TEXT = Valores desta coluna serão textos. Podem ter símbolos, números e espaços. REAL = Valores desta coluna serão numéricos reais. (números decimais, positivos, negativos e 0.0) INTEGER = Valores desta coluna serão numéricos inteiros. (positivos, negativos e 0) (não existe tipo BOOLEAN, use TEXT e insira valor "false" ou "true") (existe valor NULL, é diferente de vazio e diferente de 0. NULL significa ausência de dados. O NULL aparece quando você cria uma linha ou coluna nova sem atribuir valores a elas.) Deletar tabela do banco de dados: executeSQLQuery ("DROP TABLE nomedatabela") Todas as linhas, colunas, células e valores desta tabela são deletados junto. Deletar linhas da tabela: (as células não ficarão NULL) executeSQLQuery ("DELETE FROM nomedatabela WHERE colunaespecífica=?", valorDaCelulaEspecifica) O ? indica que o valor está após a declaração do SQL. Você poderia colocar o valor direto no lugar do ?. Mas por alguma razão, as vezes isso gera erro. Além disso, se o valor da célula estiver em uma variável no seu script, você não pode declarar a variável no lugar do ?. Ali só pode ser o valor direto, pois a declaração SQL inteira se trata de uma string. Por isso o uso do ?, que está recebendo o valor da variável que está depois da vírgula. Obs: Para verificar se uma célula tem valor nulo, não se usa os operadores lógicos de ==, <= >=. Para isso, usa-se IS NULL ou IS NOT NULL. Ex: executeSQLQuery ("DELETE nomecoluna1,nomecoluna2 FROM nomedatabela WHERE nomecoluna3 IS NULL") Isso vai deletar todas as células da coluna 1 e coluna 2 onde a coluna 3 tem uma célula de valor NULL. Se a coluna 3 não tiver nenhuma célula de valor NULL, nada acontece. Inserir nova linha de valores: (ele vai criar automaticamente uma nova linha com novas células) executeSQLQuery ("INSERT INTO nomedatabela(nomecoluna1,nomecoluna2,nomecoluna3) VALUES(?,?,?)", valorCelulaColuna1, valorCelulaColuna2, valorCelulaColuna3) Neste caso, ele está inserindo 3 novos valores, cada valor em uma coluna. Se você não declarar os nomes das colunas, ele vai preencher na ordem das colunas automaticamente. Você pode deixar de declarar uma coluna se não quiser atribuir valor na célula daquela coluna. Se o tipo de valor da variável não for do tipo de dado daquela coluna, dará erro. Atualizar valores de células que já existem em uma tabela: (não é possível alterar os tipos de valores, é necessário editar o tipo da coluna se quiser fazer isso) executeSQLQuery ("UPDATE nomedatabela SET nomecoluna2=?,nomecoluna3=? WHERE nomecoluna1=?", valorCelulaColuna2, valorCelulaColuna3, valorCelulaColuna1) No caso acima, ele vai atualizar as células das colunas 2 e 3 onde o valor da célula da coluna 1 for igual ao valor de valorColunaCelula1. OBS: Nada impede que você coloque as primeiras variáveis junto à declaração SQL, mas para fazer isso você deve "cortar" a string, inserir as variáveis e depois continuar a string, Ex: executeSQLQuery ("UPDATE nomedatabela SET nomecoluna2= '".. valorCelulaColuna2 .."',nomecoluna3='".. valorCelulaColuna2 .."' WHERE nomecoluna1=?", valorCelulaColuna1) Lembrando que o valor destas variáveis também são strings na declaração, portanto use aspas simples antes e depois de cada corte para transformar os valores em string. Os dois pontos (..) significam que estes valores fazem parte do argumento SQL. Da mesma forma, se vc usar "1" .. "1", será igual a "11". (Por isso acho muito mais fácil deixar tudo ? na declaração SQL e colocar as variáveis todas após a string.) Selecionar determinadas células da tabela: (usado geralmente para obter os valores destas células para usar no script, você pode selecionar somente 1 célula ou várias) executeSQLQuery ("SELECT nomecoluna1,nomecoluna2 FROM nomedatabela WHERE nomecoluna3=?", valorCelulaColuna3) Neste exemplo, ele vai selecionar a célula da coluna 1 e a célula da coluna 2, na linha onde a célula da coluna 3 for igual a valorCelulaColuna3. Alterar a tabela (adicionar coluna nova) [SQLite não suporta deletar coluna nem editar tipo de coluna] executeSQLQuery ("ALTER TABLE nomedatabela ADD nomecoluna4 REAL") Devido a limitações do SQLite, ALTER TABLE não pode ser usado para deletar uma coluna nem para editar seu tipo. Para fazer isso é necessário recriar a tabela inteira com as novas alterações. No exemplo acima, ele vai adicionar uma nova coluna chamada "nomecoluna4". Tá, mas como ficaria tudo isso dentro de um script? Fiz um código com vários testes de banco de dados. Cada comando faz alguma coisa. É possível mexer em um banco de dados manualmente sem usar scripts? Sim, é possível. Eu mesmo costumo fazer isso para corrigir algumas coisas rápidas sem precisar programar mais nada. Para poder abrir os bancos de dados (internal.db e registry.db) você deve usar um programa chamado DB Browser for SQLite. Um programa gratuito, leve e bem fácil de entender. Nele você consegue acessar todas as tabelas do banco de dados e editar os valores como se fosse em uma planilha do Excel. Basta ir na aba Navegar dados, selecionar a tabela que deseja modificar, clicar em cima da célula cujo valor deseja atualizar, digitar o novo valor, clicar em Aplicar e depois clicar em Escrever modificações (salvar banco de dados). Pronto! E tem mais! Se você já tiver conhecimento avançado com a linguagem SQL, você também pode fazer alterações avançadas via código dentro do programa. Basta acessar a aba Executar SQL, escrever o comando SQL corretamente e depois clicar no botão de Play. Espero ter ajudado.
    1 point
  10. Na verdade é bem simples por meio de código. Vc só precisa saber o ID do objeto e informar uma coordenada bem próxima ao objeto, não precisa ser exatamente no centro do objeto. Para descobrir o ID de um objeto que não é selecionável, dai é algo mais complexo que exige ferramentas externas. Para isso, vamos no site http://dev.prineside.com e clicamos no botão Model Search by Map Position. Após selecionada a posição no mapa, ele vai mostrar todos os objetos (selecionáveis e não selecionáveis) em um raio de 500 metros, em ordem dos mais próximos para os mais distantes. Na lista que aparecer, encontre o objeto que você deseja remover e anote o ID desse objeto. Descobrimos o ID do objeto, e agora? Agora já passou a parte mais difícil, o resto é programar um script básico de remoção de objetos por ID. Para isso vamos usar a função RemoveWorldModel. Essa função é bem simples de se usar, basta informar o ID do objeto a ser removido, o raio cuja remoção será aplicada e as coordenadas do ponto onde vai começar a remoção. Você precisa restaurar o objeto quando o script for desligado, para isso use RestoreWorldModel. O script funciona tanto em server-side quanto em client-side, mas em geral utiliza-se server-side. O Script deve ficar como esse: function removeBagulho() removeWorldModel(5681, 15, 1911.3, -1776.25, 13.38) -- Remove o objeto do lava-jato próximo ao posto de LS quando o resource é iniciado. end addEventHandler("onResourceStart", resourceRoot, removeBagulho) function restauraBagulho() restoreWorldModel(5681, 15, 1911.3, -1776.25, 13.38) -- Restaura o objeto quando o resource é desativado. end addEventHandler("onResourceStop", resourceRoot, restauraBagulho) Esse script vc adiciona junto com o resource do seu mapa. Você pode optar por deixar isso em um script separado ou deixar junto com algum script que vc já tenha no seu mapa por exemplo scripts de portões, server-side. Vlw, flw. Deixe seu LIKE se ajudou você. Dúvidas comente abaixo. Obs: Nem todos os objetos podem ser removidos com essa função, por exemplo aquelas plantas do deserto que se você bater com veículo elas podem quebrar. Isso ocorre pois elas são geradas no mapa, não possuem posição fixa. Outras plantas geradas também não podem ser removidas, mesmo se forem selecionáveis. Tanto que se você tentar procurar o ID dessas árvores seguindo os passos acima, vai perceber que o site não encontra essas árvores na pesquisa do mapa. Para remover essas plantas, utilize isso: setWorldSpecialPropertyEnabled("randomfoliage", false)
    1 point
  11. Introduction Properly handling your user's credentials (username and password) is very important, this guide gives detailed information and code samples on how to (properly) implement an account "system". This guide assumes you are not using MTA's built in accounts. Disclaimer: Any code shown in this tutorial is purely for illustrative purposes, and is not finished code, you should use it as a guideline, not a solution. Content The following topics will be discussed in this tutorial: How to hash and salt passwords (register) How to validate a hashed password (login) How to add "remember-me" functionality How to offer password recovery How to migrate from an older hashing algorithm, to a newer one Using a password policy (Extra) How to handle database leaks (Extra) What even is hashing and salting? For the purpose of this tutorial we expect a database structure which is somewhat similar to this: How to hash and salt passwords When you have a user register on your service, that user expects of you to keep their password safe. Whilst it is generally bad practice to use the same password for multiple services there are many users that still do so. Because of this it's crucial that you save the user's passwords in a way that an attacker will be unable to find out the original password the user typed. This includes if they have full access to your database. In order to do this we do what is called "Password hashing" When a user registers, your server receives the user's intended username, (email) and password. Before you save that password to the database you have to hash and salt this, luckily MTA has a function that takes care of this. If you wish to know more about what exactly it does, there's more information at the end of this tutorial. In order to hash this password you use the passwordHash function. This function is relatively slow (by design), so it is highly recommended you pass a callback to this function, so your entire script doesn't wait for it to complete. https://wiki.multitheftauto.com/wiki/PasswordHash local mysqlHandle -- we're assuming this value is set somewhere else in code function register(username, email, password) local player = client passwordHash(password, "bcrypt", {}, function(hashedPassword) -- callback function for hashing the password local handle = dbQuery(function(handle) -- callback function for storing the user in the database if (handle) then triggerClientEvent(player, "registrationSuccess") -- inform the user that registration was successful else triggerClientEvent(player, "registrationFailed") end end,mysqlHandle, "INSERT INTO users (email, username, password) VALUES (?, ?, ?)", email, username, hashedPassword) end) end addEvent("passwordTutorial:register", true) addEventHandler("passwordTutorial:register", getRootElement(), register) How to validate a hashed password Once you've saved the hashed password to your database you need to do a little bit of additional work when authenticating the user. Luckily MTA offers a passwordVerify() function, which is the counterpart of the previously discussed passwordHash(). What this function does it basically hashes the password in the same way, resulting in the same output hash. https://wiki.multitheftauto.com/wiki/passwordVerify In order to get the account the user is trying to log in to you have to do a query for an account which has the user submitted username, and of which the password matches through passwordVerify. PasswordVerify is also a relatively slow function, thus you should use a callback. function login(username, password) local player = client dbQuery(function (handle) -- callback for the query selecting the user by username local results = dbPoll(handle, -1) if (#results == 0) then triggerClientEvent(player, "loginFailed") return end passwordVerify(password, results[1].password, {}, function(matches) -- callback function for the password verify if (matches) then -- Do anything you wish with the database result to log the player in with the rest of your scripts triggerClientEvent(player, "loginSuccess") else triggerClientEvent(player, "loginFailed") end end) end, mysqlHandle, "SELECT * FROM users WHERE username = ?", username) end addEvent("passwordTutorial:login", true) addEventHandler("passwordTutorial:login", getRootElement(), login) How to add "remember me" functionality When users on your server log in, they often do not want to have to enter their username and password every time they want to log in. In order to satisfy this need you can implement a "remember me" function. What I've seen happen in the past, is people would store the user's password (encrypted) on the client. This is NOT safe, and should never be done! In order to properly use remember me functionality what you would do is upon login in, generate a random string. The longer the better. This random string is what we call an access token. You would then allow the user to log in with such an access token, preferably only once generating a new access token each time one is used. To implement this you would generate that token every time the user logs in, whilst they have "remember me" enabled. You will have to save this token in your database alongside your user. For extra security you could also store the user's serial alongside the access token, you can then validate that the access token is being used from the same device. https://wiki.multitheftauto.com/wiki/Filepath function login(username, password) -- This code should be put in the callback to the dbQuery function, but to keep the example clean that's not shown here if (rememberMe) then local token = generateRandomToken() dbQuery(mysqlHandle, "INSERT INTO access_tokens (user_id, token) VALUES (?, ?)", results[1].id, token) triggerClientEvent(player, "loginSuccess", token) end end function rememberMeLogin(username, accessToken) -- this function handles a user's login attempt dbQuery(function(handle) local result = dbPoll(handle, -1) if (#result == 0) then triggerClientEvent(player, "loginFailed") else -- Do anything you wish with the database result to log the player in with the rest of your scripts triggerClientEvent(player, "loginSuccess") end end,mysqlHandle, "SELECT users.* FROM access_tokens JOIN users ON users.id = access_tokens.user_id WHERE users.username = ?", username) end addEvent("passwordTutorial:loginRememberMe", true) addEventHandler("passwordTutorial:loginRememberMe", getRootElement(), login) How to offer password recovery Offering password recovery requires a little bit more than just your MTA server. Generally password recovery is done with emails. So you would need access to an email server / service which you can use to send an email from an HTTP request. (Like you can do with fetchRemote()). When a user requests a password reset, have them enter the email you registered with. You then fetch a user from the database with this email address. You would then store a password recovery token for this user. This token, just like the remember me token, is a random string. Ideally, you would send the user a link with a password reset form that goes to a webpage where the user can reset their password. You could do this with an external service, like a webserver. Or you could use MTA's Resource web access for it, but if you do make sure you handle permissions properly for anything else that uses this. However another option would be to have the user copy paste the generated token from the email into you server's login window. Which of the two solutions you pick is up to you, my personal preference goes to the one with the link in the email. But in either case the server side logic is the same. When the user attempts to perform password recovery, verify that the token they give you belongs to a user, and then change the password to the newly requested password. Make sure you hash this password the same way you do in your login. function requestPasswordRecovery(email) dbQuery(function (handle)) local result = dbPoll(handle, -1) if (#result == 0) then triggerClientEvent(player, "passwordTutorial:passwordRecoveryRequestFailed") else local token = generateRandomToken() dbExec(mysqlHandle, "UPDATE user_data SET recovery_token = ?", token) -- mail the token to the user, mail implementation depends on the mail server/service you use triggerClientEvent(player, "passwordTutorial:passwordRecoveryRequestSuccess") end end, mysqlHandle, "SELECT * FROM users WHERE email = ?", email) end function recoverPassword(recoveryToken, password) dbQuery(function (handle) local result = dbPoll(handle, -1) if (#result == 0) then -- this is only valid if you have the user request password recovery from ingame triggerClientEvent(player, "passwordTutorial:passwordRecoveryFailed") else passwordHash(password, "bcrypt", {}, function(hashedPassword) -- callback function for hashing the password local handle = dbExec(function(handle) -- callback function for storing the new password in the database if (handle) then -- this is only valid if you have the user request password recovery from ingame triggerClientEvent(player, "passwordTutorial:passwordRecoverySuccess") -- inform the user that registration was successful else -- this is only valid if you have the user request password recovery from ingame triggerClientEvent(player, "passwordTutorial:passwordRecoveryFailed") end end,mysqlHandle, "UPDATE user_data SET password = ? WHERE recovery_token = ?", username, recoveryToken) end) end end, "SELECT * FROM users WHERE recovery_token = ?", recoveryToken) end Besides changing the password, it's important you also delete any access tokens that user might have if you're using remember me functionality. It is also good practice to make recovery tokens expiry after a certain amount of times, and not allow a recovery token to be created whilst one is already in progress. This prevents a user from sending a large number of emails from your service. How to migrate from an older hashing algorithm, to a newer one Maybe after reading this topic you realise that your password security is not what it should be. So you want to change your old password hashing / validation logic to the ones explained in this topic. And due to the nature that hashes can not be "unhashed", you can't simply migrate your passwords over. So in order to migrate the passwords what you have to do is when a user logs in, first validate their password with the old hashing algorithm. If this matches, then hash (and salt) it with your new hashing algorithm and save it in your database. Make sure to delete the old password otherwise your password security is not any better than before. Using a password policy Passwords policies are important to prevent your users from picking a password that is too easily cracked / brute forced. Many password policies come in the form of "Must have at least one capital letter, one digit and one number". But that discards that fact that the best way to make your password more difficult to crack, is making your password longer. So in the code snippet below is a function that measures the 'search space' of a password. The search space of a password is the amount of possible passwords there are with a certain combination of characters. In order to use this, you would have to set a minimum password search space when a user registers for an account. This minimum is up for you to set, but be reasonable, you shouldn't expect a user's password to be impossible to remember / create. I recommend playing with the function a bit to see what values you get out of it, and pick something you believe is sensible. function getPasswordSearchSpace(password) local lowerCase = password:find("%l") and 26 or 0 local upperCase = password:find("%u") and 26 or 0 local digits = password:find("%d") and 10 or 0 local symbols = password:find("%W") and 32 or 0 local length = password:len() return (lowerCase + upperCase + digits + symbols) ^ length end -- The below function calls are to indicate the difference in search space for a set of passwords print(getPasswordSearchSpace("a")) print(getPasswordSearchSpace("abc")) print(getPasswordSearchSpace("Abc")) print(getPasswordSearchSpace("Ab!")) print(getPasswordSearchSpace("Ab!0")) print(getPasswordSearchSpace("Mu#9A0h.")) print(getPasswordSearchSpace("This is a demonstration of how easy an incredibly strong password is to remember")) How to handle database leaks If you have reason to believe that your database has been leaked or otherwise compromised, it is important that your first course of action is removing any access tokens stored in your database. Once you have done that you have to inform your users. Whilst when properly hashed and salted it's extremely difficult / time consuming to find out a user's password it is still a possibility. So you should inform your users of the breach, tell them that their passwords were properly hashed, and they do not need to fear for their passwords immediately. However you should suggest to your users that they change their password either way, just in case. What even is hashing and salting? Hashing has been brought up several times in this tutorial, whilst you do not need to know what it is / does, you might be interested in knowing regardless. I won't be going too far in depth as I simply do not have the knowledge, but the basic idea of hashing is this: When you hash anything, you turn it into a string of characters (or other value) that has no relation to the original input, other than when you hash the original input again, it will always generate the same hash. For example, when you hash the string 'banana' using the sha512 hashing algorithm, it will always yield the output: "F8E3183D38E6C51889582CB260AB825252F395B4AC8FB0E6B13E9A71F7C10A80D5301E4A949F2783CB0C20205F1D850F87045F4420AD2271C8FD5F0CD8944BE3" Now hashing can not be reverted, you can not "unhash" a hash, so in order to verify someone's password you hash it again, and see if the two hashes are the exact same. Now this is great, passwords are safely stored. However there is still more to do, salting. Salting is adding some random data to your password prior to hashing it. This prevents when two users (on the same service, or on others) have the same password, that their hashes are also the same. Meaning if one password is compromised, the other password is not. It is important that a salt is random for every user in your application, not one salt for your entire application. Now you might think we didn't do any salting in the code / tutorial above. This is not true, we just didn't do it ourselves. MTA's passwordHash function actually hashes the passwords and salts it, this salt is then stored in the output hash it self, just before the actual password hash. In the case of bcrypt it actually stores a little bit more info in the resulting hash, but you need not worry about that.
    1 point
  12. Você vai usar apenas GetPedOccupiedVehicle junto com uma verificação. Exemplo: function Radar () local Veh = getPedOccupiedVehicle ( localPlayer ) if Veh then dxDrawRectangle(x, y, x, y, tocolor(255,255,255,255), false) end end addEventHandler("onClientRender", root, Radar)
    1 point
  13. em lua todo if tem um then e um end para limitar o corpo da função, eu tenho uns tutorias de lua no youtube se achar necessario pode ve-los e tambem uma pequena série sobre mta sa.
    1 point
×
×
  • Create New...