commit 029d135a6e3a2e715dde7bc6fab51f2cffc3106c Author: Jonathan jegouzo Date: Thu Oct 4 21:52:03 2012 +0200 Initial publication diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ebd21a --- /dev/null +++ b/.gitignore @@ -0,0 +1,163 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results +[Dd]ebug/ +[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds +*.dotCover + +## TODO: If you have NuGet Package Restore enabled, uncomment this +#packages/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Installshield output folder +[Ee]xpress + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML + + + +############ +## Windows +############ + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# Mac crap +.DS_Store diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..cb0e95d --- /dev/null +++ b/README.txt @@ -0,0 +1,51 @@ +Minetest 0.4 mod: factions v0.1 +=============================== + +License of source code: +----------------------- +Copyright (C) 2011-2012 Jonjeg + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +http://www.gnu.org/licenses/lgpl-2.1.html + +Dependancies +------------ +This mod require my other mod localisation, you can find it at https://github.com/Jonjeg/localisation. + +Language support +---------------- +EN,FR + +Description: +------------ +This mod allow players to group as factions,it can be useful for pvp. +Anyone can create his faction. +Faction got a name, a public description, a creation date, a faction channel and can be free to join or private(private par default). +The creator of a faction can kick someone from the faction,invite players in the faction,change the faction description and the access to the faction. +The factions are stored in a txt file in the mod folder and are saved currently each 5min. +These settings can be modified in init.lua in the mod folder. + +Usage: +------ + +type /help faction for help on commands + +/faction create -> create your faction +/faction list -> list of all factions +/faction info -> info on the faction +/faction join -> join the faction +/faction leave -> leave your current faction + +Faction administration +---------------------- + +/faction kick -> kick the player from your faction +/faction invite -> the player join your faction +/faction disband -> disband the faction +/faction set_free -> allow the players to join freely +/faction description -> change the description text of your faction +/f for speaking in the faction channel. \ No newline at end of file diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..7ff98d0 --- /dev/null +++ b/depends.txt @@ -0,0 +1,2 @@ +default +localisation \ No newline at end of file diff --git a/factions.txt b/factions.txt new file mode 100644 index 0000000..e69de29 diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..8985eb4 --- /dev/null +++ b/init.lua @@ -0,0 +1,440 @@ +-- FACTIONS +factions = {} +factions.intervale_between_save_in_seconds = 300 -- 5minutes +factions.faction_file_path = minetest.get_modpath("factions").."/factions.txt"; + +-- localisation +dofile(minetest.get_modpath("factions").."/localisation.lua") + +-- datas +factions.factions_list = {} +factions.player_to_faction = {} + +-- Prototype definition + +function factions.factory_faction(name_val,fondateur_name_val,date_creation_val,description_val) + return { + name = name_val, + fondateur = fondateur_name_val, + date_creation = date_creation_val, + description = description_val, + free_to_join = false, + players = {}, + } +end + +-- DATA STORAGE + +function factions.save_datas() + local file,err = io.open(factions.faction_file_path,"w+") + local separateur = "|" + for k,faction in pairs(factions.factions_list) do + file:write(faction["name"],separateur,faction["fondateur"],separateur,faction["date_creation"],separateur,faction["description"],separateur,tostring(faction["free_to_join"]),separateur); + for k,player_name in ipairs(faction["players"]) do + file:write(player_name,separateur) + end + end + io.close(file) +end + +function factions.read_datas() + local nb_param_before_player_list = 6 + local file,err = io.open(factions.faction_file_path,"r") + if file ~= nil then -- File exists + for line in file:lines() do + local players = {} + local faction_info = {} + local k = 1 + for info in string.gmatch(line, "(.-)|") do + if k < nb_param_before_player_list then + table.insert(faction_info,info) + else + table.insert(players,info) + end + k = k+1 + end + factions.factions_list[faction_info[1]] = factions.factory_faction(faction_info[1],faction_info[2],faction_info[3],faction_info[4]) + factions.factions_list[faction_info[1]]["players"] = players + for k,p in pairs(players) do + factions.player_to_faction[p] = faction_info[1] + end + end + else -- File do not exists + io.close(io.open(factions.faction_file_path,"w+")) + factions.read_datas() + end +end + +function factions.auto_save() + minetest.log("action","Factions mod : sauvegarde des informations de factions dans "..factions.faction_file_path) + factions.save_datas() + minetest.after(factions.intervale_between_save_in_seconds, factions.auto_save) +end + +factions.read_datas() +factions.auto_save() + +-- Access to data + +function factions.get_faction(faction_name) + return factions.factions_list[faction_name] +end + +function factions.is_faction_exist(faction_name) + return (factions.get_faction(faction_name) ~= nil) +end + +function factions.is_free_to_join(faction_name) + if factions.is_faction_exist(faction_name) then + return factions.factions_list[faction_name]["free_to_join"] + else + return false + end +end + +function factions.get_fondateur_of_faction(faction_name) + if factions.is_faction_exist(faction_name) then + return factions.factions_list[faction_name]["fondateur"] + else + return nil + end +end + +function factions.get_description_of_faction(faction_name) + if factions.is_faction_exist(faction_name) then + return factions.factions_list[faction_name]["description"] + else + return nil + end +end + +function factions.get_faction_name_of_player(player_name) + return factions.player_to_faction[player_name] +end + +function factions.is_player_in_faction(player_name) + return (factions.get_faction_name_of_player(player_name) ~= nil) +end + +-- PRIVS + +-- FUNCTIONS + +function factions.chat_send_faction_message(faction_name,msg) + if not factions.is_faction_exist(faction_name) then -- Inexistant faction + minetest.chat_send_player(player_name,localisation.translate("factions:inexistant_faction",faction_name)) + return false + else + for key,player_name in ipairs(factions.factions_list[faction_name]["players"]) do + minetest.chat_send_player(player_name,"[/F] "..msg) + end + end +end + +function factions.register_player_joining_faction(faction_name,player_name,operateur) + if not factions.is_faction_exist(faction_name) then + minetest.chat_send_player(operateur,localisation.translate("factions:inexistant_faction",faction_name)) + return false + end + if not factions.is_player_in_faction(player_name) then + factions.player_to_faction[player_name] = faction_name + table.insert(factions.factions_list[faction_name]["players"],player_name) + factions.chat_send_faction_message(faction_name,localisation.translate("factions:player_join_faction",player_name,faction_name)) + else + if factions.get_faction_name_of_player(player_name) == faction_name then + if player_name == operateur then + minetest.chat_send_player(operateur, localisation.translate("factions:self_already_in_faction")) + else + minetest.chat_send_player(operateur, localisation.translate("factions:already_in_faction",player_name)) + end + else + minetest.chat_send_player(operateur, localisation.translate("factions:already_in_another_faction",factions.player_to_faction[player_name])) + end + end +end + +function factions.register_player_leaving_faction(faction_name,player_name,operateur) + if not factions.is_faction_exist(faction_name) then + minetest.chat_send_player(operateur,localisation.translate("factions:inexistant_faction",faction_name)) + return false + end + if factions.is_player_in_faction(player_name) and factions.get_faction_name_of_player(player_name) == faction_name then + for k,p in pairs(factions.player_to_faction) do + if k == player_name then + factions.player_to_faction[player_name] = nil + factions.chat_send_faction_message(faction_name,localisation.translate("factions:player_quit_faction",player_name,faction_name)) + minetest.chat_send_player(player_name,localisation.translate("factions:player_quit_faction",player_name,faction_name)) + break + end + end + for k,p in ipairs(factions.factions_list[faction_name]["players"]) do + if p == player_name then + table.remove(factions.factions_list[faction_name]["players"],k) + break + end + end + else + if not factions.is_player_in_faction(player_name) then + if player_name == operateur then + minetest.chat_send_player(operateur, localisation.translate("factions:self_no_faction")) + else + minetest.chat_send_player(operateur, localisation.translate("factions:no_faction",player_name)) + end + else + minetest.chat_send_player(operateur, localisation.translate("factions:already_in_another_faction",factions.player_to_faction[player_name])) + end + end +end + +function factions.register_faction(name,fondateur_name) + if not factions.is_faction_exist(name) and not factions.is_player_in_faction(fondateur_name) then + factions.factions_list[name] = factions.factory_faction(name,fondateur_name,os.date("!%c"),"Created by "..fondateur_name) + minetest.chat_send_all(localisation.translate("factions:create_faction",name,fondateur_name)) + factions.register_player_joining_faction(name,fondateur_name) + else + if factions.is_faction_exist(name) then + minetest.chat_send_player(fondateur_name,localisation.translate("factions:existant_faction",name)) + else -- Creator already in faction + minetest.chat_send_player(fondateur_name, localisation.translate("factions:already_in_another_faction",factions.player_to_faction[fondateur_name])) + end + end +end + +function factions.disband_faction(name,fondateur_name) + if factions.is_faction_exist(name) and factions.is_player_in_faction(fondateur_name) then + minetest.chat_send_all(localisation.translate("factions:delete_faction",name,fondateur_name)) + --local f_index = 1 + for f_name,f in pairs(factions.factions_list) do + if f["name"] == name then + for i,p in ipairs(factions.factions_list[name]["players"]) do + factions.register_player_leaving_faction(name,p,fondateur_name) + end + factions.factions_list[f_name] = nil + break + end + --f_index = f_index + 1 + end + end +end + +-- CHAT COMMANDS + +minetest.register_chatcommand("faction", { + params = "create "..localisation.translate("factions:help_info_create").."\n" + .."info : "..localisation.translate("factions:help_info_info").."\n" + .."list : "..localisation.translate("factions:help_info_list").."\n" + .."join : "..localisation.translate("factions:help_info_join").."\n" + .."leave: "..localisation.translate("factions:help_info_leave").."\n" + .."Faction Admin\n" + .."kick : "..localisation.translate("factions:help_info_kick").."\n" + .."invite : "..localisation.translate("factions:help_info_invite").."\n" + .."disband : "..localisation.translate("factions:help_info_disband").."\n" + .."set_free : "..localisation.translate("factions:help_info_set_free").."\n" + .."description : "..localisation.translate("factions:help_info_description").."\n" + , + description = localisation.translate("factions:help_description"), + privs = {}, + func = function(name, param) + local parameters = {string.match(param,"^([^ ]+)%s?(.*)")} + if parameters == nil then + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Action name like create, info")) + else + local action = parameters[1] + if action == "create" then + local faction_name = parameters[2] + if faction_name ~= nil then + factions.register_faction(faction_name,name,name) + else + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Faction name")) + end + return true + end + if action == "disband" then + local faction_name = factions.get_faction_name_of_player(name) + if faction_name ~= nil then + if factions.get_fondateur_of_faction(faction_name) == name then + factions.disband_faction(faction_name,name,name) + else + minetest.chat_send_player(name, localisation.translate("factions:insufficient_privilege")) + end + else + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Faction name")) + end + return true + end + if action == "list" then + local faction_list = {} + for k,f in pairs(factions.factions_list) do + table.insert(faction_list,k) + end + if #faction_list ~= 0 then + minetest.chat_send_player(name,"Factions("..#faction_list..") : "..table.concat(faction_list,",")) + else + minetest.chat_send_player(name,localisation.translate("factions:no_faction_registered")) + end + return true + end + if action == "info" then + local faction_name = parameters[2] + if faction_name ~= "" then + if factions.is_faction_exist(faction_name) then + local str = "" + for key,par in pairs(factions.factions_list[faction_name]) do + if key == "players" then + str = str..key.." = "..table.concat(par,",") + else + str = str..key.." = "..tostring(par) + end + str = str.."\n" + end + minetest.chat_send_player(name,str) + else + minetest.chat_send_player(name,localisation.translate("factions:inexistant_faction",faction_name)) + end + else + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Faction name")) + end + return true + end + if action == "join" then + local faction_name = parameters[2] + if faction_name ~= "" then + if factions.is_free_to_join(faction_name) then + factions.register_player_joining_faction(faction_name,name,name) + else + minetest.chat_send_player(name,localisation.translate("factions:not_free_to_join",faction_name)) + end + else + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Faction name")) + end + return true + end + if action == "leave" then + local faction_name = factions.get_faction_name_of_player(name) + if faction_name ~= nil then + factions.register_player_leaving_faction(faction_name,name,name) + else + minetest.chat_send_player(name, localisation.translate("factions:self_no_faction")) + end + return true + end + if action == "invite" then + local faction_name = factions.get_faction_name_of_player(name) + local player_to_invite = parameters[2] + if faction_name ~= nil and faction_name == factions.get_faction_name_of_player(name) then + if player_to_invite ~= "" and factions.get_fondateur_of_faction(faction_name) == name then + factions.register_player_joining_faction(faction_name,player_to_invite,name) + factions.chat_send_faction_message(faction_name,localisation.translate("factions:player_invited",player_to_invite,name)) + else + if factions.get_fondateur_of_faction(faction_name) == name then + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Player name")) + else + minetest.chat_send_player(name, localisation.translate("factions:insufficient_privilege")) + end + end + else + minetest.chat_send_player(name, localisation.translate("factions:self_no_faction")) + end + return true + end + if action == "kick" then + local faction_name = factions.get_faction_name_of_player(name) + local player_to_kick = parameters[2] + if faction_name ~= nil and faction_name == factions.get_faction_name_of_player(name) then + if player_to_kick ~= "" and factions.get_fondateur_of_faction(faction_name) == name then + factions.chat_send_faction_message(faction_name,localisation.translate("factions:player_kicked",player_to_kick,name)) + factions.register_player_leaving_faction(faction_name,player_to_kick,name) + else + if factions.get_fondateur_of_faction(faction_name) == name then + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Player name")) + else + minetest.chat_send_player(name, localisation.translate("factions:insufficient_privilege")) + end + end + else + minetest.chat_send_player(name, localisation.translate("factions:self_no_faction")) + end + return true + end + if action == "description" then + local faction_name = factions.get_faction_name_of_player(name) + local desc = parameters[2] + if factions.is_faction_exist(faction_name) and factions.get_fondateur_of_faction(faction_name) == name then + factions.factions_list[faction_name]["description"] = desc + minetest.chat_send_all(localisation.translate("factions:new_faction_description",desc)) + else + minetest.chat_send_player(name, localisation.translate("factions:insufficient_privilege")) + end + return true + end + if action == "set_free" then + local faction_name = factions.get_faction_name_of_player(name) + if factions.is_faction_exist(faction_name) and factions.get_fondateur_of_faction(faction_name) == name then + factions.factions_list[faction_name]["free_to_join"] = not factions.factions_list[faction_name]["free_to_join"] + if factions.is_free_to_join(faction_name) then + minetest.chat_send_all(localisation.translate("factions:allow_free_join_true",faction_name)) + else + minetest.chat_send_all(localisation.translate("factions:allow_free_join_false",faction_name)) + end + else + minetest.chat_send_player(name, localisation.translate("factions:insufficient_privilege")) + end + return true + end + if action == "save" then + if minetest.check_player_privs(name, {server=true}) then + factions.save_datas() + else + minetest.chat_send_player(name, localisation.translate("factions:insufficient_privilege")) + end + return true + end + if action == nil then + if factions.is_player_in_faction(name) then + local faction_name = factions.get_faction_name_of_player(name) + if faction_name ~= "" then + if factions.is_faction_exist(faction_name) then + local str = "" + for key,par in pairs(factions.factions_list[faction_name]) do + if key == "players" then + str = str..key.." = "..table.concat(par,",") + else + str = str..key.." = "..tostring(par) + end + str = str.."\n" + end + minetest.chat_send_player(name, localisation.translate("factions:current_faction",faction_name)) + minetest.chat_send_player(name,str) + else + minetest.chat_send_player(name,localisation.translate("factions:inexistant_faction",faction_name)) + end + else + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Faction name")) + end + return true + else + minetest.chat_send_player(name, localisation.translate("factions:self_no_faction")) + return true + end + end + if action ~= "" and action ~= nil then + minetest.chat_send_player(name,localisation.translate("factions:missing_argument","Action name")) + return true + end + end + end, +}) + +minetest.register_chatcommand("f", { + params = "", + description = "Faction channel", + privs = {}, + func = function(name,param) + local faction_name = factions.player_to_faction[name] + if faction_name ~= nil then + factions.chat_send_faction_message(faction_name,param) + else + minetest.chat_send_player(name,localisation.translate("factions:self_no_faction")) + end + end, +}) \ No newline at end of file diff --git a/localisation.lua b/localisation.lua new file mode 100644 index 0000000..3bc10b6 --- /dev/null +++ b/localisation.lua @@ -0,0 +1,73 @@ +local message = { + EN = { + help_description = "Commandes linked to factions", + help_info_create = "Create your faction.", + help_info_list = "Display the list of the registered factions on this server.", + help_info_invite = "The player supplied is now a member of your faction.", + help_info_disband = "Disband the faction.", + help_info_description = "Set the description with the text supplied", + help_info_set_free = "(Dis)Allows everyone to join your faction.", + help_info_info = "Display informations about the faction", + help_info_join = "You join the faction, if it exist.", + help_info_leave = "You leave your current faction.", + help_info_kick = "You kick the player from your faction.", + create_faction = "The faction '$1' has been created by $2.", + inexistant_faction = "The faction '$1' don't exist.", + existant_faction = "The faction '$1' exist already.", + delete_faction = "The faction '$1' was disbanded by $2.", + not_free_to_join = "You need to be invited by '$1' for joining them", + allow_free_join_true = "The faction $1 now allows players to freely join them", + allow_free_join_false = "The faction $1 is now a private faction.", + new_faction_description = "The faction $1 got a new description : $2", + player_join_faction = "$1 joined the faction $2", + player_quit_faction = "$1 left the faction $2", + player_invited = "$1 has been invited in the faction by $2", + player_kicked = "$1 has been kicked from the faction by $2", + self_already_in_faction = "You already belong to this faction", + already_in_faction = "$1 already belong to this faction", + already_in_another_faction = "You belong to an another faction : $1. Quit it for join a new one.", + self_no_faction = "You don't belong to a faction", + no_faction = "$1 don't belong to a faction", + missing_argument = "Missing arguments : $1", + no_faction_registered = "There is no faction registered yet.", + insufficient_privilege = "Your privileges are insufficient.", + current_faction = "Current faction : $1", + inexistant_player = "This player don't exist or is offline.", + }, + FR = { + help_description = "Commandes liées aux factions.", + help_info_create = "Crée votre faction.", + help_info_list = "Affiche la liste des factions de ce serveur.", + help_info_invite = "Integre le joueur à votre faction.", + help_info_disband = "Dissout la faction.", + help_info_description = "Etablis la nouvelle description de votre faction", + help_info_set_free = "(Des)Autorise tout le monde à rejoindre votre faction.", + help_info_info = "Affiche des informations à propos de la faction.", + help_info_join = "Vous rejoignez la faction, si elle existe.", + help_info_leave = "Vous quittez votre faction actuelle.", + help_info_kick = "Vous expulsez ce joueur de votre faction.", + create_faction = "La faction $1 vient d'être créee par $2", + inexistant_faction = "La faction $1 n'existe pas.", + existant_faction = "La faction $1 existe déjà.", + delete_faction = "La faction $1 a été dissoute par $2.", + not_free_to_join = "Vous ne pouvez rejoindre $1 que sur invitation de leur part.", + allow_free_join_true = "La faction $1 est désormais ouverte à tous les joueurs.", + allow_free_join_false = "La faction $1 est désormais privée.", + new_faction_description = "La faction $1 a une nouvelle description : $2", + player_join_faction = "$1 vient de rejoindre la faction $2.", + player_quit_faction = "$1 vient de quitter la faction $2.", + player_invited = "$1 a été invité dans la faction par $2.", + player_kicked = "$1 a été expulsé de la faction par $2.", + self_already_in_faction = "Vous appartenez déja à cette faction.", + already_in_faction = "$1 appartient déja à cette faction.", + already_in_another_faction = "Vous appartenez déja à une autre faction : $1. Quittez la pour en rejoindre une nouvelle.", + self_no_faction = "Vous n'appartenez à aucune faction.", + no_faction = "$1 n'appartient a aucune faction.", + missing_argument = "Arguments manquant : $1.", + no_faction_registered = "Il n'existe aucune faction pour le moment.", + insufficient_privilege = "Vous ne possèdez pas les privilèges requis.", + current_faction = "Faction actuelle : $1.", + inexistant_player = "Ce joueur n'existe pas ou est non connecté.", + }, +} +localisation.register_translations("factions", message) \ No newline at end of file