summaryrefslogblamecommitdiffstats
path: root/MCServer/Plugins/Core/console.lua
blob: df90a9b9aee1c8c245293e801813b51bc0045a94 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11










                                                 




                                                                                                                                     
                                                                                                                       

                                                                                                                                                   


                                                                                                                                                         
                                                                                                                                                



                                                                                                                                        





































                                                                                       
























                                                                        
                        
                                              

                                                                                                               
            











































                                                                                 














                                                                
                        
                                          
                                                                         

                                     
                                                        
         
                          












                                                                         
                                                                                                        



                                               
                        
                                                            
                                                             
                                                        
                                                                 


                    
                          









                                                                       
                                                                                                                             




                                                                 

















































                                                                                                                                













































                                                                                            
                                                                                              
                                                

                                                                                      

    




 

                                                                                            
 










                                                                             
            
                                           



    

 



                                                                




    

-- console.lua

-- Implements things related to console commands





function InitConsoleCommands()
	local PluginMgr = cPluginManager:Get();
	
	-- Please keep the list alpha-sorted
	PluginMgr:BindConsoleCommand("ban",                  HandleConsoleBan,                  "Bans a player by name");
	PluginMgr:BindConsoleCommand("banlist",              HandleConsoleBanList,              "Lists all players banned by name");
	PluginMgr:BindConsoleCommand("banlist ips",          HandleConsoleBanList,              "Lists all players banned by IP");
	PluginMgr:BindConsoleCommand("help",                 HandleConsoleHelp,                 "Lists all commands");
	PluginMgr:BindConsoleCommand("list",                 HandleConsoleList,                 "Lists all players in a machine-readable format");
	PluginMgr:BindConsoleCommand("listgroups",           HandleConsoleListGroups,           "Shows a list of all the groups");
	PluginMgr:BindConsoleCommand("numchunks",            HandleConsoleNumChunks,            "Shows number of chunks currently loaded");
	PluginMgr:BindConsoleCommand("players",              HandleConsolePlayers,              "Lists all connected players");
	PluginMgr:BindConsoleCommand("primaryserverversion", HandleConsolePrimaryServerVersion, "Gets or sets server version reported to 1.4+ clients");
	PluginMgr:BindConsoleCommand("rank",                 HandleConsoleRank,                 " [Player] [Group] - add a player to a group");
	PluginMgr:BindConsoleCommand("reload",               HandleConsoleReload,               "Reloads all plugins");
	PluginMgr:BindConsoleCommand("save-all",             HandleConsoleSaveAll,              "Saves all chunks");
	PluginMgr:BindConsoleCommand("say",                  HandleConsoleSay,                  "Sends a chat message to all players");
	PluginMgr:BindConsoleCommand("unload",               HandleConsoleUnload,               "Unloads all unused chunks");
end





