Ir para conteúdo

Advanced Guild System


Omega

Posts Recomendados

Bom, eu percebi que algo que poderia deixar os servidores bem legais seria um foco maior nas guilds em si. Então, resolvi criar um sistema que fosse melhorar isso, e surgiu o Advanced Guild System.

Atualizações

  • 22/01/14 - Publicação da versão 1.0
  • 21/04/14 - Adição de mais tratamento de erros

Informações
O AGS, em si, não faz nada. Isso mesmo. Ele é uma biblioteca com várias funções focadas para guilds. Além disso, ele também faz algumas modificações no seu banco de dados ao ser instalado:

  • Cria a tabela guild_storages;
  • Adiciona a coluna pontos na tabela guilds, se ela não existir;
  • Adiciona a coluna balance na tabela guilds, se ela não existir;
  • Adiciona a coluna guild_id na tabela players;
  • Adiciona um gatilho(trigger) para atualizar a coluna guild_id toda vez que ocorrer uma mudança na tabela guilds.

Para acompanhar essa biblioteca e mostrar sua utilidade, fiz alguns sistemas utilizando ela:

Funções

 

  • installAdvancedGuildSystem()

Cria as colunas e tabelas necessárias para o pleno funcionamento do sistema. Além disso, muda o valor do global storage 50050 para 1 e envia uma mensagem sobre o status da atualização.

  • updateGuildColumn()

Força a atualização da coluna guild_id da tabela players e envia uma mensagem com o status da atualização

  • isAGSInstalled

Uma variável que retorna verdadeiro se o sistema tiver sido instalado corretamente

  • getGuildPoints(guild_id)

Retorna a quantidade de pontos de uma guilda

  • doGuildAddPoints(guild_id, value)

Adiciona ou subtrai pontos de uma guilda (para subtrair, basta usar um valor negativo)

  • hasGuild(cid)

Retorna verdadeiro caso o jogador esteja em uma guilda

  • isInGuild(cid, guildId)

Retorna verdadeiro caso o jogador esteja na guilda especificada

  • getGuildName(guild_id)

Retorna o nome de uma guilda pelo seu id

  • getGuildMembersGUID(guild_id)

Retorna uma tabela com os ids(GUIDs) de todos os jogadores em uma guilda

  • getPlayerGuildIdByGUID(guid)

Retorna o Id da guilda de um jogador pelo seu Id(GUID)

  • getOnlineGuildMembersByRank(guildId[, rank[, selectLowerRanks]])

Retorna uma tabela com os cids de todos os jogadores online de uma guilda por um certo rank. Ambos os parâmetros são opcionais: caso o rank não seja especificado, retornará todos os jogadores online de uma guilda. O parâmetro selectLowerRanks indica se a função deverá retornar os jogadores com rank abaixo também e tem valor padrão falso

  • doFunctionOnGuildMembers(guildId, func)

Executa a função especificada em todos os jogadores online de uma guilda. A função especificada deve conter apenas um parâmetro(cid). Pode ser usada para, por exemplo, enviar uma mensagem para todos os jogadores de uma guild:

doFunctionOnGuildMembers(guild, function(cid)	doPlayerSendTextMessage(cid, 27, "Um grande ola a todos os membros da guilda!")end)
  • setGuildStorageValue(guild_id, key, value)

Essa função introduz o sistema de guild storages, funciona igual aos player storages, mas é específico para uma guilda. Essa função muda o valor de uma storage especificada por key

  • getGuildStorageValue(guild_id, key)

Retorna o valor de uma guild storage especificada por key

  • getGuildBalance(guild_id)

Retorna o balanço(saldo) bancário de uma guilda

  • setGuildBalance(guild_id, value)

Modifica o balanço bancário de uma guilda

  • doGuildAddBalance(guild_id, value)

Adiciona ao balanço bancário de uma guilda



Instalação


Basta chamar a função installAdvancedGuildSystem em qualquer script. Por exemplo, use a talkaction abaixo, salvando-a como installAGS.lua:

function onSay(cid, words, param)	installAdvancedGuildSystem()end

Registre em talkactions.xml:
Verifique se o sitema foi instalado corretamente na janela do executável



Código
Salve-o como guildlib.lua em data/lib

 

