diff --git a/API.txt b/API.txt new file mode 100644 index 0000000..9c9ec40 --- /dev/null +++ b/API.txt @@ -0,0 +1,133 @@ +API do gestor +============= + +As funcionalidades do gestor estao descritas com foco para desenvolvimento de mods de apoio + + +======================================> Lugares Avulsos <====================================== +Esses lugares sao estruturas que precisam ser montadas para o funcionamento de uma aventura ou +tarefa dos jogadores. O gestor pode informar essa estrutura e seu status de atividade +(OK ou PENDENTE) para o administrador acompanhada de um texto sobre a estrutura que pode ser +usado para informar um comando ou metodo facil para o administrador criar a estrutura. + +Sintaxe +gestor.lugares_avulsos.definir(nome, status, texto) + +* Todas as variaveis sao obrigatorias (nome, status, texto) + +* Variavel nome deve ser uma cadeia de caracteres para o nome do lugar + +* Variavel status deve ser do tipo boleano para definir o estado do lugar onde true serve +para OK e false serve para PENDENTE + +* Variavel texto deve ser uma cadeia de caracteres que serve para definir um texto sobre o +lugar e como criar o lugar por meio de comandos ou qualquer outro metodo que quiser informar. +Jamais use a barra invertida ("\") nesse texto pois isso corrompe o banco de dados do gestor. +Exemplo: +Esse lugar se trata de uma vila onde o jogador troca madeira por qualquer outra coisa. Use o +comando /montar e aguarde o termino + +Exemplo de uso: + +-- Nome da estrutura acompanha o nome do mod (para evitar nomes iguais entre os mods) +local nome_estrutura = minetest.get_current_modname() .. "_castelo" + +-- Texto explicativo da estrutura +local texto = "Castelo do norte. Use /"..nome_estrutura.."_instalar par montar a estrutura" + +-- Verifica se ja existe o se nao existir, cria +if not gestor.registros.lugares["avulsos"][nome_estrutura] then + gestor.lugares_avulsos.definir(nome_estrutura, false, texto) +end + +-- Verifica se ja foi criada e toma uma atitude +if gestor.registros.lugares["avulsos"][nome_estrutura].status == false then + + -- Bloco de algoritimos + + gestor.lugares_avulsos.definir(nome_estrutura, false, "Castelo do mal") +end + +=============================================================================================== + + + +================================> Serializar/Salvar estrutura <================================ +Esse método é usado para serializar uma estrutura dentro da pasta estruturas de um mod que a +executa + +Sintaxe +gestor.estruturador.salvar(pos, nome, largura, altura, modp, silencio) + +* Variaveis pos, nome, largura e altura sao obrigatorias e caso as outros 3 (largura, altura, +modp) não sejam definidas, elas serão pesquisadas com base na tabela de estruturas do proprio +gestor + +* Variavel pos é uma coordenada do ponto onde a estrutura vai ser lida sendo que ela sempre +é lida a partir dessa coordenada e vai para os valores positivos + +* Variavel nome é uma string do nome do arquivo que vai ser gerado na pasta estruturas do mod +que a executa. + +* As variaveis largura e altura são valores numéricos para definir as dimensoes da estrutura +que o metodo vai ler para salvar + +* Variavel modp é uma string com o caminho do diretório do mod que executa esse metodo + +* Variavel silencio é um valor boleano caso queira evitar mensagens no console do servidor +(usado para operar de forma sistemica) +=============================================================================================== + + + +======================================> Criar estrutura <====================================== +Esse metodo é usado para criar estruturas a partir de arquivos de estruturas previamente +serializadas pelo mod gestor. + +Sintaxe +gestor.estruturador.carregar(pos, nome, largura, altura, modp, silencio) + +* Variaveis pos e nome sao obrigatorias e caso as outros 3 (largura, altura, modp) não sejam +definidas, elas serão pesquisadas com base na tabela de estruturas do proprio gestor + +* Variavel pos é uma coordenada do ponto onde a estrutura vai ser montada sendo que ela sempre +é montada a partir dessa coordenada e vai para os valores positivos + +* Variavel nome é uma string para um nome do arquivo da estrutura serializada que deve +obrigatóriamente estar em uma pasta chamada estruturas dentro da pasta do mod que usar esse +metodo + +* As variaveis largura e altura são valores numéricos para definir as dimensoes da estrutura +que o metodo vai montar + +* Variavel modp é uma string com o caminho do diretório do mod que executa esse metodo + +* Variavel silencio é um valor boleano caso queira evitar mensagens no console do servidor +(usado para operar de forma sistemica) +=============================================================================================== + + + +======================================> Proteger Areas <====================================== +Esse metodo protege uma area e caso ocorra alguma falha ao proteger uma area ele retorna uma +string explicando a falha e caso de tudo certo ele retorna boleano verdadeiro (true) + +Sintaxe +gestor.proteger_area(NomeAdmin, NomeDono, NomeArea, pos1, pos2, silencio) + +* Todas as variaveis sao obrigatorias + +* Variavel NomeAdmin deve ser string do nome de um jogador com privilegios para registrar areas + +* Variavel NomeDono deve ser string do nome de um jogador que vai poder interagir na area e +adicionar uma subarea para outro jogador + +* Variavel NomeArea deve ser string de uma nome qualquer para a area criada e vai aparecer na +lista de areas com esse nome (pode ser um nome igual ao de outras areas) + +* As variaveis pos1 e pos2 são tabelas de vetores de cordenadas ({x,y,z}) que delimitam a area +a ser protegida (tanto faz qual tem o menor valor de x, y ou z) + +* Variavel silencio é um valor boleano caso queira evitar mensagens no console do servidor +(usado para operar de forma sistemica) +=============================================================================================== diff --git a/LICENÇA.txt b/LICENÇA.txt new file mode 100644 index 0000000..57efb42 --- /dev/null +++ b/LICENÇA.txt @@ -0,0 +1,80 @@ +LICENÇA CC BY 3.0 BR + +A OBRA (CONFORME DEFINIDA ABAIXO) É DISPONIBILIZADA DE ACORDO COM OS TERMOS DESTA LICENÇA PÚBLICA +CREATIVE COMMONS ("CCPL" OU "LICENÇA"). A OBRA É PROTEGIDA POR DIREITO AUTORAL E/OU OUTRAS LEIS +APLICÁVEIS. QUALQUER USO DA OBRA QUE NÃO O AUTORIZADO SOB ESTA LICENÇA OU PELA LEGISLAÇÃO AUTORAL +É PROIBIDO. + +AO EXERCER QUAISQUER DOS DIREITOS À OBRA AQUI CONCEDIDOS, VOCÊ ACEITA E CONCORDA FICAR OBRIGADO +NOS TERMOS DESTA LICENÇA. O LICENCIANTE CONCEDE A VOCÊ OS DIREITOS AQUI CONTIDOS EM CONTRAPARTIDA +A SUA ACEITAÇÃO DESTES TERMOS E CONDIÇÕES. + +1. Definições + +"Obra Derivada" significa uma Obra baseada na Obra ou na Obra e outras Obras pré-existentes, +tal qual uma tradução, adaptação, arranjo musical ou outras alterações de uma Obra literária, +artística ou científica, ou fonograma ou performance, incluindo adaptações cinematográficas ou +qualquer outra forma na qual a Obra possa ser refeita, transformada ou adaptada, abrangendo +qualquer forma reconhecível como derivada da original, com exceção da Obra que constitua uma +Obra Coletiva, a qual não será considerada uma Obra Derivada para os propósitos desta Licença. +Para evitar dúvidas, quando a Obra for uma Obra musical, performance ou fonograma, a sincronização +da Obra em relação cronometrada com uma imagem em movimento (“synching”) será considerada uma +Obra Derivada para os propósitos desta Licença. + +"Obra Coletiva" significa uma coleção de Obras literárias, artísticas ou científicas, tais quais +enciclopédias e antologias, ou performances, fonogramas ou transmissões, ou outras Obras ou +materiais não indicados na Seção 1(g) abaixo, que em razão da seleção e arranjo do seu conteúdo, +constituam criações intelectuais nas quais a Obra é incluída na sua integridade em forma +não-modificada, juntamente com uma ou mais contribuições, cada qual constituindo separada e +independentemente uma Obra em si própria, que juntas são reunidas em um todo coletivo. A Obra +que constituir uma Obra Coletiva não será considerada uma Obra Derivada (como definido acima) +para os propósitos desta Licença. + +"Distribuir" significa colocar à disposição do público o original e cópias da Obra ou Obra +Derivada, o que for apropriado, por meio de venda ou qualquer outra forma de transferência de +propriedade ou posse. + +"Licenciante" significa a pessoa física ou jurídica que oferece a Obra sob os termos desta Licença. + +"Autor Original" significa, no caso de uma Obra literária, artística ou científica, o indivíduo ou +indivíduos que criaram a Obra ou, se nenhum indivíduo puder ser identificado, a editora. + +"Titular de Direitos Conexos" significa (i) no caso de uma performance os atores, cantores, músicos, +dançarinos, e outras pessoas que atuem, cantem, recitem, declamem, participem em, interpretem ou +façam performances de Obras literárias ou artísticas ou expressões de folclore (ii) no caso de um +fonograma, o produtor, sendo este a pessoa ou entidade legal que primeiramente fixar os sons de +uma performance ou outros sons; e (iii) no caso de radiodifusão, a empresa de radiodifusão. + +"Obra" significa a Obra literária, artística e/ou científica oferecida sob os termos desta Licença, +incluindo, sem limitação, qualquer produção nos domínios literário, artístico e científico, qualquer +que seja o modo ou a forma de sua expressão, incluindo a forma digital, tal qual um livro, brochuras +e outros escritos; uma conferência, alocução, sermão e outras Obras da mesma natureza; uma +Obra dramática ou dramático-musical; uma Obra coreográfica ou pantomima; uma composição musical +com ou sem palavras; uma Obra cinematográfica e as expressas por um processo análogo ao da +cinematografia; uma Obra de desenho, pintura, arquitetura, escultura, gravura ou litografia; uma +Obra fotográfica e as Obras expressas por um processo análogo ao da fotografia; uma Obra de arte +aplicada; uma ilustração, mapa, plano, esboço ou Obra tridimensional relativa a geografia, topografia, +arquitetura ou ciência; uma performance, transmissão ou fonograma, na medida em que tais +Obras/direitos sejam reconhecidos e protegidos pela legislação aplicável; uma compilação de dados, +na extensão em que ela seja protegida como uma Obra sujeita ao regime dos direitos autorais; ou +uma Obra executada por artistas circenses ou de shows de variedade, conforme ela não for considerada +uma Obra literária, artística ou científica. + +"Você" significa a pessoa física ou jurídica exercendo direitos sob esta Licença, que não tenha +previamente violado os termos desta Licença com relação à Obra, ou que tenha recebido permissão +expressa do Licenciante para exercer direitos sob esta Licença apesar de uma violação prévia. + +"Executar Publicamente" significa fazer a utilização pública da Obra e comunicar ao público a Obra, +por qualquer meio ou processo, inclusive por meios com ou sem fio ou performances públicas digitais; +disponibilizar ao público Obras de tal forma que membros do público possam acessar essas Obras de um +local e em um local escolhido individualmente por eles; Executar a Obra para o público por qualquer +meio ou processo e comunicar ao público performances da Obra, inclusive por performance pública +digital; transmitir e retransmitir a Obra por quaisquer meios, inclusive sinais, sons ou imagens. + +"Reproduzir" significa fazer cópias da Obra por qualquer meio, inclusive, sem qualquer limitação, +por gravação sonora ou visual, e o direito de fixar e Reproduzir fixações da Obra, inclusive o +armazenamento de uma performance protegida ou fonograma, em forma digital ou qualquer outro meio +eletrônico. + +Para continuar lendo a licença +https://creativecommons.org/licenses/by/3.0/br/legalcode diff --git a/anticrash.lua b/anticrash.lua new file mode 100644 index 0000000..4ea8af2 --- /dev/null +++ b/anticrash.lua @@ -0,0 +1,75 @@ +-- +-- Mod gestor +-- +-- Sistema AntiCrash +-- + +gestor.anticrash = {} + +-- Caminho da pasta de depurador (depug.txt) +local debug_path = io.popen"pwd":read"*all" +debug_path = string.split(debug_path, "\n") +debug_path = debug_path[1] + +-- Validar dados +--[[ + Verificar a existencia de dados e + cria-los com valor padrão para que + estejam disponiveis + ]] + +local verificar_dado = function(dado, padrao) + if gestor.bd:verif("anticrash", dado) ~= true then + gestor.bd:salvar("anticrash", dado, padrao) + end +end + +-- Tabela de dados (que devem estar no banco de dados) +local dados = { + -- Dados Valor padrao + -- Sistema AntCrash + { "comando_abertura", "./../../bin/minetest --server"}, + { "processo", "minetest --server"}, + { "interval", "300"}, + -- Sistema de Email + { "status_email", "false"}, + { "from_email", "gestorminemacro@gmail.com"}, + { "from_login", "gestorminemacro@gmail.com"}, + { "from_senha", ""}, + { "from_smtp", "smtp.gmail.com"}, + { "from_smtp_port", "587"}, + { "from_subject", "Servidor reiniciado!"}, + { "to_email", "borgesdossantosbruno@gmail.com"}, + -- Sistema de Backups + { "status_backup", "false"}, + { "debug_path", debug_path}, + { "world_path", minetest.get_worldpath()}, +} + +-- Verifica todos os cados +for _, v in ipairs(dados) do + verificar_dado(v[1], v[2]) +end + +-- Iniciar anticrash +gestor.anticrash.iniciar = function() + local comando = "./anticrash " + -- ..comando_abertura.." " -- 1 + -- ..processo.." " -- 2 + -- ..interval.." " -- 3 + -- ..status_email.." " -- 4 + -- ..from_email.." " -- 5 + -- ..from_login.." " -- 6 + -- ..from_senha.." " -- 7 + -- ..from_smtp.." " -- 8 + -- ..from_smtp_port.." " -- 9 + -- ..from_subject.." " -- 10 + -- ..to_email.." " -- 11 + -- ..status_backup.." " -- 12 + -- ..debug_path.." " -- 13 + -- ..world_path.." " -- 14 + .."&" + os.execute(comando) +end + + diff --git a/anticrash.sh b/anticrash.sh new file mode 100755 index 0000000..64df04c --- /dev/null +++ b/anticrash.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +##################################################### +################ SCRIPT ANTICRASH ################### +##################################################### +## LICENÇA: LGPL ## +##################################################### +## Por ############################################## +## Lunovox ## +## BrunoMine ## +##################################################### + +# Intervalo de verificação +interval=300 #PADRÃO: 300 segundos (5 minutos) + +# Nome do processo +processo="minetest --server" + +# Comando de abertura do servidor +# Use o comando '~$ minetest --help' +# para saber os parâmetros válidos +comando_abertura="./../../bin/minetest --server" + +# Caminho de depuração (debug.txt) +debug_path="./../../bin" + +# Caminho do diretório do mundo +world_path="./../../worlds/minemacro" + +# Variáveis de Email +from_email="gestorminemacro@gmail.com" # Endereço de origem que envia email +from_login="gestorminemacro@gmail.com" # Loggin do email de origem +from_senha="minemacro123" # Senha do email de origem +from_smtp="smtp.gmail.com:587" # Protocolo de SMTP do seu servidor de email +from_subject="[$(date '+%Y-%m-%d %H:%M:%S')] Servidor reiniciado! " # Titulo do email que será enviado +to_email="borgesdossantosbruno@gmail.com" # Endereço de destinatário que recebe email + + +echo -e "[\033[01;32m$(date '+%Y-%m-%d %H:%M:%S')\033[00;00m] Iniciando verificação de processo '$processo' a cada $interval segundos..." + +# Laço de verificação infinito +while [ true == true ]; do +if ! [ "$(pgrep -f "$processo")" ]; then # verificar processo +quando="$(date '+%Y-%m-%d %H-%M-%S')" + +echo -e "[\033[01;32m$quando\033[00;00m] Renomenado 'debug.txt' para 'debug ($quando).txt'..." +mv "$debug_path/debug.txt" "$debug_path/debug ($quando).txt" # Salvando arquivo de depuração + +echo -e "[\033[01;32m$quando\033[00;00m] Fazendo backup do mapa em '$world_path($quando).tar.gz'..." +#7z a "$world_path ($quando).7z" "$world_path" +tar -czf "$world_path($quando).tar.gz" "$world_path" + +echo -e "[\033[01;32m$quando\033[00;00m] Enviando relatório para '$to_email'..." +sendemail -s "$from_smtp" -xu "$from_login" -xp "$from_senha" -f "$from_email" -t "$to_email" -u "$from_subject" -m "O servidor Minemacro crashou" -o message-charset=UTF-8 -a "$debug_path/debug ($quando).txt" + +echo -e "[\033[01;32m$quando\033[00;00m] Reativando servidor de minetest ..." +#$comando_abertura & +fi +#echo "aguardando $interval segundos" +sleep $interval +done diff --git a/banco_de_dados.lua b/banco_de_dados.lua new file mode 100644 index 0000000..89760ce --- /dev/null +++ b/banco_de_dados.lua @@ -0,0 +1,35 @@ +-- +-- Mod gestor +-- +-- Banco de Dados +-- + + +-- Validar dados + +-- Minemacro (tabela 'centro') +if gestor.bd:verif("centro", "pos") ~= true then + gestor.bd:salvar("centro", "status", false) -- Se minemacro esta ativo + gestor.bd:salvar("centro", "pos", {x=0,y=0,z=0}) -- Coordenada de teleporte para o centro do servidor +end + + +-- Vilas (tabela 'vilas') +--[[ + São armazenadas com a index '' e + o valor é uma tabela com o nome apresentavel e + a coordenada de teleport para a vila. + Exemplo: ["blocopolis"] = {nome="Blocopolis", pos={x=100, y=100, z=100}} + ]] + +-- Lugares avulsos (tabela 'avulsos') +--[[ + São armazenadas com a index '' + e o valor é uma tabela com o status (para saber + se foi criada e devidamente operante) e um texto + explicando como tornar a estrutura ativa e/ou + sobre algo sobre a propria estrutura. + Exemplo: ["castelinho"] = {status=false, texto="Use /montar"} + ]] + + diff --git a/comandos.lua b/comandos.lua new file mode 100644 index 0000000..808148e --- /dev/null +++ b/comandos.lua @@ -0,0 +1,60 @@ +-- +-- Mod gestor +-- +-- Comandos +-- + +-- Comando para exibir tela de gerenciamento +minetest.register_chatcommand("gestor", { + privs = {server=true}, + params = "[Nenhum]", + description = "Abrir tela de gerenciamento", + func = function(name) + minetest.after(1, gestor.menu_principal, name, true) + end +}) + + +-- Comando de serializar estrutura +minetest.register_chatcommand("serializar", { + privs = {server=true}, + params = "[ ]", + description = "Serializa uma estrutura", + func = function(name, param) + local m = string.split(param, " ") + local param1, param2, param3 = m[1], m[2], m[3] + if param1 then + local player = minetest.get_player_by_name(name) + local pos = player:getpos() + if gestor.estruturador.salvar(pos, param1, param2, param3) then + minetest.chat_send_player(name, "Estrutura serializada com sucesso") + else + minetest.chat_send_player(name, "Falha ao serializar estrutura") + end + else + minetest.chat_send_player(name, "Comando invalido") + end + end +}) + +-- Comando de deserializar estrutura +minetest.register_chatcommand("deserializar", { + privs = {server=true}, + params = "[ ]", + description = "Serializa uma estrutura", + func = function(name, param) + local m = string.split(param, " ") + local param1, param2, param3 = m[1], m[2], m[3] + if param1 then + local player = minetest.get_player_by_name(name) + local pos = player:getpos() + if gestor.estruturador.carregar(pos, param1, param2, param3) then + minetest.chat_send_player(name, "Estrutura deserializada com sucesso") + else + minetest.chat_send_player(name, "Falha ao deserializar estrutura") + end + else + minetest.chat_send_player(name, "Comando invalido") + end + end +}) diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..f6878c3 --- /dev/null +++ b/depends.txt @@ -0,0 +1,3 @@ +default +areas +memor diff --git a/diretrizes.lua b/diretrizes.lua new file mode 100644 index 0000000..ad9013d --- /dev/null +++ b/diretrizes.lua @@ -0,0 +1,35 @@ +-- +-- Mod gestor +-- +-- Diretrizes +-- + +-- Variavel de Diretrizes +gestor.diretrizes = {} + +-- Estruturas +gestor.diretrizes.estruturas = { + -- arquivo, largura, altura + -- Centro + ["centro"] = { 10, 10 }, + -- Vilas +} + +-- Lista de vilas (lista de estruturas ja salvas) +gestor.vilas = { + -- "exemplo", +} + + +-- Lista-string configurada altomaticamente +gestor.lista_vilas = "" +local i = 1 +while (gestor.vilas[i]~=nil) do + gestor.lista_vilas = gestor.lista_vilas..gestor.vilas[i] + if i < table.maxn(gestor.vilas) then gestor.lista_vilas = gestor.lista_vilas .. "," end + i = i + 1 +end +-- Variavel de registros +gestor.registros = {} + + diff --git a/estruturador.lua b/estruturador.lua new file mode 100644 index 0000000..799c36a --- /dev/null +++ b/estruturador.lua @@ -0,0 +1,273 @@ +-- +-- Mod gestor +-- +-- Estruturador +-- + +-- Diretorio do Mod +local modpath = minetest.get_modpath("gestor") + +-- Variavel global de estruturador +gestor.estruturador = {} + + +-- Arredondar posicao +local arredondar = function(pos) + local r = {} + if pos.x > (math.floor(pos.x)+0.5) then + r.x = math.ceil(pos.x) + else + r.x = math.floor(pos.x) + end + if pos.y > (math.floor(pos.y)+0.5) then + r.y = math.ceil(pos.y) + else + r.y = math.floor(pos.y) + end + if pos.z > (math.floor(pos.z)+0.5) then + r.z = math.ceil(pos.z) + else + r.z = math.floor(pos.z) + end + return r +end + +-- Restaurar as refenrencias em relacao a uma pos +local restaurar_pos = function(pos, ref) + local r = {} + r.x, r.y, r.z = (pos.x+ref.x), (pos.y+ref.y), (pos.z+ref.z) + return r +end + +-- calcular o deslocamento de ref em relacao a pos +local ref_pos = function(pos, ref) + local r = {} + r.x, r.y, r.z = (ref.x-pos.x), (ref.y-pos.y), (ref.z-pos.z) + return r +end + +-- metodo melhorado para pegar nodes (pega nodes ainda nao carregados) +local function pegar_node(pos) + local resp = {} + local node = minetest.get_node(pos) + if node.name == "ignore" then + minetest.get_voxel_manip():read_from_map(pos, pos) + node = minetest.get_node(pos) + end + resp = {node=node} + --[[ + Para salvar os metadados é criada um valor meta (node.meta) + para que alguns dados possam ser mantidos de forma serializada + no node e posteriormente serem restaurados quando a estrutura + for restaurada + ]] + local meta = minetest.get_meta(pos) + if node.name == "placa_terreno:livre" then -- placas de terreno + local ref1 = "" + local ref2 = "" + if meta:get_string("ref1") ~= "" then + -- Mantem os antigos ref's caso existam no metadado + ref1 = minetest.deserialize(meta:get_string("ref1")) + ref2 = minetest.deserialize(meta:get_string("ref2")) + else + -- Calcula os ref's + ref1 = minetest.serialize(ref_pos(pos, minetest.deserialize(meta:get_string("pos1")))) + ref2 = minetest.serialize(ref_pos(pos, minetest.deserialize(meta:get_string("pos2")))) + end + local custo = meta:get_string("custo") + local altura = meta:get_string("altura") + resp = {node=node,meta={ref1=ref1,ref2=ref2,custo=custo,altura=altura}} + elseif node.name == "default:sign_wall" then -- placas normais de parede + local text = meta:get_string("text") + local infotext = meta:get_string("infotext") + resp = {node=node,meta={text=text,infotext=infotext}} + end + return resp +end + + +-- Serializar estrutura +gestor.estruturador.salvar = function(pos, nome, largura, altura, modp, silencio) + if not pos or not nome then return false end + -- arredondar posicao + pos = arredondar(pos) + + if modp == nil then + modp = modpath + end + largura = largura or gestor.diretrizes.estruturas[nome][1] + altura = altura or gestor.diretrizes.estruturas[nome][1] + if not largura or not altura then return false end + -- Criar estrutura + if silencio == nil or silencio == false then minetest.chat_send_all("Serializando estrutura. Aguarde...") end + local estrutura = {} + local ix, iy, iz = 1, 1, 1 + local x, y, z = pos.x, pos.y, pos.z + local limx, limy, limz = (pos.x+largura-1), (pos.y+altura-1), (pos.z+largura-1) + local i = 0 + while (x <= limx) do + while (y <= limy) do + while (z <= limz) do + estrutura[ix.." "..iy.." "..iz] = pegar_node({x = x, y = y, z = z}) + i = i + 1 + z = z + 1 + iz = iz + 1 + end + z = pos.z + iz = 1 + y = y + 1 + iy = iy + 1 + end + y = pos.y + iy = 1 + x = x + 1 + ix = ix + 1 + end + + -- Criar arquivo + local output = io.open(modp .. "/estruturas/"..nome, "w") + output:write(minetest.serialize(estrutura)) + io.close(output) + + -- Estrutura serializada com sucesso + if silencio == nil or silencio == false then minetest.chat_send_all("Serializacao concluida.") end + return true +end + +-- Deserializar uma estrutura +gestor.estruturador.carregar = function(pos, nome, largura, altura, modp, silencio) + if pos == nil or nome == nil then return false end + if silencio == nil or silencio == false then minetest.chat_send_all("Criando estrutura. Aguarde...") end + -- Coleta de dados + local dados = {} + if modp == nil then + dados = gestor.diretrizes.estruturas[nome] or {} + largura = dados[1] or largura + altura = dados[2] or altura + modp = modpath + end + if largura == nil or altura == nil or nome == nil then return false end + local input = io.open(modp .. "/estruturas/"..nome, "r") + if input then + dados.estrutura = minetest.deserialize(input:read("*l")) + else + return false + end + io.close(input) + -- Criar estrutura + local ix, iy, iz = 1, 1, 1 + local x, y, z = pos.x, pos.y, pos.z + local limx, limy, limz = (pos.x+largura-1), (pos.y+altura-1), (pos.z+largura-1) + local i = 0 + while (x <= limx) do + while (y <= limy) do + while (z <= limz) do + local PosNode = dados.estrutura[ix.." "..iy.." "..iz] or {node={name="air"}} + minetest.set_node({x = x, y = y, z = z}, PosNode.node) + if PosNode.meta then + if PosNode.node.name == "placa_terreno:livre" then + local meta = minetest.get_meta({x = x, y = y, z = z}) + --[[ + Tenta restaurar pos1 e pos2 mas devido a um erro + desconhecido as vezes desloca 1 node de distancia + para alguma direção + ]] + meta:set_string("pos1", + minetest.serialize(restaurar_pos(minetest.deserialize(PosNode.meta.ref1), + {x = x, y = y, z = z})) + ) + meta:set_string("pos2", + minetest.serialize(restaurar_pos(minetest.deserialize(PosNode.meta.ref2), + {x = x, y = y, z = z})) + ) + --[[ + Mantes ref1 e ref2 no meto do bloco para evitar distorções maiores + usando sempre esses ref's a distorção pode ser no maximo 1 node + ]] + meta:set_string("ref1", minetest.serialize(PosNode.meta.ref1)) + meta:set_string("ref2", minetest.serialize(PosNode.meta.ref2)) + meta:set_string("custo", PosNode.meta.custo) + meta:set_string("altura", PosNode.meta.altura) + meta:set_string("status", "livre") + meta:set_string("infotext", "Terreno a Venda") + elseif PosNode.node.name == "default:sign_wall" then + local meta = minetest.get_meta({x = x, y = y, z = z}) + meta:set_string("text", PosNode.meta.text) + meta:set_string("infotext", PosNode.meta.infotext) + end + end + i = i + 1 + z = z + 1 + iz = iz + 1 + end + z = pos.z + iz = 1 + y = y + 1 + iy = iy + 1 + end + y = pos.y + iy = 1 + x = x + 1 + ix = ix + 1 + end + + -- Estrutura construida com sucesso + if silencio == nil or silencio == false then minetest.chat_send_all("Estrutura construida. Aguarde o mapa ser renderizado.") end + return true +end + +-- +----- +-------- +-- Nodes restaurador de escadarias +local criar_nivel_escadaria = function(pos, largura, name) + local limx, limz = pos.x+(largura/2), pos.z+(largura/2) + local x, z = pos.x-(largura/2), pos.z-(largura/2) + while (x<=limx) do + z = pos.z-(largura/2) + while (z<=limz) do + local npos = {x=x,y=pos.y,z=z} + local node = minetest.get_node(npos) + if node.name == "ignore" then + minetest.get_voxel_manip():read_from_map(npos, npos) + node = minetest.get_node(npos) + end + if node.name == "air" then + minetest.set_node(npos, {name=name}) + end + z=z+1 + end + x=x+1 + end +end +local criar_escadaria = function(pos, node) + local npos = {x=pos.x,y=pos.y-10,z=pos.z} + local altura = pos.y - 8 + while altura <= pos.y do + criar_nivel_escadaria({x=pos.x,y=altura,z=pos.z}, (math.abs(pos.y-altura)*4)+7, node) + altura = altura + 1 + end +end +minetest.register_node("gestor:escadaria", { + description = "Restaurador de escadaria", + tiles = { + "default_pine_wood.png", + "default_pine_wood.png", + "default_pine_wood.png", + "default_pine_wood.png", + "default_pine_wood.png", + "default_pine_wood.png" + }, + groups = {choppy=2,oddly_breakable_by_hand=2,wood=1}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos) + local node = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + criar_escadaria({x=pos.x,y=pos.y-1,z=pos.z}, node.name) + minetest.set_node(pos, {name="air"}) + minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, {name="air"}) + end, +}) +-- Fim +-------- +----- +-- diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..c551e5c --- /dev/null +++ b/init.lua @@ -0,0 +1,32 @@ +-- +-- Mod gestor +-- +-- Inicializador +-- + +-- Notificador de Inicializador +local notificar = function(msg) + if minetest.setting_get("log_mods") then + minetest.debug("[GESTOR]"..msg) + end +end + +local modpath = minetest.get_modpath("gestor") + +-- Variavel global das funcionalidades +gestor = {} + +-- Banco de Dados do gestor +gestor.bd = memor.montar_bd() + +-- Carregar scripts +notificar("Carregando...") +dofile(modpath.."/diretrizes.lua") +dofile(modpath.."/banco_de_dados.lua") +dofile(modpath.."/estruturador.lua") +dofile(modpath.."/protetor.lua") +dofile(modpath.."/lugares_avulsos.lua") +dofile(modpath.."/menu_principal.lua") +dofile(modpath.."/comandos.lua") +dofile(modpath.."/anticrash.lua") +notificar("OK") diff --git a/lugares_avulsos.lua b/lugares_avulsos.lua new file mode 100644 index 0000000..f63b19e --- /dev/null +++ b/lugares_avulsos.lua @@ -0,0 +1,16 @@ +-- +-- Mod gestor +-- +-- Lugares avulsos (gerenciamento) +-- + +-- Variavel global +gestor.lugares_avulsos = {} + +-- Definir um lugar no banco de dados (usado para inserir e editar) +gestor.lugares_avulsos.definir = function(nome, status, texto) + if not nome or not texto then return false end + gestor.bd:salvar("avulsos", nome, {status=status, texto=texto}) + return true +end + diff --git a/menu_principal.lua b/menu_principal.lua new file mode 100644 index 0000000..5567d29 --- /dev/null +++ b/menu_principal.lua @@ -0,0 +1,423 @@ +-- +-- Mod gestor +-- +-- Menu Principal +-- + +local escolha_local_avulso = {} + +local escolha_vila = memor.online() + +-- Desordenar tabela +local desordenar = function(tb) + local ntb = {} + for _,d in ipairs(tb) do + ntb[d] = {} + end + return ntb +end + +-- Abrir Menu principal +local aba = {} -- salva em que aba o jogador esta +gestor.menu_principal = function(name, inicio) + if inicio == true then aba[name] = "inicio" end + + local formspec = "size[14,11]" + ..default.gui_bg + ..default.gui_bg_img + .."label[0,0;Gestor Administrativos do Servidor]" + .."button[0,1;3,1;desligar;Desligar]" -- Botao 1 + .."button[0,2;3,1;lugares;Lugares]" -- Botao 2 + .."button[0,3;3,1;conf;Diretrizes]" -- Botao 3 + .."button[0,4;3,1;anticrash;AntiCrash]" -- Botao 4 + --.."button[0,5;3,1;;]" -- Botao 5 + --.."button[0,6;3,1;;]" -- Botao 6 + --.."button[0,7;3,1;;]" -- Botao 7 + --.."button[0,8;3,1;;]" -- Botao 8 + --.."button[0,9;3,1;;]" -- Botao 9 + + -- + -- Gerando Abas + -- + + -- Lugares + if aba[name] == "lugares" then + local lugares = {} + lugares["centro"] = desordenar(minetest.get_dir_list(minetest.get_worldpath().."/gestor/centro")) + lugares["vilas"] = desordenar(minetest.get_dir_list(minetest.get_worldpath().."/gestor/lugares")) + lugares["avulsos"] = desordenar(minetest.get_dir_list(minetest.get_worldpath().."/gestor/avulsos")) + local status_lugares = {} + + -- Status e teleporte do Centro do Servidor + if gestor.bd:verif("centro", "status") then + status_lugares["centro"] = "Ativo" + formspec = formspec.."button_exit[7,2.5;3,1;ir_centro;Ir para Centro]" + formspec = formspec.."button[10,2.5;3,1;tp_centro;Redefinir pos. tp.]" + else + status_lugares["centro"] = "Inativo" + end + + -- Preparar variaveis para Lugares avulsos + local lista_avulsos = "" + local desc_avulso = "Selecione um lugar \nna lista ao lado \n<<<<<<<<<<<<<\npara saber sobre" + .."\nMaximizar a tela \najuda na leitura da \nlista e do texto" + local n = 0 + for nome_avulso, v in pairs(lugares["avulsos"]) do + if lista_avulsos ~= "" then lista_avulsos = lista_avulsos.."," end + if v.status then lista_avulsos = lista_avulsos.."OK |" else lista_avulsos = lista_avulsos.."PEND. |" end + lista_avulsos = lista_avulsos.." "..nome_avulso + n = n + 1 + if tonumber(escolha_local_avulso[name]) == n then desc_avulso = v.texto end + end + if lista_avulsos == "" then lista_avulsos = "Nenhum" end + formspec = formspec.. + "label[4,1;Lugares]".. + -- Centro do Servidor + "label[4,2;Centro do Servidor - Spawn ("..status_lugares["centro"]..")]".. + "button[4,2.5;3,1;construir_centro;Constrir Aqui]".. + -- Vilas + "label[4,4;Vilas]".. + "dropdown[4,4.5;4,1;vila;"..gestor.lista_vilas..";1]".. + "button[8,4.4;2.5,1;construir_vila;Constrir Aqui]".. + "button_exit[10.5,4.4;3.1,1;tp_vila;Definir spawn de vila]".. + -- Lugares Avulsos + "label[4,6;Lugares Avulsos]".. + "textlist[4,6.5;5,4;avulsos;"..lista_avulsos.."]".. + "textarea[9.4,6.48;4.5,4.73;desc_avulso;Sobre o lugar;"..desc_avulso.."]" + + -- Diretrizes + elseif aba[name] == "diretrizes" then + + formspec = formspec + .."label[4,1;Diretrizes]" + .."label[4,2;Ponto de Spawn]" + .."button_exit[4,2.4;3,1;definir_spawn;Definir Aqui]" + .."button_exit[7,2.4;3,1;ir_spawn;Ir para Spawn]" + .."field[4.3,4.1;3,1;slots;Limite de Jogadores;"..minetest.setting_get("max_users").."]" + .."button_exit[7,3.8;3,1;definir_slots;Redefinir Limite]" + + -- AntiCrash + elseif aba[name] == "anticrash" then + + local status_senha = "" + if gestor.bd:pegar("anticrash", "from_senha") then status_senha = " (Salva)" end + + local status_email = "1" + if gestor.bd:pegar("anticrash", "status_email") == "true" then status_email = "2" end + + local status_backup = "1" + if gestor.bd:pegar("anticrash", "status_backup") == "true" then status_backup = "2" end + + formspec = formspec + .."label[4,1;AntiCrash]" + .."button[10.6,1.5;3,1;salvar;Salvar Dados]" + -- Sistema Verificador AntiCrash + .."label[4,2;Sistema Verificador AntiCrash]" + .."button[4,2.7;2,1;iniciar;Iniciar]" + .."field[6.4,3;4,1;processo;Nome do Processo;"..gestor.bd:pegar("anticrash", "processo").."]" + .."field[10.4,3;3.5,1;quedas;Lim. de quedas seguidas;5]" + .."field[4.3,4;9.6,1;comando_abertura;Comando de abertura do servidor (Via terminal UNIX);"..gestor.bd:pegar("anticrash", "comando_abertura").."]" + -- Sistema Notificador via Email + .."label[4,5;Sistema Notificador via Email]" + .."label[4,5.4;Estado]" + .."dropdown[4,5.8;2,1;status_email;Inativo,Ativo;"..status_email.."]" + .."field[6.3,6;4.3,1;from_email;Email emissor;"..gestor.bd:pegar("anticrash", "from_email").."]" + .."pwdfield[10.6,6;3.3,1;from_senha;Senha"..status_senha.."]" + .."field[4.3,7;6,1;from_smtp;Servidor SMTP do email emissor;"..gestor.bd:pegar("anticrash", "from_smtp").."]" + .."field[10.3,7;3.6,1;from_smtp_port;Porta;"..gestor.bd:pegar("anticrash", "from_smtp_port").."]" + .."field[4.3,8;5,1;from_subject;Titulo da mensagem de email enviada;"..gestor.bd:pegar("anticrash", "from_subject").."]" + .."field[9.3,8;4.6,1;to_email;Email do destinatario;"..gestor.bd:pegar("anticrash", "to_email").."]" + -- Sistema de Backup + .."label[4,8.8;Sistema de Backup]" + .."dropdown[4,9.3;3,1;status_backup;Inativo,Ativo;"..status_backup.."]" + + end + + -- Exibir tela + minetest.show_formspec(name, "gestor:menu_principal", formspec) +end + + +-- Receptor de campos +minetest.register_on_player_receive_fields(function(player, formname, fields) + + -- Menu Principal + if formname == "gestor:menu_principal" then + local name = player:get_player_name() + + -- + -- Alternar aba selecionada + -- + + if fields.lugares then -- Lugares + aba[name] = "lugares" + gestor.menu_principal(name) + return true + elseif fields.conf then -- Diretrizes + aba[name] = "diretrizes" + gestor.menu_principal(name) + return true + elseif fields.anticrash then -- AntiCrash + aba[name] = "anticrash" + gestor.menu_principal(name) + return true + end + + + -- Botao Desligar servidor + if fields.desligar then + minetest.show_formspec(name, "gestor:aviso_desligamento", "size[4,1.8]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;Tem certeza que quer \ndesligar do servidor?]".. + "button[0,1;2,1;cancelar;Cancelar]".. + "button_exit[2,1;2,1;ok;Sim]" + ) + end + + -- + -- Recebendo campos de Abas + -- + + -- Lugares + if aba[name] == "lugares" then + if fields.construir_centro then + minetest.show_formspec(name, "gestor:aviso_construir_centro", "size[4,1.8]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;Tem certeza que quer \nconstruir Centro do Servidor]".. + "button[0,1;2,1;cancelar;Cancelar]".. + "button_exit[2,1;2,1;ok;Sim]" + ) + elseif fields.construir_vila then + escolha_vila[name] = fields.vila + minetest.show_formspec(name, "gestor:aviso_construir_vila", "size[4,3.8]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;Tem certeza que quer \nconstruir essa vila?]".. + "field[0.25,1.2;4,1;nome_vila;;Nome da Vila]".. + "label[0,2;Arquivo de midia: \n"..escolha_vila[name].."]".. + "button[0,3;2,1;cancelar;Cancelar]".. + "button_exit[2,3;2,1;ok;Sim]" + ) + elseif fields.tp_vila then + if fields.vila then + if gestor.bd:verif("vilas", fields.vila) then + local dados_vila = gestor.bd:pegar("vilas", fields.vila) + gestor.bd:salvar("vilas", fields.vila, {nome=dados_vila.nome, pos=player:getpos()}) + minetest.chat_send_player(name, "Posicao de teleporte da vila "..fields.vila.." redefinido para esse local.") + else + minetest.chat_send_player(name, "Vila "..fields.vila.." ainda nao existe.") + end + else + minetest.log("error", "Nome da vila parece inconsistente ("..dump(fields.vila)..").") + end + elseif fields.ir_centro then + player:setpos(gestor.bd:pegar("centro", "pos")) + minetest.chat_send_player(name, "Teleportado para o Centro do Servidor") + elseif fields.tp_centro then + gestor.bd:salvar("centro", "pos", player:getpos()) + minetest.show_formspec(name, "gestor:aviso", "size[4,1.8]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;AVISO\nPosicao de teleport \ndo Centro do Servidor \nredefinido para aqui]" + ) + minetest.after(2, gestor.menu_principal, name) + elseif fields.avulsos then + local n = string.split(fields.avulsos, ":") + escolha_local_avulso[name] = n[2] + gestor.menu_principal(name) + end + + -- Diretrizes + elseif aba[name] == "diretrizes" then + if fields.definir_spawn then + local pos = player:getpos() + minetest.setting_set("static_spawnpoint", pos.x.." "..pos.y.." "..pos.z) + minetest.chat_send_player(name, "Spawn redefinido aqui.") + elseif fields.ir_spawn then + local pos = minetest.setting_get_pos("static_spawnpoint") or {x=0,y=0,z=0} + player:setpos(pos) + minetest.chat_send_player(name, "Teleportado para ponto de Spawn.") + elseif fields.definir_slots then + if tonumber(fields.slots) then + minetest.setting_set("max_users", fields.slots) + minetest.chat_send_player(name, "Limite de jogadores redefinido para "..fields.slots..".") + else + minetest.chat_send_player(name, "Digite um numero para o limite de jogadores") + end + end + + -- Anticrash + elseif aba[name] == "anticrash" then + + if fields.salvar then + + -- Salvar dados gerais + gestor.bd:salvar("anticrash", "processo", fields.processo) + gestor.bd:salvar("anticrash", "comando_abertura", fields.comando_abertura) + gestor.bd:salvar("anticrash", "from_email", fields.from_email) + gestor.bd:salvar("anticrash", "from_smtp", fields.from_smtp) + gestor.bd:salvar("anticrash", "from_smtp_port", fields.from_smtp_port) + gestor.bd:salvar("anticrash", "from_subject", fields.from_subject) + gestor.bd:salvar("anticrash", "to_email", fields.to_email) + if fields.from_senha ~= "" then + gestor.bd:salvar("anticrash", "from_senha", fields.from_senha) + end + + minetest.show_formspec(name, "gestor:aviso", "size[4,1.8]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;AVISO\nTodos os dados \nforam salvos com \nsucesso]" + ) + + -- Verificar sistema de email + if fields.status_email = "Ativo" then + --[[ + EM DESENVOLVIMENTO + Deve criar algum bloco de codigo + que verifique se o computador está + apto a enviar emails (independente + se os dados fornecidos estão corretos) + + if ?????? then + ?????? + else + minetest.show_formspec(name, "gestor:aviso", "size[4,1.8]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;AVISO \nFalta o software sendEmail \nno computador para usar \no Sistema de Email]" + ) + minetest.after(2, gestor.menu_principal, name) + return + end + + ]] + --gestor.bd:salvar("anticrash", "status_email", "true") + end + + -- Verificar sistema de backup + if fields.status_backup = "Ativo" then + --[[ + EM DESENVOLVIMENTO + Deve criar algum bloco de codigo + que verifique se o computador está + apto a enviar compactar em tar.gz + + if ?????? then + ?????? + else + minetest.show_formspec(name, "gestor:aviso", "size[4,1.8]".. + default.gui_bg.. + default.gui_bg_img.. + "label[0,0;AVISO \nFalta um compactador\nno computador para usar \no Sistema de Backups]" + ) + minetest.after(2, gestor.menu_principal, name) + return + end + + ]] + --gestor.bd:salvar("anticrash", "status_backup", "true") + end + + minetest.after(2, gestor.menu_principal, name) + return + + elseif fields.iniciar then + gestor.anticrash.iniciar() + end + end + end + + -- + -- Janelas de aviso e outros + -- + + -- Desligamento + if formname == "gestor:aviso_desligamento" then + local name = player:get_player_name() + + if fields.ok then + minetest.chat_send_all("*** Servidor desligando em 3 segundos. (Por "..name..")") + minetest.after(3, minetest.chat_send_all, "*** Servidor Desligado") + minetest.after(3, minetest.request_shutdown) + end + if fields.cancelar then + gestor.menu_principal(name) + end + end + + -- Construir Centro do Servidor + if formname == "gestor:aviso_construir_centro" then + local name = player:get_player_name() + + if fields.ok then + -- adquirindo dados + local pos = player:getpos() + local dados_estrutura = gestor.diretrizes.estruturas["centro"] + if not dados_estrutura then return minetest.chat_send_player(name, "Estrutura nao encontrada") end + local pos_c = {x=pos.x-(dados_estrutura[1]/2), y=pos.y-2, z=pos.z-(dados_estrutura[1]/2)} + local n_spawn = {x=pos.x, y=pos.y+2, z=pos.z} + -- Construir estrutura + if gestor.estruturador.carregar(pos_c, "centro") == false then return minetest.chat_send_player(name, "Estrutura nao encontrada") end + -- Proteger area da estrutura + local resp = gestor.proteger_area( + name, -- Quem registra + name, -- Quem vai ser o dono + "Centro", -- Nome(etiqueta) da area + {x=pos.x-(dados_estrutura[1]/2)-10, y=2000, z=pos.z-(dados_estrutura[1]/2)-10}, -- um dos cantos opostos + {x=pos.x+(dados_estrutura[1]/2)+10, y=pos.y-60, z=pos.z+(dados_estrutura[1]/2)+10} -- outro dos cantos opostos + ) + if resp ~= true then minetest.chat_send_player(name, "Falha ao proteger: "..resp) end + -- Salvar dados + minetest.setting_set("static_spawnpoint", pos.x.." "..(pos.y+10).." "..pos.z) + gestor.bd:salvar("centro", "pos", n_spawn) + gestor.bd:salvar("centro", "status", true) + -- Finalizando + player:moveto(n_spawn) + minetest.chat_send_player(name, "Centro construido e parcialmente definido. Configure a loja principal e o banco apenas. Recomendavel redefinir o spawn.") + end + if fields.cancelar then + gestor.menu_principal(name) + end + end + + -- Construir vila + if formname == "gestor:aviso_construir_vila" then + local name = player:get_player_name() + + if fields.ok then + -- Verificando se ja existe essa vila + local vila = escolha_vila[name] + if gestor.bd:verif("vilas", vila) then return minetest.chat_send_player(name, "Vila ja existente") end + -- Adquirindo dados + local pos = player:getpos() + local dados_estrutura = gestor.diretrizes.estruturas[vila] + if not dados_estrutura then return minetest.chat_send_player(name, "Estrutura nao encontrada") end + local pos_c = {x=pos.x-(dados_estrutura[1]/2), y=pos.y-2, z=pos.z-(dados_estrutura[1]/2)} + local n_spawn = {x=pos.x, y=pos.y+10, z=pos.z} + -- Construir estrutura + if gestor.estruturador.carregar(pos_c, vila) == false then return minetest.chat_send_player(name, "Estrutura nao encontrada") end + -- Proteger area da estrutura + local resp = gestor.proteger_area( + name, -- Quem registra + name, -- Quem vai ser o dono + fields.vila, -- Nome(etiqueta) da area + {x=pos.x-(dados_estrutura[1]/2)-10, y=2000, z=pos.z-(dados_estrutura[1]/2)-10}, -- um dos cantos opostos + {x=pos.x+(dados_estrutura[1]/2)+10, y=pos.y-60, z=pos.z+(dados_estrutura[1]/2)+10} -- outro dos cantos opostos + ) + if resp ~= true then minetest.chat_send_player(name, "Falha ao proteger: "..resp) end + -- Salvar dados + gestor.bd:salvar("vilas", vila, {nome=fields.nome_vila,pos=n_spawn}) + -- Finalizando + player:moveto(n_spawn) + minetest.chat_send_player(name, "*** Vila construida quase pronta. Ajuste as entradas da vila e o ponto de TP(spawn) perto da bilheteria. Configure lojas e bancos existentes.") + end + if fields.cancelar then + gestor.menu_principal(name) + end + end + + +end) + diff --git a/protetor.lua b/protetor.lua new file mode 100644 index 0000000..8ef3114 --- /dev/null +++ b/protetor.lua @@ -0,0 +1,42 @@ +-- +-- Mod gestor +-- +-- Protetor +-- + +-- Proteger uma area +gestor.proteger_area = function(name, PlayerName, AreaName, pos1, pos2, silencio) + if not tostring(PlayerName) or not tostring(AreaName) then return "Faltam argumentos ou estao incorretos" end + local param = tostring(PlayerName).." "..tostring(AreaName) + local found, _, ownername, areaname = param:find('^([^ ]+) (.+)$') + + if not found then + return "Incorrect usage, see /help set_owner" + end + + if pos1 and pos2 then + pos1, pos2 = areas:sortPos(pos1, pos2) + else + return "Você precisa selecionar a area primeiro" + end + + if not areas:player_exists(ownername) then + return "O jogador \""..ownername.."\" não existe." + end + + minetest.log("action", name.." runs /set_owner. Owner = "..ownername.. + " AreaName = "..areaname.. + " StartPos = "..minetest.pos_to_string(pos1).. + " EndPos = " ..minetest.pos_to_string(pos2)) + + local id = areas:add(ownername, areaname, pos1, pos2, nil) + areas:save() + + if silencio == nil or silencio == false then + minetest.chat_send_player(ownername, + "Voce registrou essa area para o jogador #".. + id..". Use /lista para ver as areas.") + minetest.chat_send_player(name, "Area protected. ID: "..id) + end + return true +end