diff --git a/plugins/core/permissions.lua b/plugins/core/permissions.lua index 4e3741e..9bed50d 100644 --- a/plugins/core/permissions.lua +++ b/plugins/core/permissions.lua @@ -253,7 +253,7 @@ PermissionsPlugin.CheckPermissionNotify = function(client, permission) end -- Operators bypass permissions - if (client:GetUserType() == 0x64) then -- operator + if (client:GetUserType() >= 0x64) then -- operator or higher return true end diff --git a/plugins/core/utils.lua b/plugins/core/utils.lua index 280f590..408db47 100644 --- a/plugins/core/utils.lua +++ b/plugins/core/utils.lua @@ -47,3 +47,7 @@ end WORLD_NOT_ACTIVE = function(name) return "&cWorld &f" .. name .. " &cnot active (unloaded)" end + +WORLD_ALREADY_EXISTS = function(name) + return "&cWorld &f" .. name .. " &calready exists" +end diff --git a/plugins/essentials/world.lua b/plugins/essentials/world.lua index 6446886..b280ee9 100644 --- a/plugins/essentials/world.lua +++ b/plugins/essentials/world.lua @@ -1,18 +1,18 @@ EssentialsPlugin.World = { Init = function() - local worldCmd = Server.AddCommand("luaworld", "lw", function() end, "world - various commands related to worlds", 1, 0) - local worldListCmd = worldCmd:AddSubcommand("list", EssentialsPlugin.World.WorldCommand_List, "list - list all available worlds; active=green, inactive=red", 0, 0) - worldCmd:AddSubcommand("set", EssentialsPlugin.World.WorldCommand_Set, "set [option] [value] - sets world options; leave off arguments to see list of options; leave off value to see current value", 0, 1) - worldCmd:AddSubcommand("save", EssentialsPlugin.World.WorldCommand_Save, "save - saves world options and map data to file", 0, 1) - worldCmd:AddSubcommand("load", EssentialsPlugin.World.WorldCommand_Load, "load - loads world map into memory", 1, 0) - worldCmd:AddSubcommand("new", EssentialsPlugin.World.WorldCommand_New, "new ", 4, 0) + local worldCmd = Server.AddCommand("world", "w map", function() end, "world - various commands related to worlds", 1, 0) + local worldListCmd = worldCmd:AddSubcommand("list", EssentialsPlugin.World.Command_List, "list - list all available worlds; active=green, inactive=red", 0, 0) + worldCmd:AddSubcommand("set", EssentialsPlugin.World.Command_Set, "set [option] [value] - sets world options; leave off arguments to see list of options; leave off value to see current value", 0, 1) + worldCmd:AddSubcommand("save", EssentialsPlugin.World.Command_Save, "save - saves world options and map data to file", 0, 1) + worldCmd:AddSubcommand("load", EssentialsPlugin.World.Command_Load, "load - loads world map into memory", 1, 0) + worldCmd:AddSubcommand("new", EssentialsPlugin.World.Command_New, "new ", 4, 0) - Server.AddCommand("worlds", "", function(client, args) EssentialsPlugin.World.WorldCommand_List(client, args) end, "worlds - shortcut for /world list", 0, 0) + Server.AddCommand("worlds", "", function(client, args) EssentialsPlugin.World.Command_List(client, args) end, "worlds - shortcut for /world list", 0, 0) PermissionsPlugin.RequirePermission("essentials.world") end, -WorldCommand_List = function(client, args) +Command_List = function(client, args) local message = "&eWorlds: " local worlds = Server.GetWorlds() @@ -33,7 +33,7 @@ WorldCommand_List = function(client, args) Server.SendMessage(client, message) end, -WorldCommand_Set = function(client, args) +Command_Set = function(client, args) if (not PermissionsPlugin.CheckPermissionNotify(client, "essentials.world")) then return end @@ -73,7 +73,7 @@ WorldCommand_Set = function(client, args) Server.SendMessage(client, "&eSet option " .. option .. " to " .. value) end, -WorldCommand_Save = function(client, args) +Command_Save = function(client, args) if (not PermissionsPlugin.CheckPermissionNotify(client, "essentials.world")) then return end @@ -83,7 +83,7 @@ WorldCommand_Save = function(client, args) Server.SendMessage(client, "&eWorld saved") end, -WorldCommand_Load = function(client, args) +Command_Load = function(client, args) local targetName = string.lower(args[1]) local targetWorld = Server.GetWorldByName(targetName) @@ -104,7 +104,39 @@ WorldCommand_Load = function(client, args) Server.SendMessage(client, "&eLoaded world &a" .. worldName) end, -WorldCommand_New = function(client, args) - Server.SendMessage(client, "&cNot yet implemented") +Command_New = function(client, args) + if (not PermissionsPlugin.CheckPermissionNotify(client, "essentials.world")) then + return + end + + local worldName = string.lower(args[1]) + + if (string.len(worldName) > 10) then + Server.SendMessage(client, "&cInvalid name") + return + end + + local x = tonumber(args[2]) + local y = tonumber(args[3]) + local z = tonumber(args[4]) + + if (type(x) ~= 'number' or type(y) ~= 'number' or type(z) ~= 'number') then + Server.SendMessage(client, "&cMalformed input") + return + end + + if ((x > 512 or x <= 0) or (y > 64 or y <=0) or (z > 512 or z <= 0)) then + Server.SendMessage(client, "&cInvalid size. Max map size is &f512&cx&f64&cx&f512&c.") + return + end + + if (Server.GetWorldByName(worldName) ~= nil) then + Server.SendMessage(client, WORLD_ALREADY_EXISTS(worldName)) + return + end + + Server.CreateWorld(worldName, x, y, z) + + Server.SendMessage(client, "&eWorld '" .. worldName .. "' with size " .. x .. "x" .. y .. "x" .. z .. " created successfully.") end } diff --git a/src/CommandHandler.cpp b/src/CommandHandler.cpp index 5197b52..6ebd6e3 100644 --- a/src/CommandHandler.cpp +++ b/src/CommandHandler.cpp @@ -65,6 +65,18 @@ Command* CommandHandler::GetCommand(std::string name) return iter->second; } +Command* CommandHandler::GetCommandByAlias(std::string name) +{ + auto aliasIter = m_aliases.find(name); + if (aliasIter != m_aliases.end()) { + auto iter = m_commands.find(aliasIter->second); + if (iter != m_commands.end()) + return iter->second; + } + + return nullptr; +} + void CommandHandler::Register(std::string name, Command* command, std::string aliases) { std::pair res = m_commands.insert(std::make_pair(name, command)); @@ -111,8 +123,10 @@ void CommandHandler::Execute(Client* sender, std::string name, const CommandArgs // Not found, check aliases if (iter == m_commands.end()) { auto aliasIter = m_aliases.find(name); - if (aliasIter != m_aliases.end()) - iter = m_commands.find(aliasIter->second); + if (aliasIter != m_aliases.end()) { + name = aliasIter->second; + iter = m_commands.find(name); + } } if (iter == m_commands.end()) { diff --git a/src/CommandHandler.hpp b/src/CommandHandler.hpp index 6a5a5c6..3148e82 100644 --- a/src/CommandHandler.hpp +++ b/src/CommandHandler.hpp @@ -52,7 +52,8 @@ class CommandHandler { void Reset(); Command* GetCommand(std::string name); - const CommandMap& GetCommandList() const { return m_commands; } + Command* GetCommandByAlias(std::string name); + CommandMap GetCommandList() const { return m_commands; } void Register(std::string name, Command* command, std::string aliases=""); void Execute(Client* sender, std::string name, const CommandArgs& args); diff --git a/src/Commands/HelpCommand.hpp b/src/Commands/HelpCommand.hpp index 95dc123..0987c6c 100644 --- a/src/Commands/HelpCommand.hpp +++ b/src/Commands/HelpCommand.hpp @@ -50,9 +50,16 @@ class HelpCommand : public Command { // Does this command exist? auto iter = commands.find(commandName); - if (iter != commands.end()) { + + Command* testCommand = nullptr; + if (iter != commands.end()) + testCommand = iter->second; + else + testCommand = server->GetCommandHandler().GetCommandByAlias(commandName); + + if (testCommand != nullptr) { // issued /help commandName - Command* subcheck = iter->second; + Command* subcheck = testCommand; std::string docStringPrefix = "/"; if (args.size() > 1) { diff --git a/src/Commands/WorldCommand.hpp b/src/Commands/WorldCommand.hpp deleted file mode 100644 index 6328b62..0000000 --- a/src/Commands/WorldCommand.hpp +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef WORLDCOMMAND_H_ -#define WORLDCOMMAND_H_ - -#include -#include -#include - -#include "../CommandHandler.hpp" -#include "../Utils/Logger.hpp" - -class WorldCommand : public Command { -public: - WorldCommand(std::string name) : Command(name) {} - - ~WorldCommand() {} - - virtual void Execute(Client* sender, const CommandArgs& args) - { - Server* server = Server::GetInstance(); - std::string subcommand = args.front(); - bool isOperator = sender->GetUserType() >= 0x64; - - boost::algorithm::to_lower(subcommand); - - if (subcommand == "list") { - std::vector worldNames = server->GetWorldNames(); - - int size = (int)worldNames.size(); - std::string message = "&eWorlds: "; - - for (int i = 0; i < size; ++i) { - if (server->GetWorld(worldNames[i])->GetActive()) - message += "&a"; - else - message += "&c"; - - message += worldNames[i]; - - if (i < size - 1) - message += "&e, "; - } - - Server::SendWrappedMessage(sender, message); - } else if (subcommand == "new") { - if (!isOperator) { - Protocol::SendMessage(sender, "&cOnly operators can create new worlds at this time"); - return; - } - - if (args.size() < 5) { - Protocol::SendMessage(sender, "&c/world new "); - return; - } - - std::string worldName = args[1]; - boost::algorithm::to_lower(worldName); - - if (worldName.length() > 10) { - Protocol::SendMessage(sender, "&cInvalid name"); - return; - } - - short x, y, z; - try { - x = boost::lexical_cast(args[2]); - y = boost::lexical_cast(args[3]); - z = boost::lexical_cast(args[4]); - } catch (boost::bad_lexical_cast&) { - Protocol::SendMessage(sender, "&cMalformed input"); - return; - } - - if (x <= 0 || x > 1024 || y <= 0 || y > 64 || z <= 0 || z > 1024) { - Protocol::SendMessage(sender, "&cInvalid size"); - return; - } - - //FIXME TEMPORARY - std::string filename = "worlds/maps/" + worldName + "_" + std::to_string(x) + "x" + std::to_string(y) + "x" + std::to_string(z) + ".raw"; - - World* world = new World(worldName); - - world->GetMap().GenerateFlatMap(filename, x, y, z); - world->GetMap().SetFilename(filename); - world->SetSpawnPosition(Position(x/2*32+51, y/2*32+51, z/2*32+51)); - world->SetActive(true); - - server->AddWorld(world); - - Protocol::SendMessage(sender, "&eWorld &a" + worldName + "&e created (" + std::to_string(x) + "x" + std::to_string(y) + "x" + std::to_string(z) + ")"); - } else if (subcommand == "set") { - if (!isOperator) { - Protocol::SendMessage(sender, "&cOnly operators can set world options"); - return; - } - - World *w = sender->GetWorld(); - - if (args.size() < 2) { - std::vector options = w->GetOptionNames(); - std::string message = "&eWorld options: "; - - int size = (int)options.size(); - - if (size == 0) { - Protocol::SendMessage(sender, "No options"); - return; - } - - for (int i = 0; i < size; ++i) { - message += options[i]; - if (i < size - 1) - message += ", "; - } - - Server::SendWrappedMessage(sender, message); - - return; - } - - std::string option = args[1]; - - bool validOption = w->IsValidOption(option); - if (!validOption) { - Protocol::SendMessage(sender, "&cInvalid option"); - return; - } - - if (args.size() == 2) { - std::string value = w->GetOption(option); - Protocol::SendMessage(sender, "&e" + option + "=" + value); - return; - } - - std::string value = args[2]; - - // FIXME: Temporary - if (value != "true" && value != "false") { - Protocol::SendMessage(sender, "&cInvalid value"); - return; - } - - w->SetOption(option, value); - - Protocol::SendMessage(sender, "&eWorld option " + option + "=" + value); - } else if (subcommand == "load") { - if (args.size() < 2) { - Protocol::SendMessage(sender, "&cMust specify world name"); - return; - } - - std::string worldName = args[1]; - - boost::algorithm::to_lower(worldName); - - World *world = server->GetWorld(worldName); - - if (world == nullptr) { - Protocol::SendMessage(sender, "&cWorld &f" + worldName + "&c does not exist"); - return; - } - - if (world->GetActive()) { - Protocol::SendMessage(sender, "&cWorld &a" + worldName + "&c is already loaded"); - return; - } - - world->GetMap().Load(); - world->SetActive(true); - - Protocol::SendMessage(sender, "&eLoaded world &a" + worldName); - } else if (subcommand == "save") { - if (!isOperator) { - Protocol::SendMessage(sender, "&cOnly operators can save worlds"); - return; - } - - if (args.size() < 2) { - Protocol::SendMessage(sender, "&cMust specify world name"); - return; - } - - std::string worldName = args[1]; - - boost::algorithm::to_lower(worldName); - - World *world = server->GetWorld(worldName); - - if (world == nullptr) { - Protocol::SendMessage(sender, "&cWorld &f" + worldName + "&c does not exist"); - return; - } - - world->Save(); - - Protocol::SendMessage(sender, "&eSaved world &a" + worldName); - } else if (subcommand == "spawn") { - // FIXME: Temporary - Position pos = sender->GetPosition(); - World *w = sender->GetWorld(); - - w->SetSpawnPosition(pos); - - Protocol::SendMessage(sender, "&eSpawn position set (" + std::to_string(pos.x) + ", " + std::to_string(pos.y) + ", " + std::to_string(pos.z) + ")"); - } else { - Server::SendWrappedMessage(sender, "&b" + GetDocString()); - return; - } - } - - virtual std::string GetDocString() { return "world - various world-related commands | * operator only"; } - virtual unsigned int GetArgumentAmount() { return 1; } - virtual unsigned int GetPermissionLevel() { return 0; } - -private: - -}; - -#endif // WORLDCOMMAND_H_ diff --git a/src/LuaPlugins/LuaPluginAPI.cpp b/src/LuaPlugins/LuaPluginAPI.cpp index 5360762..5e644ca 100644 --- a/src/LuaPlugins/LuaPluginAPI.cpp +++ b/src/LuaPlugins/LuaPluginAPI.cpp @@ -57,6 +57,7 @@ void LuaServer::Init(lua_State* L) .addStaticFunction("IsOperator", &LuaServer::LuaIsOperator) .addStaticFunction("TransportPlayer", &LuaServer::LuaTransportPlayer) .addStaticFunction("ReloadPlugins", &LuaServer::LuaReloadPlugins) + .addStaticFunction("CreateWorld", &LuaServer::LuaCreateWorld) .endClass(); } @@ -223,6 +224,20 @@ void LuaServer::LuaReloadPlugins() Server::GetInstance()->reloadPluginsFlag = true; } +void LuaServer::LuaCreateWorld(std::string worldName, short x, short y, short z) +{ + std::string filename = "worlds/maps/" + worldName + "_" + std::to_string(x) + "x" + std::to_string(y) + "x" + std::to_string(z) + ".raw"; + + World* world = new World(worldName); + + world->GetMap().GenerateFlatMap(filename, x, y, z); + world->GetMap().SetFilename(filename); + world->SetSpawnPosition(Position(x/2*32+51, y/2*32+51, z/2*32+51)); + world->SetActive(true); + + Server::GetInstance()->AddWorld(world); +} + // Struct to table stuff luabridge::LuaRef make_luatable() diff --git a/src/LuaPlugins/LuaPluginAPI.hpp b/src/LuaPlugins/LuaPluginAPI.hpp index 6282e05..8cb0760 100644 --- a/src/LuaPlugins/LuaPluginAPI.hpp +++ b/src/LuaPlugins/LuaPluginAPI.hpp @@ -30,6 +30,7 @@ struct LuaServer { static void LuaTransportPlayer(Client* client, World* world); static luabridge::LuaRef LuaWorldGetOptionNames(World* world); static void LuaReloadPlugins(); + static void LuaCreateWorld(std::string worldName, short x, short y, short z); }; luabridge::LuaRef make_luatable(); diff --git a/src/Server.cpp b/src/Server.cpp index c607493..d39d801 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -27,7 +27,6 @@ #include "Commands/TeleportCommand.hpp" #include "Commands/SummonCommand.hpp" #include "Commands/OpCommand.hpp" -#include "Commands/WorldCommand.hpp" Server* Server::m_thisPtr = nullptr; @@ -151,7 +150,6 @@ void Server::LoadPlugins() m_commandHandler.Register("tp", new TeleportCommand("tp")); m_commandHandler.Register("summon", new SummonCommand("summon")); m_commandHandler.Register("op", new OpCommand("op")); - m_commandHandler.Register("world", new WorldCommand("world"), "w map"); m_pluginHandler.LoadPlugin("plugins/core/init.lua"); // Load this first