--[[ Queries:
		CREATE TABLE `guild_storages` (
		`guild_id` int NOT NULL default 0,
		`key` int NOT NULL default 0,
		`value` varchar(255) NOT NULL default 0
		);
		
		CREATE TRIGGER `guilds_update`
			AFTER UPDATE OF rank_id ON players
		BEGIN
			UPDATE players
			   SET guild_id = IFNULL( ( 
					   SELECT guild_id
						 FROM guild_ranks
						WHERE id = rank_id 
				   ) 
				   , 0 );
		END;
		
		ALTER TABLE guilds ADD points INT DEFAULT 0 NOT NULL
		ALTER TABLE guilds ADD balance BIGINT default 0 NOT NULL
		ALTER TABLE players ADD guild_id INT DEFAULT 0 NOT NULL
		UPDATE players SET guild_id = IFNULL((SELECT guild_id FROM guild_ranks WHERE id = rank_id), 0)
]]

-- Advanced Guild System maintenance functions

function installAdvancedGuildSystem()
    local func = db.query or db.executeQuery
    local query = db.getResult("SELECT balance FROM guilds")
    if query:getID() == -1 then
        func("ALTER TABLE guilds ADD balance INT default 0 NOT NULL")
    else
        query:free()
    end
    local query2 = db.getResult("SELECT points FROM guilds;")
    if query:getID() == -1 then
        func("ALTER TABLE guilds ADD points INT DEFAULT 0 NOT NULL")
    else
        query2:free()
    end
    if func("ALTER TABLE players ADD guild_id INT DEFAULT 0 NOT NULL") then
        if func("UPDATE players SET guild_id = IFNULL((SELECT guild_id FROM guild_ranks WHERE `id` = rank_id), 0)") then
            if func("CREATE TABLE `guild_storages` (`guild_id` INT NOT NULL DEFAULT 0, `key` INT NOT NULL DEFAULT 0, `value` VARCHAR(255) NOT NULL DEFAULT 0);") then
                if func("CREATE TRIGGER [`rank_id update`] AFTER UPDATE OF rank_id ON players BEGIN UPDATE players SET guild_id = IFNULL((SELECT guild_id FROM guild_ranks WHERE `id` = rank_id), 0); END;") then
                    setGlobalStorageValue(50050, 1)
                    print("Advanced Guild System installation successful.")
                    return true
                end
            end
        end
    end
    print("Advanced Guild System could NOT be installed.")
    return false
end

function updateGuildColumn()
	print("Updating guild column in players table...")
	local func = db.query or db.executeQuery
	local str = "failure."
	if func("UPDATE players SET guild_id = IFNULL((SELECT guild_id FROM guild_ranks WHERE `id` = rank_id),0)") then
		str = "success!"
	end
	print("Update was a "..str)
end

isAGSInstalled = getGlobalStorageValue(50050) == 1

-- Guild Points functions

function getGuildPoints(guild_id)
	local ret = db.getResult("SELECT points FROM guilds WHERE id = " .. guild_id)
	if ret:getID() == -1 then
		return -1
	end
	return ret:getDataInt("points")
end

function doGuildAddPoints(guild_id, value)
	local func = db.executeQuery or db.query
	return func("UPDATE guilds SET points = ("..value.." + (SELECT points FROM guilds WHERE id = "..guild_id..")) WHERE id = "..guild_id)
end

-- General guild functions

function hasGuild(cid)
	return getPlayerGuildId(cid) > 0
end

function isInGuild(cid, guildId)
	return getPlayerGuildId(cid) == guildId
end

function getGuildName(guild_id)
	local query = db.getResult("SELECT name FROM guilds WHERE id = "..guild_id)
	local ret = query:getID() == -1 and false or query:getDataString("name")
	query:free()
	return ret
end

function getGuildMembersGUID(guild_id)
	if db.getResult("SELECT ownerid FROM guilds WHERE id = "..guild_id):getID() > -1 then
		local members = {}
		local query = db.getResult("SELECT `id` FROM players WHERE guild_id = "..guild_id)
		if query:getID() == -1 then
			return false
		end
		repeat
			local member = query:getDataInt("id")
			table.insert(members, member)
		until not query:next()
		query:free()
		return members
	end
	return false
end

function getPlayerGuildIdByGUID(guid)
	local query = db.getResult("SELECT guild_id FROM players WHERE id = "..guid)
	return query:getDataInt("guild_id")
end

function getOnlineGuildMembersByRank(guildId, rank, selectLowerRanks)
	if not rank then
		rank = 3
		selectLowerRanks = true
	end
	local list = {}
	for _, pid in pairs(getPlayersOnline()) do
		if getPlayerGuildId(pid) == guildId then
			local playerRank = getPlayerGuildLevel(pid)
			if playerRank == rank or (selectLowerRanks and playerRank <= rank) then
				table.insert(list, pid)
			end
		end
	end
	return list
end

