Sim, é o famoso banco de dados. Neste tutorial, eu vou abordar o uso do MySQL focado no MTA. Mas é claro que você pode estudar e expandir para outras áreas sem problema algum.
É onde seus dados roubados ficam guardados — brincadeira. Resumidamente, é onde os dados ficam guardados. Tá, mas... que dados são esses? Eles podem ser qualquer coisa, desde textos, imagens, áudios, IDs, nome de usuário, senhas, tabelas JSON, números, data de criação e por aí vai.
Com esses dados que estão guardados nós podemos formar uma informação.
É muito simples! Tudo o que você precisa fazer é instalar um servidor MySQL na sua torradeira, mais conhecido como seu computador. Também, para simplificar a visualização dos dados, nós precisaremos de um programa para isso.
Você deve instalar esse programa no seu computador, ele será responsável por gerir toda a conexão MySQL.
Link para baixar: https://www.apachefriends.org/pt_br/index.html
Particularmente eu amo esse programa, então irei usá-lo nesse tutorial. Existem outras soluções como phpMyAdmin e MySQL Workbench. Mas, sinceramente, o Beekeeper Studio funciona muito bem — sem contar que ele é feito em JavaScript, usando Electron, isto é, super leve.
Link para baixar: https://github.com/beekeeper-studio/beekeeper-studio/releases
Nota: o download é feito através do GitHub pois essa é a versão gratuita e de código aberta feita pela comunidade. Existe a versão paga, mas convenhamos: ninguém merece. Lembre-se de baixar a versão e instalador correto. Ele tem este nome: Beekeeper-Studio-Setup-3.8.9.exe
Eles não precisam de uma configuração prévia. É simplesmente instalar, abrir e começar a usar. De qualquer forma, se isso ainda não é claro, não tem problema, vamos passo a passo.
Uma vez que você instalou o XAMPP, abra-o. Pode ser que ele não crie um atalho na área de trabalho, mas você pode apertar o botão do Windows e pesquisar por XAMPP. Recomendo que abra como administrador.
Com ele aberto, veremos esta tela:
Não se preocupe se aquele "X" vermelho estiver em todos no seu. Quando eu instalo, prefiro deixar só o necessário. De qualquer forma, não é nada que irá atrapalhar o andamento do tutorial.
Agora nós já podemos iniciar o servidor MySQL, clicando no botão "Start". Ele ficará assim:
Pronto! Nosso servidor está instalado e rodando.
Por favor, abra o programa. Com ele aberto, nós veremos uma tela deste jeito:
Não tem muito segredo. Vamos nos conectar ao servidor MySQL, dessa forma iremos ver tudo o que acontece em nosso banco de dados.
Clique em Select a connection type
Selecione a opção MySQL. Nós daremos de cara com alguns campos para preencher. Não se preocupe. É bem fácil!
No campo Host, iremos colocar localhost. No campo User, iremos colocar root.
Pronto! Com esses dois campos preenchidos, clique no botão "Connect". Se tudo estiver correto, esta tela irá aparecer:
Daqui, já podemos gerenciar os bancos de dados e tabelas. Eu vou facilitar algumas coisas, pois pode ser a primeira vez de alguém entrando em contato com essa interface.
Aqui fica o local onde você irá selecionar o banco de dados para visualizar as tabelas, registros e outros.
Uma vez que você clica ali, será listado todos os banco de dados criados. Existem alguns que vêm como padrão, criados pelo próprio XAMPP.
Temos também a área onde iremos digitar alguns comandos.
Por enquanto, é apenas isso que você deve saber. Vamos começar!
Existem algumas formas de criar um banco de dados, irei mostrar a forma que eu recomendo. É super simples e fácil.
Naquele campo onde usaremos para digitar comandos, iremos digitar o seguinte:
CREATE DATABASE `db_test` CHARACTER SET `utf8` COLLATE `utf8_general_ci`;
Oh, meu deus! O que é isso? Nossa! Mas o que é tudo isso? Me ajuda, me ajuda, por favor!
Relaxe. Não é nada demais. O nosso primeiro comando, então, é o CREATE. Geralmente ele é usado para criar banco de dados e tabelas.
CHARACTER SET serve para definirmos qual será a codificação de todos os dados dentro das tabelas. Recomendo sempre usar utf8, pois engloba todos os caracteres, sem possibilidades de causar um bug.
COLLATE também serve para definir a codificação, mas existem várias, você pode pesquisar a fim de estudar. Usaremos utf8_general_ci.
Abrindo a lista de bancos de dados, ele deve estar ali.
Selecione-o. É importante SEMPRE ter o seu banco de dados selecionado. Caso isso não aconteça, os comandos digitados não irão funcionar.
Agora que criamos o banco de dados e estamos com ele selecionado, vamos criar uma tabela para armazenar alguns dados.
Apague o comando anterior e digite este:
CREATE TABLE IF NOT EXISTS `products` (
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(128) NOT NULL,
`price` INT NOT NULL
);
Calma! Não entre em pânico. Irei explicar algumas coisas sobre o comando acima.
Antes disso, você percebeu que eu usei crase (`) encapsulando o nome? Então, isso é de suma importância para os nomes que damos, informando ao servidor MySQL que aquilo NÃO É UM COMANDO, mas sim o nome de alguma coisa. Não usar aquilo pode ocasionar alguns erros.
Notasse que há "IF NOT EXISTS", ou seja, a tabela só será criado caso ela não exista. É recomendável que use dessa maneira para evitar que os dados sejam apagados.
Dando continuidade. Quando temos uma tabela, nela existem duas coisas: colunas e entradas.
Colunas - são identificadores. Simples assim. Se nós quisermos o nome de um produto, iremos buscar pela coluna name, nesse caso.
Entradas - onde os dados ficarão salvos. Cada entrada no banco de dados é diferente, podendo conter outros nomes. Por exemplo, inseri um dado na tabela e, na coluna name coloquei PlayStation 4; quando eu for inserir novamente, posso colocar Samsung Galaxy S23. Teoricamente, nossa tabela agora tem dois produtos.
Em toda tabela que você criar, SEMPRE adicione a chave id daquela forma. Citarei aqui novamente:
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
Toda tabela deve ter esse campo, ele que irá ser referência para uma outra tabela ou em criações de chaves estrangeiras. Não iremos abordar esse tema neste tutorial. De qualquer forma, crie!
Existem alguns tipos de dados, sendo eles:
VARCHAR
INT
JSON
TEXT
BIGINT
TINYINT
BOOLEAN
TIMESTAMP
BLOB
Usaremos apenas alguns, mas vale o estudo em relação aos outros tipos.
Esse comando irá dizer para a tabela que não irá aceitar uma inserção sem um valor.
Esse comando irá dizer para a tabela que o ID será adicionado de forma automática assim que uma nova entrada for criada.
Enfim, caso você tenha criado corretamente, a tabela irá aparecer ali no canto. Ficará desta forma:
Para isso, usaremos um outro comando, que é o INSERT. Ele é bem simples também. Apague o comando anterior. Copie, cole e execute este:
INSERT INTO `products` (`name`, `price`) VALUES ('Computador Super Gamer', 15999);
Mesmo você não visualizando, se tudo estiver correto, nós temos agora uma entrada no banco de dados — e não é calvice. Brincadeira.
Primeiramente, vamos focar em entender como esse comando funciona. Começando pelo:
INSERT INTO - pode ser traduzido para "INSIRA DENTRO DE". Após digitar isso, nós precisamos indicar em qual tabela os dados serão inseridos. Em nosso exemplo, queremos que insira os dados na tabela "products".
Depois disso, nós temos que abrir parênteses () e definir as colunas. Aqui vamos inserir um nome e um preço.
VALUES - é onde ficará os valores, de acordo com o nome das colunas. Por exemplo, nós indicamos que iremos inserir os seguintes dados: nome e preço (name
, price
) — sendo assim, o primeiro dado a vir dentro de VALUES deve ser o nome do produto. Respectivamente, o preço.
O jeito que iremos inserir nos exemplos futuros de MTA será diferente. Por enquanto, vamos focar como as coisas estão no momento.
Lembre-se de usar crase (`) para indicar que estamos falando sobre o nome da coluna. Perceba que não tem crase (`) nos valores que estamos inserindo, pois eles são, como o nome diz, valores que ficarão armazenados.
Hum... começando a ficar um pouquinho complexo. Mas você vai entender fácil.
Usaremos agora o comando SELECT. Digamos que nós queremos obter todos os dados da tabela, de todas as colunas. O comando para isso é:
SELECT * FROM `products`;
Observação: Já que chegamos aqui, vou aproveitar pra falar uma coisa: sempre que for executar um novo comando, apague o anterior. É sim possível ter múltiplos comandos naquela área, mas pelo tutorial, faça dessa forma.
Com o comando executado, se tudo estiver correto, você verá os dados que inserimos anteriormente:
Vamos adicionar mais um produto. Você fará isso sozinho. Depois de adicionado, execute novamente o comando. O seu estará assim:
Não liga para o ID 3 ali, eu errei uma coisa aqui e tive que deletar a outra entrada. Não se preocupe. O seu deve estar 1 e 2.
Certo. Agora você deve estar se perguntando: tá, mas como eu faria para obter os dados de uma entrada específica?
O comando segue sendo o mesmo, mas agora nós iremos especificar qual nós queremos. Use o seguinte comando:
SELECT * FROM `products` WHERE `id` = 1;
Se tudo estiver correto, deve retornar apenas aquela entrada que tem o ID de número 1:
WHERE - é como se fosse um if que usamos na programação. Nós também podemos passar mais coisas além disso. Vejamos:
SELECT * FROM `products` WHERE `price` >= 5000;
O comando acima irá buscar somente pelos produtos que têm o preço maior ou igual a 5 mil reais.
Suponhamos que temos uma coluna com o nome de brand (que é marca de alguma coisa, em Inglês)
Nós podemos buscar somente produtos daquela marca e que tenha o preço maior ou igual que, por exemplo, 2 mil reais. Ficando assim:
SELECT * FROM `products` WHERE `price` >= 2000 AND `brand` = 'Samsung';
Nota: O comando acima não é passível de ser executado, mas como exercício, você pode criar a tabela novamente com essa coluna.
Também é algo simples. Usaremos o comando UPDATE. Dê uma olhada no comando abaixo:
UPDATE `products` SET `price` = 12500 WHERE `id` = 1;
O que o comando está querendo dar a entender é o seguinte: atualize o banco de dados products, alterando as seguintes colunas se alguma coisa for especificada.
Uma observação extremamente importante: Jamais deixe de usar o comando WHERE juntamente com UPDATE. Caso contrário, todos os dados serão substituídos e, dessa forma, perdidos. Sempre que for atualizar alguma coisa, lembre-se que essa coisa será atualizada para somente uma entrada.
Tente pensar da seguinte forma: se o preço do Computador Super Gamer alterou, então eu preciso especificar que o preço DELE mudou. Os outros produtos continuarão com o mesmo preço, a menos que eles também tenham o preço reduzido ou aumentado. Mas, novamente, especificamente cada um deles, em um comando diferente.
Nota: Também podemos usar o comando AND, caso seja necessário. Há cenários em que precisaremos, mas não aconteceu aqui, pois temos uma tabela simples.
Para remover entradas, nós usamos o comando DELETE. Ele é parecido com o comando UPDATE, sendo necessário SEMPRE o uso do WHERE para especificar qual entrada deve ser excluída.
Usaremos o seguinte comando para deletar o nosso Computador, que tem o ID 1:
DELETE FROM `products` WHERE `id` = 1;
Após executar o comando e fazendo uma busca, você irá perceber que não tem mais. Assim está o meu:
Para isso, nós usamos o comando TRUNCATE. Ele remove todas as entradas, ou seja, limpa completamente a tabela especificada. Segue o exemplo:
TRUNCATE `products`;
Faça uma busca e verá que não há mais nenhum dado.
Trabalhar com banco de dados de forma simples é bem fácil, com o tempo, praticando, você consegue criar comandos mais complexos.
Lembre-se:
Para usarmos um banco de dados dentro do MTA, temos duas opções:
- MySQL (Conexão, salvo na nuvem)
- SQLite (Arquivo, salvo em disco, localmente)
Independente do modo que você irá usar, é quase sempre a mesma coisa. Quase sempre pois cada banco de dados pode ter um motor (engine) diferente. Não é uma grande diferença, porém alguns comandos podem ser diferentes.
Neste tutorial, usaremos MySQL. Mas... tenho uma surpresa no final!
Precisamos da função dbConnect e também especificar de qual modo usaremos, junto com as informações de conexão, como: host (IP/DNS), usuário, senha (caso haja) e o nome do banco de dados.
Agora, crie uma pasta dentro de resources, lá do seu servidor MTA. Eu vou colocar como dbtut.
Feito isso, crie um arquivo meta.xml com o seguinte conteúdo, apenas para carregar nosso resource:
<meta>
<script src="database.lua" type="server" />
<export function="getConnection" type="server" />
</meta>
Agora, iremos criar também o arquivo database.lua, com o seguinte conteúdo:
local connectionInfo = {
db_name = "db_test", -- Mesmo nome do banco de dados que criamos.
host = "localhost",
username = "root",
password = '' -- Aqui deixaremos vazio, já que o nosso banco de dados não possui um senha.
}
local databaseConnection -- Variável onde a conexão ficará armazenada
function getConnection() -- Função que iremos exportar para retornar a conexão, sendo assim poderemos usar fora daqui.
return databaseConnection
end
addEventHandler("onResourceStart", resourceRoot,
function()
databaseConnection = dbConnect("mysql", "dbname=" .. connectionInfo.db_name .. ";host=" .. connectionInfo.host, connectionInfo.username, connectionInfo.password)
-- Checando se a conexão foi estabelecida.
if databaseConnection then
print("Conexão com o banco de dados estabelecida!")
else
print("Infelizmente a conexão não pôde ser estabelecida.")
end
end
)
Inicie o resource em seu servidor. Se tudo estiver correto, poderemos continuar com o tutorial.
Agora que nós temos o resource rodando e com o banco de dados iniciado. Criaremos um outro resource e trabalharemos lá.
Crie uma pasta com outro nome, eu vou deixar como tut_markers, só para fins de estudo.
Use este meta.xml:
<meta>
<script src="script.lua" type="server" />
</meta>
Crie um arquivo com o nome script.lua e vamos continuar.
Agora, dentro do arquivo script.lua, vamos adicionar um evento para quando o resource iniciar ele então criar a nossa tabela.
local markers = {}
local lastId
addEventHandler("onResourceStart", resourceRoot,
function()
local db = exports.dbtut:getConnection() -- Iremos obter a conexão.
if not db then -- Caso não haja a conexão, iremos informar através de um `print` que o banco de dados está off-line.
return print("Banco de dados off-line. Impossível continuar.")
end
-- Se tudo estiver correto, vamos criar a tabela. Nós usamos a função `dbExec` (https://wiki.multitheftauto.com/wiki/DbExec)
dbExec(db, [[
CREATE TABLE IF NOT EXISTS `markers` (
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
`position` JSON NOT NULL,
`color` JSON NOT NULL,
`type` VARCHAR(16) DEFAULT 'cylinder',
`size` INT DEFAULT 1,
`creator` VARCHAR(32) DEFAULT 'server',
`created_at` BIGINT NOT NULL
);
]])
-- Há duas maneiras de usar a função `dbQuery`
-- Irei usá-la diretamente, sem callbacks
-- Aqui nós vamos buscar todos os markers que estão salvos
-- No banco de dados e então criaremos todos eles
local queryHandler = dbQuery(db, "SELECT * FROM `markers`")
local data = dbPoll(queryHandler, -1)
-- A função `dbQuery` apenas retorna um "handler"
-- Que nós temos que organizar com a função `dbPoll`
-- Essa função (dbPoll) irá retornar uma tabela parecida com esta:
--[[
local data = {
{ id = 1, position = { posX, posY, posZ }, color = { r, g, b, a }, type = type, size = size, creator = creator, created_at = created_at },
{ id = 2, position = { posX, posY, posZ }, color = { r, g, b, a }, type = type, size = size, creator = creator, created_at = created_at },
{ id = 3, position = { posX, posY, posZ }, color = { r, g, b, a }, type = type, size = size, creator = creator, created_at = created_at },
}
]]--
lastId = 0
if #data == 0 then -- Se não tiver nada ainda, então iremos parar por aqui
return false
end
-- Se tiver entradas, iremos criar
for k = 1, #data do
local row = data[k]
-- Lembra que salvamos a posição e cor no banco de dados
-- Como JSON? Então, agora temos que converter novamente
-- Para a forma que o MTA reconhece
-- Usaremos a função `fromJSON` para isso
local position = fromJSON(row.position)
local color = fromJSON(row.color)
local markerType = row.type
local markerSize = row.size
local creatorName = row.creator
local createdAt = row.created_at
local marker = createMarker(position[1], position[2], position[3], markerType, markerSize, color[1], color[2], color[3], color[4])
markers[marker] = {
id = row.id,
position = position,
creator_name = creatorName,
created_at = createdAt
}
end
lastId = data[#data].id
end
)
Inicie o resource em seu servidor. Se tudo estiver certo, você terá uma nova tabela adicionada ao seu banco de dados.
Perceba que eu usei o comando DEFAULT. Isso quer dizer que, caso eu não queira definir no INSERT INTO, ele usará aquele valor como padrão.
Vamos começar a interagir com essa tabela!
Eu optei por separar cada comando, dessa forma ficará mais fácil o entendimento para aqueles que não são muito experientes com isso ainda.
addCommandHandler("create-marker",
function(player, command, markerType, markerSize)
local db = exports.dbtut:getConnection() -- Novamente obtendo a conexão.
if not db then -- Novamente checando.
return print("O banco de dados está off-line.")
end
-- Devemos nos perguntar uma coisa.
-- Quais dados são obrigatórios?
-- Nesse caso, somente a posição e a cor.
-- Porém a cor nós iremos definir uma padrão pelo código mesmo.
local posX, posY, posZ = getElementPosition(player)
posZ = posZ - 1 -- Só pra criar o marker no chão
local color = { 255, 255, 255, 255 }
-- Sim, nós definimos um valor padrão (DEFAULT)
-- No banco de dados, mas vamos aplicar aqui também
-- Só para fins de estudo
markerType = markerType or "cylinder"
markerSize = tonumber(markerSize) or 1
local creatorName = getPlayerName(player)
local createdAt = getRealTime().timestamp
-- Usaremos essa função (dbExec) para inserir coisas no banco de dados.
-- Existe a função "dbQuery" mas só usamos ela quando se trata de um SELECT.
-- Perceba que usaremos a função "toJSON"
-- Isto é, estaremos convertendo a tabela Lua para JSON
-- Pois o banco de dados não aceita uma tabela Lua
dbExec(db, "INSERT INTO `markers` (`position`, `color`, `type`, `size`, `creator`, `created_at`) VALUES (?, ?, ?, ?, ?, ?)", toJSON({ posX, posY, posZ }), toJSON(color), markerType, markerSize, creatorName, createdAt)
local marker = createMarker(posX, posY, posZ, markerType, markerSize, unpack(color))
lastId = lastId + 1
markers[marker] = {
id = lastId,
position = { posX, posY, posZ },
creator_name = creatorName,
created_at = createdAt
}
print("O marker foi criado!")
end
)
-- Como usar o comando:
-- /create-marker cylinder 2
-- ou
-- /create-marker corona 1
-- ou
-- /create-marker corona 5
-- Enfim, a sintaxe é: /create-marker <tipo> <tamanho>
Eita! O código é grande. Eu vou explicar a parte onde os dados estão sendo inseridos, afinal é o que importa. Todo o resto é conceito de programação, que não se encaixa neste tutorial. Mas estude bem e tente entender, pois pensei na melhor maneira, seja em questões de otimização ou facilidades.
Bom, você pode ter percebido que, pelo menos o começo do nosso INSERT INTO é a mesma coisa, mas muda uma coisinha.
Você jamais irá passar o valor diretamente lá dentro de VALUES. Nós adicionamos interrogações (?) em vez disso e, então, no outro parâmetro da função dbExec, passamos os argumentos, respectivamente. Não se esqueça disso: é sempre na ordem em que você colocou os nomes antes.
Nesse caso, eu passei position, color, type, size, creator, created_at. Sendo assim, eu sou obrigado a passar os argumentos dessa forma. Primeiro sendo a posição, depois a cor, depois o tipo, o tamanho e continua...
O total de interrogações (?) depende exatamente disso, de quantas colunas você passou. Existem 6 colunas em nosso exemplo.
Começaremos criando uma função para que possamos obter o marker mais próximo do player que executou o comando.
function getNearestMarker(playerRef)
local matches = {}
local px, py, pz = getElementPosition(playerRef)
for marker, data in pairs(markers) do
local mx, my, mz = unpack(data.position)
local distance = getDistanceBetweenPoints3D(px, py, pz, mx, my, mz)
if distance <= 2 then
matches[#matches + 1] = marker
end
end
if #matches == 0 or #matches > 1 then
return false
end
return matches[1]
end
Com a função criada, agora vamos criar um comando para ver as informações.
addCommandHandler("show-marker",
function(player)
local marker = getNearestMarker(player)
if not marker then
return false
end
local data = markers[marker]
local markerId = data.id
local creatorName = data.creator
local stringDate = os.date("%d/%m/%Y", data.created_at)
outputChatBox("-> ID: " .. markerId, player, 255, 255, 255, true)
outputChatBox("-> Quem criou: " .. creatorName, player, 255, 255, 255, true)
outputChatBox("-> Quando foi criado: " .. stringDate, player, 255, 255, 255, true)
end
)
-- Como usar o comando:
-- /show-marker, perto de um marker
Observação: O uso de tabelas é de extrema importância. Com elas nós podemos visualizar, neste exemplo, os markers sem precisar buscar no banco de dados. Consultas são pesadas e devem ser feitas o mínimo possível. Crie um cache, como eu fiz e sempre que iniciar os resources, armazene os markers numa tabela. Você verá o quão bom é usar quando precisa editar alguma coisa do marker, seja a cor ou o tipo.
Como já temos a função de obter o marker mais próximo, vamos direto ao código!
addCommandHandler("edit-marker-color",
function(player, command, red, green, blue, alpha)
local db = exports.dbtut:getConnection()
if not db then
return false
end
local marker = getNearestMarker(player)
if not marker then
return false
end
local data = markers[marker]
local markerId = data.id
-- Nós precisamos do ID aqui para editar SOMENTE
-- O marker que queremos
-- Vamos obter a cor atual do marker
-- Para adicionar um "fallback" caso o usuário
-- Passe somente uma parte da cor
local mR, mG, mB, mA = getMarkerColor(marker)
-- Verificando se as cores estão corretas
red = tonumber(red) or mR
green = tonumber(green) or mG
blue = tonumber(blue) or mB
alpha = tonumber(alpha) or mA
-- Alteramos a cor do marker então
setMarkerColor(marker, red, green, blue, alpha)
-- Agora o mais importante...
-- Lembra que eu disse que tabelas são importantes? Pois então
-- Nós já temos o ID (markerId)
-- Basta atualizar a cor no banco de dados
dbExec(db, "UPDATE `markers` SET `color` = ? WHERE `id` = ?", toJSON({ red, green, blue, alpha }), markerId)
print("Você alterou a cor do marker de ID " .. markerId)
end
)
-- Como usar o comando:
-- /edit-marker-color 255 89 0 255, perto de um marker
-- /edit-marker-color <r> <g> <b> <a>
Você deve ter percebido que eu usei interrogação (?) aqui também. Sim, é de extrema importância usar, pois como no comando INSERT INTO, lá em VALUES, caso esteja sendo passado diretamente, irá ocorrer o famoso SQL Injection. Jogadores de má índole poderão quebrar totalmente seu banco de dados.
Preste bem atenção e lembre-se novamente: está tudo numa ordem! Vamos por partes.
UPDATE `markers` SET `color` = ? WHERE `id` = ?
Basicamente é isso: eu estou querendo mudar a cor, mas somente se o ID for igual àquele que passarmos. Se falarmos em voz alta e lermos o código, fica mais fácil. Preste bem atenção.
"O que eu quero fazer?" 🤔
dbExec(db, "UPDATE `markers` SET")
"Eu quero alterar a cor" 🎨
dbExec(db, "UPDATE `markers` SET `color` = ?", toJSON({ red, green, blue, alpha }))
"Mas somente se for desse ID aqui ó, código" ❗
dbExec(db, "UPDATE `markers` SET `color` = ? WHERE `id` = ?", toJSON({ red, green, blue, alpha }), markerId)
Pronto. Eles estão em ordem. Agora a cor será alterada, se for daquele ID.
Ah, e lembrando, você pode passar mais coisas além da cor. No exemplo só quero mesmo alterar a cor. Porém, se precisássemos mudar a cor e o tipo ao mesmo tempo, ficaria desta forma:
local markerType = "corona"
dbExec(db, "UPDATE `markers` SET `color` = ?, `type` = ? WHERE `id` = ?", toJSON({ red, green, blue, alpha }), markerType, markerId)
Nós separamos por vírgula. E novamente, perceba a ordem. Jamais se esqueça disso e preste muito atenção sempre que for mexer nisso.
Hora de deletar o nosso querido marker. Vamos ao código... porém, antes de começar, criaremos uma função para obter o total de itens dentro de uma tabela.
function table.length(array)
local count = 0
for _ in pairs(array) do
count = count + 1
end
return count
end
addCommandHandler("delete-marker",
function(player)
local db = exports.dbtut:getConnection()
if not db then
return false
end
local marker = getNearestMarker(player)
if not marker then
return false
end
local data = markers[marker]
local markerId = data.id
-- Nós precisamos do ID aqui para deletar SOMENTE
-- O marker que queremos
markers[marker] = nil
destroyElement(marker)
dbExec(db, "DELETE FROM `markers` WHERE `id` = ?", markerId)
-- Lembra que criamos uma função para pegar o total de items
-- na tabela? Então, iremos usá-la para limpar a tabela
-- do banco de dados. Dessa forma, os IDs do AUTO_INCREMENT
-- serão resetados, ocasionando nenhum bug
if table.length(markers) == 0 then -- Caso não tenha mais nenhum marker criado (obviamente não terá nem no banco de dados)
dbExec(db, "TRUNCATE `markers`")
lastId = 0 -- Também voltamos o contador do último ID para 0
end
print("Você deletou o marker de ID " .. markerId)
end
)
-- Como usar o comando:
-- /delete-marker, perto de um marker
O tutorial termina por aqui e espero que eu possa ter passado um pouco de conhecimento para a comunidade. Isso estava previsto para ser postado ano passado, em Janeiro de 2022, porém o meu tempo ficou curto e não consegui. Escrevi este tutorial novamente, tudo do zero para vocês e elaborei mais coisas.
Ainda existem muitas coisas a serem vistas em relação aos bancos de dados. No momento, o básico está neste tutorial. Eu garanto que vocês são capazes de aproveitar muita coisa daqui. Leiam e releiam caso necessário.
Qualquer dúvida em relação ao código pode me chamar no privado do Discord, responderei assim que tiver disponível.
Estudem, aprendam e não parem de seguir o que vocês gostam!
Gratidão,
androksi.