function HandleConsoleBan(Split)
	if (#Split < 2) then
		return true, cChatColor.Green .. "Usage: /ban [Player] <Reason>";
	end

	local Reason = "You have been banned"
	if (#Split > 2) then
		Reason = table.concat(Split, " ", 3);
	end
	
	
	if (not(BanPlayer(Split[2], Reason))) then
		return true, cChatColor.Green .. "Could not find player " .. Split[2];
	end

	return true, "Player " .. Split[2] .. " has been banned.";
end





function HandleConsoleBanList(Split)
	if (#Split == 1) then
		return true, BanListByName();
	end
	
	if (string.lower(Split[2]) == "ips") then
		return true, BanListByIPs();
	end
	
	return true, "Unknown banlist subcommand";
end





function HandleConsoleHelp(Split)
	local Commands = {};   -- {index => {"Command", "HelpString"} }
	local MaxLength = 0;
	local AddToTable = function(Command, HelpString)
		table.insert(Commands, { Command, HelpString });
		local CmdLen = Command:len();
		if (CmdLen > MaxLength) then
			MaxLength = CmdLen;
		end
	end
	
	cPluginManager:Get():ForEachConsoleCommand(AddToTable);
	
	-- Sort the table:
	local CompareCommands = function(a, b)
		return a[1] < b[1];  -- compare command strings
	end
	table.sort(Commands, CompareCommands);
	
	local Out = "";
	for i, Command in ipairs(Commands) do
		Out = Out .. Command[1] .. string.rep(" ", MaxLength - Command[1]:len());  -- Align to a table
		Out = Out .. " - " .. Command[2] .. "\n";
	end
	return true, Out;
end





function HandleConsoleList(Split)
	-- Get a list of all players, one playername per line
	local Out = "";
	cRoot:Get():ForEachWorld(
		function (a_World)
			a_World:ForEachPlayer(
				function (a_Player)
					Out = Out .. a_Player:GetName() .. "\n";
				end
			);
		end
	);
	return true, Out;
end





function HandleConsoleListGroups(Split)
	-- Read the groups.ini file:
	local GroupsIni = cIniFile("groups.ini");
	if (not(GroupsIni:ReadFile())) then
		return true, "No groups found";
	end
	
	-- Read the groups:
	Number = GroupsIni:NumKeys();
	Groups = {};
	for i = 0, Number do
		table.insert(Groups, GroupsIni:KeyName(i))
	end
	
	-- Output the groups, concatenated to a string:
	local Out = "Groups:\n"
	Out = Out .. table.concat(Groups, ", ");
	return true, Out;
end





function HandleConsoleNumChunks(Split)
	local Output = {};
	local AddNumChunks = function(World)
		Output[World:GetName()] = World:GetNumChunks();
	end;
	
	cRoot:Get():ForEachWorld(AddNumChunks);
	
	local Total = 0;
	local Out = "";
	for name, num in pairs(Output) do
		Out = Out .. "  " .. name .. ": " .. num .. " chunks\n";
		Total = Total + num;
	end
	Out = Out .. "Total: " .. Total .. " chunks\n";
	
	return true, Out;
end





function HandleConsolePlayers(Split)
	local PlayersInWorlds = {};    -- "WorldName" => [players array]
	local AddToTable = function(Player)
		local WorldName = Player:GetWorld():GetName();
		if (PlayersInWorlds[WorldName] == nil) then
			PlayersInWorlds[WorldName] = {};
		end
		table.insert(PlayersInWorlds[WorldName], Player:GetName() .. " @ " ..  Player:GetIP());
	end
	
	cRoot:Get():ForEachPlayer(AddToTable);
	
	local Out = "";
	for WorldName, Players in pairs(PlayersInWorlds) do
		Out = Out .. "World " .. WorldName .. ":\n";
		for i, PlayerName in ipairs(Players) do
			Out = Out .. "  " .. PlayerName .. "\n";
		end
	end
	
	return true, Out;
end





function HandleConsolePrimaryServerVersion(Split)
	if (#Split == 1) then
		-- Display current version:
		local Version = cRoot:Get():GetPrimaryServerVersion();
		return true, "Primary server version: #" .. Version .. ", " .. cRoot:GetProtocolVersionTextFromInt(Version);
	end
	
	-- Set new value as the version:
	cRoot:Get():SetPrimaryServerVersion(tonumber(Split[2]));
	local Version = cRoot:Get():GetPrimaryServerVersion();
	return true, "Primary server version is now #" .. Version .. ", " .. cRoot:GetProtocolVersionTextFromInt(Version);
end





function HandleConsoleRank(Split)
	if (Split[2] == nil) or (Split[3] == nil) then
		return true, "Usage: /rank [Player] [Group]";
	end
	local Out = "";
	
	-- Read the groups.ini file:
	local GroupsIni = cIniFile("groups.ini")
	if (not(GroupsIni:ReadFile())) then
		Out = "Could not read groups.ini, creating anew!\n"
	end
	
	-- Find the group:
	if (GroupsIni:FindKey(Split[3]) == -1) then
		return true, Out .. "Group does not exist";
	end
	
	-- Read the users.ini file:
	local UsersIni = cIniFile("users.ini");
	if (not(UsersIni:ReadFile())) then
		Out = Out .. "Could not read users.ini, creating anew!\n";
	end
	
	-- Write the new group value to users.ini:
	UsersIni:DeleteKey(Split[2]);
	UsersIni:GetValueSet(Split[2], "Groups", Split[3]);
	UsersIni:WriteFile();
	
	-- Reload the player's permissions:
	cRoot:Get():ForEachWorld(
		function (World)
			World:ForEachPlayer(
				function (Player)
					if (Player:GetName() == Split[2]) then
						Player:SendMessage(cChatColor.Green .. "You were moved to group " .. Split[3]);
						Player:LoadPermissionsFromDisk();
					end
				end
			);
		end
	)

	return true, Out .. "Player " .. Split[2] .. " was moved to " .. Split[3];
end





function HandleConsoleReload(Split)
	Server = cRoot:Get():GetServer();
	Server:SendMessage(cChatColor.Green .. "Reloading all plugins.");
	cPluginManager:Get():ReloadPlugins();
	return true;
end





function HandleConsoleSaveAll(Split)
	cRoot:Get():SaveAllChunks();
	return true;
end





function HandleConsoleSay(Split)
	table.remove(Split, 1);
	local Message = "";
	for i, Text in ipairs(Split) do
		Message = Message .. " " .. Text;
	end
	Message = Message:sub(2);  -- Cut off the first space
	cRoot:Get():GetServer():BroadcastChat(cChatColor.Purple .. "[SERVER] " .. Message);
	return true;
end





function HandleConsoleUnload(Split)
	local UnloadChunks = function(World)
		World:UnloadUnusedChunks();
	end
	
	local Out = "Num loaded chunks before: " .. cRoot:Get():GetTotalChunkCount() .. "\n";
	cRoot:Get():ForEachWorld(UnloadChunks);
	Out = Out .. "Num loaded chunks after: " .. cRoot:Get():GetTotalChunkCount();
	return true, Out;
end






-------------------------------------------------------------------------------------------
-- Helper functions:

--- Returns the list of players banned by name, separated by ", "
function BanListByName()
	local NumValues = BannedPlayersIni:NumValues("Banned");
	local Banned = {};
	local KeyID = BannedPlayersIni:FindKey("Banned");
	for i = 1, NumValues do
		local PlayerName = BannedPlayersIni:ValueName(KeyID, i - 1);
		if (BannedPlayersIni:GetValueB("Banned", PlayerName)) then
			-- Player listed AND banned
			table.insert(Banned, PlayerName);
		end
	end
	return table.concat(Banned, ", ");
end





--- Returns the list of players banned by IP, separated by ", "
function BanListByIPs()
	-- TODO: No IP ban implemented yet
	return "";
end