function doFunctionOnGuildMembers(guildId, func)
	local players = getPlayersOnline()
	local count = 0
	for _, pid in pairs(players) do
		if getPlayerGuildId(pid) == guildId then
			func(pid)
			count = count + 1
		end
	end
	return count
end

-- Guild Storage functions

function setGuildStorageValue(guild_id, key, value)
	local func = db.executeQuery or db.query
	local query = db.getResult("SELECT `value` FROM guild_storages WHERE `key` = "..key.." AND guild_id = "..guild_id)
	if query:getID() == -1 then
		return func("INSERT INTO guild_storages (guild_id, `key`, `value`) VALUES ("..guild_id..", "..key..", "..value..")")
	end
	return func("UPDATE guild_storages SET `value` = "..value.." WHERE `key` = "..key.." AND guild_id = "..guild_id)
end

function getGuildStorageValue(guild_id, key)
	local ret = db.getResult("SELECT `value` FROM guild_storages WHERE guild_id = "..guild_id.." AND `key` = "..key)
	if ret:getID() == -1 then
		return -1
	end
	return ret:getDataInt("value") or ret:getDataString("value")
end

-- Guild Balance functions

function getGuildBalance(guild_id)
	local balance = db.getResult("SELECT balance FROM guilds WHERE `id` = "..guild_id)
	local ret = balance:getID() >= 0 and balance:getDataInt("balance") or false
	balance:free()
	return ret
end

function setGuildBalance(guild_id, value)
	local func = db.executeQuery or db.query
	func("UPDATE guilds SET balance = "..value.." WHERE `id` = "..guild_id)
	return true
end

function doGuildAddBalance(guild_id, value)
	local func = db.executeQuery or db.query
	func("UPDATE guilds SET balance = (SELECT balance FROM guilds WHERE `id` = "..guild_id..") + "..value.." WHERE `id` = "..guild_id)
	return true
end

 




Problemas na Instalação?
Caso uma ou mais das colunas adicionadas já existam no seu banco de dados, execute as queries manualmente:


 

CREATE TABLE `guild_storages` (`guild_id` int NOT NULL default 0, `key` int NOT NULL default 0,	`value` varchar(255) NOT NULL default 0);

 


 

CREATE TRIGGER guilds_update AFTER UPDATE OF rank_id ON players	BEGIN UPDATE players SET guild_id = IFNULL( (SELECT guild_id FROM guild_ranks WHERE id = rank_id ), 0 ); END;

 


 

ALTER TABLE guilds ADD points INT DEFAULT 0 NOT NULL;
ALTER TABLE guilds ADD balance BIGINT default 0 NOT NULL;
ALTER TABLE players ADD guild_id INT DEFAULT 0 NOT NULL;
UPDATE players SET guild_id = IFNULL((SELECT guild_id FROM guild_ranks WHERE `id` = rank_id), 0);

 




Depois disso, considere seu AGS instalado.

Editado por Omega
Link para o comentário
Compartilhar em outros sites

Ótimas funções, Omega!

Com um pouco de conhecimento e de imaginação, da para criar vários sistemas bem legais com isso.

Eu mesmo já pensei em 2 que irei criar para meu servidor!

Link para o comentário
Compartilhar em outros sites

Boooa Omega!! O Guild tasks e Banqueiro das guildas são scripts em andamento?

Eu vi o Guild Rank e gostei muito!

 

Mais uma vez, parabéns!

 

Obrigado, Alex.

Os dois já estavam terminados, mas eu pensei em mais coisas pro banqueiro e acabei refazendo muito mais completo e acabei de publicar. O Guild Tasks está pronto, mas quero terminar de fazer mais uns testes aqui.

Editado por Omega
Link para o comentário
Compartilhar em outros sites

Muito bom, To criando um scripter também.

 

To criando uma Spell que ta quase pronta, as funções dela são.....

 

• Heala quem ta na party

• Não heala que não ta na party

• Não ataka quem ta na party

• Não heala Quem não ta na Party

Link para o comentário
Compartilhar em outros sites

  • 2 weeks later...
  • 2 weeks later...

Omega, sistema muito bem elaborado e legal!! Já leva rep+ pela criatividade

 

Mas aqui ta dando um Erro

Quando eu escrevo /installAGS

 

[14/02/2014 22:08:50] [Error - TalkAction Interface]
[14/02/2014 22:08:50] data/talkactions/scripts/installAGS.lua:onSay
[14/02/2014 22:08:50] Description:
[14/02/2014 22:08:50] data/lib/004-database.lua:100: [Result:free] Result not set!
[14/02/2014 22:08:50] stack traceback:
[14/02/2014 22:08:50] [C]: in function 'error'
[14/02/2014 22:08:50] data/lib/004-database.lua:100: in function 'free'
[14/02/2014 22:08:50] data/lib/guildlib.lua:34: in function 'installAdvancedGuildSystem'
[14/02/2014 22:08:50] data/talkactions/scripts/installAGS.lua:2: in function
[14/02/2014 22:09:18] mysql_real_query(): ALTER TABLE guilds ADD balance BIGINT default 0 NOT NULL - MYSQL ERROR: Duplicate column name 'balance' (1060)

[14/02/2014 22:09:18] [Error - TalkAction Interface]
[14/02/2014 22:09:18] data/talkactions/scripts/installAGS.lua:onSay
[14/02/2014 22:09:18] Description:
[14/02/2014 22:09:18] data/lib/004-database.lua:100: [Result:free] Result not set!
[14/02/2014 22:09:18] stack traceback:
[14/02/2014 22:09:18] [C]: in function 'error'
[14/02/2014 22:09:18] data/lib/004-database.lua:100: in function 'free'
[14/02/2014 22:09:18] data/lib/guildlib.lua:34: in function 'installAdvancedGuildSystem'
[14/02/2014 22:09:18] data/talkactions/scripts/installAGS.lua:2: in function
[14/02/2014 22:09:29] Leoo has logged in.
[14/02/2014 22:09:38] [Error - MoveEvent::executeStep] Call stack overflow.
[14/02/2014 22:09:38] [Error - MoveEvent::executeStep] Call stack overflow.

 

 

Tu sabe oque poderia ser??

Editado por llucas75
Link para o comentário
Compartilhar em outros sites

  • 4 weeks later...

Fico muito bom, bem util inclusive.
Só um alerta, quanto ao uso de banco de dados, quando for usar consultas ao db tem que pensar tambem na quantidade de vezes que elas podem ser executadas in game, algumas funções ai pode ser usadas simultaneamente por diversos players, e pra cada um deles é uma consulta no banco de dados, isso pode crashar ele.

O ideal seria criar um meio de passar os dados do banco de dados para a memoria dinamica, que fosse uma tabela lua mesmo, daria mais agilidade tambem as consultas.

Tu pode fazer ate algo bem simples como uma tabela na lib, que tu atualiza de tempo em tempo no banco de dados, dessa forma nao teria tantas consultas e teria acesso mais rapido a informação e de forma mais "leve".

 

A estrutura dos dados em lua poderia ficar assim:

 

Guilds = {
    guild_storages = {
        [guild_id_1] = {key1=value1, ..., keyN=valueN};
        [guild_id_N] = {key1=value1, ..., keyN=valueN};
    };
    guilds = {
        [guild_id_1] = {points = 0, balance = 0};
        [guild_id_N] = {points = 0, balance = 0};
    };
}

 

Dai tu carrega ela toda vez que ligar o servidor, uma consulta so no banco de dados.

E salva ela de tempos em tempos, ai vai da estabilidade do servidor.

 

Um exemplo de uma das funções ai que tu usou, ficaria algo assim:

 

function getGuildStorageValue(guild_id, key)
    return Guilds.guild_storages[guild_id][key] -- obs.: só um exemplo, logico que nao seria tão direto, poderia dar erros de index.
end

 

E as de definir dados, tu simplesmente alteraria a tabela em lua, dai quando voce salvar a tabela em lua no db, tu atualiza.

Eu sei que parece meio trabalho e as vezes e até desnecessario, mas vai dar uma otima performance fazendo isso.

Só tem um porem, no banco de dados tu tem mais mobilidade pra colher os dados, mas ai vai de como tu monta a tabela em lua, e da pra fazer que nem no db, mas teria que usar uns loops dependendo do que for :D

Bom, de qualquer modo teu script ta excelente, meus parabéns! Otima ideia aliás,

Link para o comentário
Compartilhar em outros sites

  • 5 weeks later...

OMEGA o script é otimo mais aki ta dando error n ta dando pra instar olha o q aparece um monte de error que n ta dando pra min te mostrar pq o execultavel nn dexa copiar oq ta escrito laa maus aee la diz

 

[ERROR TALKACTION - INTERFACE]

Link para o comentário
Compartilhar em outros sites

  • 2 weeks later...

Rep +

 

Gostei, mais deu um erro aqui quando executei o comando: /installAGS

 

Versão 9.83

ZPeyh3T.png

 

Atualizei, pode tentar de novo que deve funcionar sem problemas.

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...