Moved command API into cPluginManager.
As specified in http://forum.mc-server.org/showthread.php?tid=765 , commands are now bound using a single function, cPluginManager:BindCommand(). git-svn-id: http://mc-server.googlecode.com/svn/trunk@1183 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
71bbf2d44b
commit
019c8b5bc7
@ -1,56 +1,40 @@
|
||||
function HandleHelpCommand( Split, Player )
|
||||
function HandleHelpCommand(Split, Player)
|
||||
local PluginManager = cRoot:Get():GetPluginManager()
|
||||
|
||||
local LinesPerPage = 9
|
||||
local CurrentPage = 1
|
||||
local CurrentLine = 0
|
||||
local LinesPerPage = 9;
|
||||
local CurrentPage = 1;
|
||||
local CurrentLine = 0;
|
||||
local PageRequested = 1;
|
||||
local Output = {};
|
||||
|
||||
if( #Split == 2 ) then
|
||||
CurrentPage = tonumber(Split[2])
|
||||
if (#Split == 2) then
|
||||
PageRequested = tonumber(Split[2]);
|
||||
end
|
||||
|
||||
local Pages = {}
|
||||
local Process = function(Command, Permission, HelpString)
|
||||
if not(Player:HasPermission(Permission)) then
|
||||
return false;
|
||||
end;
|
||||
if (HelpString == "") then
|
||||
return false;
|
||||
end;
|
||||
|
||||
local PluginList = PluginManager:GetAllPlugins()
|
||||
for k, Plugin in pairs(PluginList) do
|
||||
if( Plugin ) then
|
||||
local Commands = Plugin:GetCommands()
|
||||
for i, v in ipairs( Commands ) do
|
||||
if( Player:HasPermission( v.Permission ) ) then
|
||||
local PageNum = math.floor( CurrentLine/LinesPerPage )+1
|
||||
if( Pages[ PageNum ] == nil ) then Pages[ PageNum ] = {} end -- Create page
|
||||
|
||||
if( Pages[ PageNum ].ShownName ~= Plugin:GetName() and SHOW_PLUGIN_NAMES == true ) then
|
||||
if( CurrentLine == LinesPerPage * PageNum -1 ) then -- Don't add if it's the last line of the page, it looks silly
|
||||
-- Add it to the next page instead
|
||||
CurrentLine = CurrentLine+1
|
||||
PageNum = math.floor( CurrentLine/LinesPerPage )+1
|
||||
|
||||
if( Pages[ PageNum ] == nil ) then Pages[ PageNum ] = {} end -- Create page
|
||||
table.insert( Pages[ PageNum ], cChatColor.Gold .. Plugin:GetName() )
|
||||
else
|
||||
Pages[ PageNum ].ShownName = Plugin:GetName()
|
||||
table.insert( Pages[ PageNum ], cChatColor.Gold .. Plugin:GetName() )
|
||||
end
|
||||
CurrentLine = CurrentLine+1
|
||||
PageNum = math.floor( CurrentLine/LinesPerPage )+1
|
||||
if( Pages[ PageNum ] == nil ) then Pages[ PageNum ] = {} end -- Create page
|
||||
end
|
||||
local Message = cChatColor.Blue .. v.Command .. v.Description;
|
||||
table.insert( Pages[ PageNum ], Message )
|
||||
CurrentLine = CurrentLine+1
|
||||
end
|
||||
end
|
||||
end
|
||||
CurrentLine = CurrentLine + 1;
|
||||
CurrentPage = math.floor(CurrentLine / LinesPerPage) + 1;
|
||||
if (CurrentPage ~= PageRequested) then
|
||||
return false;
|
||||
end;
|
||||
table.insert(Output, cChatColor.Blue .. Command .. HelpString);
|
||||
end
|
||||
|
||||
Player:SendMessage( cChatColor.Purple .. "- All commands - " .. cChatColor.Gold .. "[Page " .. (CurrentPage) .."/"..#Pages.."]" )
|
||||
PluginManager:ForEachCommand(Process);
|
||||
|
||||
if( Pages[CurrentPage] ~= nil ) then
|
||||
for i, v in ipairs(Pages[CurrentPage]) do
|
||||
Player:SendMessage( v )
|
||||
end
|
||||
end
|
||||
-- CurrentPage now contains the total number of pages, and Output has the individual help lines to be sent
|
||||
|
||||
Player:SendMessage(cChatColor.Purple .. "- All commands - " .. cChatColor.Gold .. "[Page " .. PageRequested .. " / " .. CurrentPage .. "]");
|
||||
for idx, msg in ipairs(Output) do
|
||||
Player:SendMessage(msg);
|
||||
end;
|
||||
|
||||
return true
|
||||
end
|
@ -8,11 +8,15 @@ PLUGIN = {} -- Reference to own plugin object
|
||||
BannedPlayersIni = {}
|
||||
WhiteListIni = {}
|
||||
|
||||
function Initialize( Plugin )
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin
|
||||
|
||||
Plugin:SetName( "Core" )
|
||||
Plugin:SetVersion(9)
|
||||
Plugin:SetName("Core")
|
||||
Plugin:SetVersion(10)
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager()
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_PLAYER_JOINED)
|
||||
@ -23,48 +27,27 @@ function Initialize( Plugin )
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CRAFTING_NO_RECIPE)
|
||||
PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT) -- used in web_chat.lua
|
||||
|
||||
Plugin:AddCommand("/help", " - [Page] Show this message", "core.help")
|
||||
Plugin:AddCommand("/pluginlist", " - Show list of plugins", "core.pluginlist")
|
||||
Plugin:AddCommand("/tp", " - [Player] - Teleport yourself to a player", "core.teleport")
|
||||
Plugin:AddCommand("/item", " - [ItemType/Name] <Amount> - Give yourself an item", "core.item")
|
||||
Plugin:AddCommand("/list", " - Shows list of connected players", "core.playerlist")
|
||||
Plugin:AddCommand("/motd", " - Show message of the day", "core.motd")
|
||||
Plugin:AddCommand("/reload", " - Reload all plugins", "core.reload")
|
||||
Plugin:AddCommand("/stop", " - Stops the server", "core.stop")
|
||||
Plugin:AddCommand("/time", " - [Day/Night] - Sets the time of day", "core.time")
|
||||
Plugin:AddCommand("/spawn", " - Return to the spawn", "core.spawn")
|
||||
Plugin:AddCommand("/kick", " - [Player] - Kick a player", "core.kick")
|
||||
Plugin:AddCommand("/ban", " - [Player] - Ban a player", "core.ban")
|
||||
Plugin:AddCommand("/unban", " - [Player] - Unban a player", "core.unban")
|
||||
Plugin:AddCommand("/top", " - Teleport yourself to the top most block", "core.top")
|
||||
Plugin:AddCommand("/gm", " - [Gamemode (0|1)] - Change your gamemode", "core.changegm")
|
||||
Plugin:AddCommand("/gotoworld", " - Move to a different world!", "core.gotoworld")
|
||||
Plugin:AddCommand("/coords", " - Show your current server coordinates", "core.coords")
|
||||
Plugin:AddCommand("/viewdistance", " - [".. cClientHandle.MIN_VIEW_DISTANCE .."-".. cClientHandle.MAX_VIEW_DISTANCE .."] - Change your view distance", "core.viewdistance")
|
||||
Plugin:AddCommand("/regeneratechunk", " - <X [Z]> - Regenerates a chunk", "core.regeneratechunk")
|
||||
|
||||
Plugin:BindCommand( "/help", "core.help", HandleHelpCommand )
|
||||
Plugin:BindCommand( "/pluginlist", "core.pluginlist", HandlePluginListCommand )
|
||||
Plugin:BindCommand( "/tp", "core.teleport", HandleTPCommand )
|
||||
Plugin:BindCommand( "/item", "core.item", HandleItemCommand )
|
||||
Plugin:BindCommand( "/i", "core.item", HandleItemCommand )
|
||||
Plugin:BindCommand( "/list", "core.playerlist", HandlePlayerListCommand )
|
||||
Plugin:BindCommand( "/who", "core.playerlist", HandlePlayerListCommand )
|
||||
Plugin:BindCommand( "/playerlist", "core.playerlist", HandlePlayerListCommand )
|
||||
Plugin:BindCommand( "/motd", "core.motd", HandleMOTDCommand )
|
||||
Plugin:BindCommand( "/reload", "core.reload", HandleReloadCommand )
|
||||
Plugin:BindCommand( "/stop", "core.stop", HandleStopCommand )
|
||||
Plugin:BindCommand( "/time", "core.time", HandleTimeCommand )
|
||||
Plugin:BindCommand( "/spawn", "core.spawn", HandleSpawnCommand )
|
||||
Plugin:BindCommand( "/kick", "core.kick", HandleKickCommand )
|
||||
Plugin:BindCommand( "/ban", "core.ban", HandleBanCommand )
|
||||
Plugin:BindCommand( "/unban", "core.unban", HandleUnbanCommand )
|
||||
Plugin:BindCommand( "/top", "core.top", HandleTopCommand )
|
||||
Plugin:BindCommand( "/gm", "core.changegm", HandleChangeGMCommand )
|
||||
Plugin:BindCommand( "/gotoworld", "core.gotoworld", HandleGotoWorldCommand )
|
||||
Plugin:BindCommand( "/coords", "core.coords", HandleCoordsCommand )
|
||||
Plugin:BindCommand( "/viewdistance", "core.viewdistance", HandleViewDistanceCommand )
|
||||
Plugin:BindCommand( "/regeneratechunk", "core.regeneratechunk", HandleRegenerateChunkCommand )
|
||||
PluginManager:BindCommand("/help", "core.help", HandleHelpCommand, " [Page] - Show available commands");
|
||||
PluginManager:BindCommand("/pluginlist", "core.pluginlist", HandlePluginListCommand, " - Show list of plugins");
|
||||
PluginManager:BindCommand("/tp", "core.teleport", HandleTPCommand, " [Player] - Teleport yourself to a player");
|
||||
PluginManager:BindCommand("/item", "core.item", HandleItemCommand, " [ItemType/Name] <Amount> - Give yourself an item");
|
||||
PluginManager:BindCommand("/list", "core.playerlist", HandlePlayerListCommand, " - Shows list of connected players");
|
||||
PluginManager:BindCommand("/who", "core.playerlist", HandlePlayerListCommand, " - Shows list of connected players");
|
||||
PluginManager:BindCommand("/playerlist", "core.playerlist", HandlePlayerListCommand, " - Shows list of connected players");
|
||||
PluginManager:BindCommand("/motd", "core.motd", HandleMOTDCommand, " - Show message of the day");
|
||||
PluginManager:BindCommand("/reload", "core.reload", HandleReloadCommand, " - Reload all plugins");
|
||||
PluginManager:BindCommand("/stop", "core.stop", HandleStopCommand, " - Stops the server");
|
||||
PluginManager:BindCommand("/time", "core.time", HandleTimeCommand, " [Day/Night] - Sets the time of day");
|
||||
PluginManager:BindCommand("/spawn", "core.spawn", HandleSpawnCommand, " - Return to the spawn");
|
||||
PluginManager:BindCommand("/kick", "core.kick", HandleKickCommand, " [Player] - Kick a player");
|
||||
PluginManager:BindCommand("/ban", "core.ban", HandleBanCommand, " [Player] - Ban a player");
|
||||
PluginManager:BindCommand("/unban", "core.unban", HandleUnbanCommand, " [Player] - Unban a player");
|
||||
PluginManager:BindCommand("/top", "core.top", HandleTopCommand, " - Teleport yourself to the top most block");
|
||||
PluginManager:BindCommand("/gm", "core.changegm", HandleChangeGMCommand, " [0|1] - Change your gamemode");
|
||||
PluginManager:BindCommand("/gotoworld", "core.gotoworld", HandleGotoWorldCommand, " [WorldName] - Move to a different world!");
|
||||
PluginManager:BindCommand("/coords", "core.coords", HandleCoordsCommand, " - Show your current server coordinates");
|
||||
PluginManager:BindCommand("/regeneratechunk", "core.regeneratechunk", HandleRegenerateChunkCommand, " <[X] [Z]> - Regenerates a chunk, current or specified");
|
||||
PluginManager:BindCommand("/viewdistance", "core.viewdistance", HandleViewDistanceCommand, " [".. cClientHandle.MIN_VIEW_DISTANCE .."-".. cClientHandle.MAX_VIEW_DISTANCE .."] - Change your view distance")
|
||||
|
||||
local IniFile = cIniFile("settings.ini")
|
||||
if ( IniFile:ReadFile() == true ) then
|
||||
|
@ -1,18 +1,18 @@
|
||||
function HandleRegenerateChunkCommand( Split, Player )
|
||||
if( (#Split == 2) or (#Split > 3) ) then
|
||||
Player:SendMessage( cChatColor.Green .. "Usage: /regeneratechunk <X [Z]>" )
|
||||
return true
|
||||
function HandleRegenerateChunkCommand(Split, Player)
|
||||
if ((#Split == 2) or (#Split > 3)) then
|
||||
Player:SendMessage( cChatColor.Green .. "Usage: '/regeneratechunk' or '/regeneratechunk [X] [Z]'");
|
||||
return true;
|
||||
end
|
||||
|
||||
local X = Player:GetChunkX()
|
||||
local Z = Player:GetChunkZ()
|
||||
local X = Player:GetChunkX();
|
||||
local Z = Player:GetChunkZ();
|
||||
|
||||
if( #Split == 3 ) then
|
||||
X = Split[2]
|
||||
Z = Split[3]
|
||||
if (#Split == 3) then
|
||||
X = Split[2];
|
||||
Z = Split[3];
|
||||
end
|
||||
|
||||
Player:SendMessage(cChatColor.Green .. "Regenerating chunk ["..X..", "..Z.."]")
|
||||
Player:GetWorld():RegenerateChunk(X, Z)
|
||||
return true
|
||||
Player:SendMessage(cChatColor.Green .. "Regenerating chunk ["..X..", "..Z.."]");
|
||||
Player:GetWorld():RegenerateChunk(X, Z);
|
||||
return true;
|
||||
end
|
@ -1455,14 +1455,6 @@
|
||||
RelativePath="..\source\Bindings.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\LuaCommandBinder.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\LuaCommandBinder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\source\LuaFunctions.h"
|
||||
>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Lua binding: AllToLua
|
||||
** Generated automatically by tolua++-1.0.92 on 01/28/13 17:46:12.
|
||||
** Generated automatically by tolua++-1.0.92 on 02/01/13 20:11:44.
|
||||
*/
|
||||
|
||||
#ifndef __cplusplus
|
||||
@ -154,7 +154,6 @@ static void tolua_reg_types (lua_State* tolua_S)
|
||||
tolua_usertype(tolua_S,"cInventory");
|
||||
tolua_usertype(tolua_S,"cRoot");
|
||||
tolua_usertype(tolua_S,"cCraftingGrid");
|
||||
tolua_usertype(tolua_S,"cPlugin::CommandStruct");
|
||||
tolua_usertype(tolua_S,"cPickup");
|
||||
tolua_usertype(tolua_S,"cItems");
|
||||
tolua_usertype(tolua_S,"cGroup");
|
||||
@ -167,7 +166,7 @@ static void tolua_reg_types (lua_State* tolua_S)
|
||||
tolua_usertype(tolua_S,"Vector3i");
|
||||
tolua_usertype(tolua_S,"Lua__cWebPlugin");
|
||||
tolua_usertype(tolua_S,"Lua__cPawn");
|
||||
tolua_usertype(tolua_S,"cStairs");
|
||||
tolua_usertype(tolua_S,"cPawn");
|
||||
tolua_usertype(tolua_S,"cItem");
|
||||
tolua_usertype(tolua_S,"Vector3f");
|
||||
tolua_usertype(tolua_S,"Lua__cTCPLink");
|
||||
@ -179,13 +178,13 @@ static void tolua_reg_types (lua_State* tolua_S)
|
||||
tolua_usertype(tolua_S,"cGroupManager");
|
||||
tolua_usertype(tolua_S,"cBlockEntity");
|
||||
tolua_usertype(tolua_S,"Lua__cPickup");
|
||||
tolua_usertype(tolua_S,"cWebPlugin");
|
||||
tolua_usertype(tolua_S,"Lua__cEntity");
|
||||
tolua_usertype(tolua_S,"cPluginManager");
|
||||
tolua_usertype(tolua_S,"cPlugin");
|
||||
tolua_usertype(tolua_S,"HTTPFormData");
|
||||
tolua_usertype(tolua_S,"cWebPlugin");
|
||||
tolua_usertype(tolua_S,"cServer");
|
||||
tolua_usertype(tolua_S,"cLadder");
|
||||
tolua_usertype(tolua_S,"MTRand");
|
||||
tolua_usertype(tolua_S,"cWorld");
|
||||
tolua_usertype(tolua_S,"HTTPFormData");
|
||||
tolua_usertype(tolua_S,"cIniFile");
|
||||
tolua_usertype(tolua_S,"cEntity");
|
||||
tolua_usertype(tolua_S,"HTTPRequest");
|
||||
@ -193,10 +192,10 @@ static void tolua_reg_types (lua_State* tolua_S)
|
||||
tolua_usertype(tolua_S,"cPlayer");
|
||||
tolua_usertype(tolua_S,"cTorch");
|
||||
tolua_usertype(tolua_S,"cBlockEntityWindowOwner");
|
||||
tolua_usertype(tolua_S,"cServer");
|
||||
tolua_usertype(tolua_S,"cPlugin");
|
||||
tolua_usertype(tolua_S,"Lua__cChestEntity");
|
||||
tolua_usertype(tolua_S,"cPawn");
|
||||
tolua_usertype(tolua_S,"Lua__cEntity");
|
||||
tolua_usertype(tolua_S,"cWorld");
|
||||
tolua_usertype(tolua_S,"cStairs");
|
||||
tolua_usertype(tolua_S,"Vector3d");
|
||||
}
|
||||
|
||||
@ -8782,9 +8781,9 @@ static int tolua_AllToLua_Lua__cPlayer_cPlayer__MoveTo00(lua_State* tolua_S)
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* method: GetPluginManager of class cPluginManager */
|
||||
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetPluginManager00
|
||||
static int tolua_AllToLua_cPluginManager_GetPluginManager00(lua_State* tolua_S)
|
||||
/* method: Get of class cPluginManager */
|
||||
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_Get00
|
||||
static int tolua_AllToLua_cPluginManager_Get00(lua_State* tolua_S)
|
||||
{
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_Error tolua_err;
|
||||
@ -8797,14 +8796,14 @@ static int tolua_AllToLua_cPluginManager_GetPluginManager00(lua_State* tolua_S)
|
||||
#endif
|
||||
{
|
||||
{
|
||||
cPluginManager* tolua_ret = (cPluginManager*) cPluginManager::GetPluginManager();
|
||||
cPluginManager* tolua_ret = (cPluginManager*) cPluginManager::Get();
|
||||
tolua_pushusertype(tolua_S,(void*)tolua_ret,"cPluginManager");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_lerror:
|
||||
tolua_error(tolua_S,"#ferror in function 'GetPluginManager'.",&tolua_err);
|
||||
tolua_error(tolua_S,"#ferror in function 'Get'.",&tolua_err);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@ -8990,7 +8989,7 @@ static int tolua_AllToLua_cPluginManager_DisablePlugin00(lua_State* tolua_S)
|
||||
#endif
|
||||
{
|
||||
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
|
||||
AString a_PluginName = ((AString) tolua_tocppstring(tolua_S,2,0));
|
||||
const AString a_PluginName = ((const AString) tolua_tocppstring(tolua_S,2,0));
|
||||
#ifndef TOLUA_RELEASE
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DisablePlugin'", NULL);
|
||||
#endif
|
||||
@ -9025,7 +9024,7 @@ static int tolua_AllToLua_cPluginManager_LoadPlugin00(lua_State* tolua_S)
|
||||
#endif
|
||||
{
|
||||
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
|
||||
AString a_PluginName = ((AString) tolua_tocppstring(tolua_S,2,0));
|
||||
const AString a_PluginName = ((const AString) tolua_tocppstring(tolua_S,2,0));
|
||||
#ifndef TOLUA_RELEASE
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'LoadPlugin'", NULL);
|
||||
#endif
|
||||
@ -9044,93 +9043,73 @@ static int tolua_AllToLua_cPluginManager_LoadPlugin00(lua_State* tolua_S)
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* get function: Command of class CommandStruct */
|
||||
#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Command
|
||||
static int tolua_get_cPlugin__CommandStruct_Command(lua_State* tolua_S)
|
||||
/* method: IsCommandBound of class cPluginManager */
|
||||
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_IsCommandBound00
|
||||
static int tolua_AllToLua_cPluginManager_IsCommandBound00(lua_State* tolua_S)
|
||||
{
|
||||
cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
|
||||
#ifndef TOLUA_RELEASE
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL);
|
||||
#endif
|
||||
tolua_pushcppstring(tolua_S,(const char*)self->Command);
|
||||
return 1;
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* set function: Command of class CommandStruct */
|
||||
#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Command
|
||||
static int tolua_set_cPlugin__CommandStruct_Command(lua_State* tolua_S)
|
||||
{
|
||||
cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_Error tolua_err;
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Command'",NULL);
|
||||
if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
|
||||
tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
|
||||
if (
|
||||
!tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
|
||||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
|
||||
!tolua_isnoobj(tolua_S,3,&tolua_err)
|
||||
)
|
||||
goto tolua_lerror;
|
||||
else
|
||||
#endif
|
||||
self->Command = ((AString) tolua_tocppstring(tolua_S,2,0))
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* get function: Description of class CommandStruct */
|
||||
#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Description
|
||||
static int tolua_get_cPlugin__CommandStruct_Description(lua_State* tolua_S)
|
||||
{
|
||||
cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
|
||||
{
|
||||
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
|
||||
const AString a_Command = ((const AString) tolua_tocppstring(tolua_S,2,0));
|
||||
#ifndef TOLUA_RELEASE
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL);
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsCommandBound'", NULL);
|
||||
#endif
|
||||
{
|
||||
bool tolua_ret = (bool) self->IsCommandBound(a_Command);
|
||||
tolua_pushboolean(tolua_S,(bool)tolua_ret);
|
||||
tolua_pushcppstring(tolua_S,(const char*)a_Command);
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_lerror:
|
||||
tolua_error(tolua_S,"#ferror in function 'IsCommandBound'.",&tolua_err);
|
||||
return 0;
|
||||
#endif
|
||||
tolua_pushcppstring(tolua_S,(const char*)self->Description);
|
||||
return 1;
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* set function: Description of class CommandStruct */
|
||||
#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Description
|
||||
static int tolua_set_cPlugin__CommandStruct_Description(lua_State* tolua_S)
|
||||
/* method: GetCommandPermission of class cPluginManager */
|
||||
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPluginManager_GetCommandPermission00
|
||||
static int tolua_AllToLua_cPluginManager_GetCommandPermission00(lua_State* tolua_S)
|
||||
{
|
||||
cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_Error tolua_err;
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Description'",NULL);
|
||||
if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
|
||||
tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
|
||||
if (
|
||||
!tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
|
||||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
|
||||
!tolua_isnoobj(tolua_S,3,&tolua_err)
|
||||
)
|
||||
goto tolua_lerror;
|
||||
else
|
||||
#endif
|
||||
self->Description = ((AString) tolua_tocppstring(tolua_S,2,0))
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* get function: Permission of class CommandStruct */
|
||||
#ifndef TOLUA_DISABLE_tolua_get_cPlugin__CommandStruct_Permission
|
||||
static int tolua_get_cPlugin__CommandStruct_Permission(lua_State* tolua_S)
|
||||
{
|
||||
cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
|
||||
{
|
||||
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
|
||||
const AString a_Command = ((const AString) tolua_tocppstring(tolua_S,2,0));
|
||||
#ifndef TOLUA_RELEASE
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL);
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetCommandPermission'", NULL);
|
||||
#endif
|
||||
tolua_pushcppstring(tolua_S,(const char*)self->Permission);
|
||||
return 1;
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* set function: Permission of class CommandStruct */
|
||||
#ifndef TOLUA_DISABLE_tolua_set_cPlugin__CommandStruct_Permission
|
||||
static int tolua_set_cPlugin__CommandStruct_Permission(lua_State* tolua_S)
|
||||
{
|
||||
cPlugin::CommandStruct* self = (cPlugin::CommandStruct*) tolua_tousertype(tolua_S,1,0);
|
||||
{
|
||||
AString tolua_ret = (AString) self->GetCommandPermission(a_Command);
|
||||
tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
|
||||
tolua_pushcppstring(tolua_S,(const char*)a_Command);
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_Error tolua_err;
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable 'Permission'",NULL);
|
||||
if (!tolua_iscppstring(tolua_S,2,0,&tolua_err))
|
||||
tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);
|
||||
#endif
|
||||
self->Permission = ((AString) tolua_tocppstring(tolua_S,2,0))
|
||||
;
|
||||
tolua_lerror:
|
||||
tolua_error(tolua_S,"#ferror in function 'GetCommandPermission'.",&tolua_err);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
@ -9329,46 +9308,6 @@ static int tolua_AllToLua_cPlugin_GetLocalDirectory00(lua_State* tolua_S)
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* method: AddCommand of class cPlugin */
|
||||
#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlugin_AddCommand00
|
||||
static int tolua_AllToLua_cPlugin_AddCommand00(lua_State* tolua_S)
|
||||
{
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_Error tolua_err;
|
||||
if (
|
||||
!tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
|
||||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
|
||||
!tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
|
||||
!tolua_iscppstring(tolua_S,4,0,&tolua_err) ||
|
||||
!tolua_isnoobj(tolua_S,5,&tolua_err)
|
||||
)
|
||||
goto tolua_lerror;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
|
||||
const AString a_Command = ((const AString) tolua_tocppstring(tolua_S,2,0));
|
||||
const AString a_Description = ((const AString) tolua_tocppstring(tolua_S,3,0));
|
||||
const AString a_Permission = ((const AString) tolua_tocppstring(tolua_S,4,0));
|
||||
#ifndef TOLUA_RELEASE
|
||||
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddCommand'", NULL);
|
||||
#endif
|
||||
{
|
||||
self->AddCommand(a_Command,a_Description,a_Permission);
|
||||
tolua_pushcppstring(tolua_S,(const char*)a_Command);
|
||||
tolua_pushcppstring(tolua_S,(const char*)a_Description);
|
||||
tolua_pushcppstring(tolua_S,(const char*)a_Permission);
|
||||
}
|
||||
}
|
||||
return 3;
|
||||
#ifndef TOLUA_RELEASE
|
||||
tolua_lerror:
|
||||
tolua_error(tolua_S,"#ferror in function 'AddCommand'.",&tolua_err);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif //#ifndef TOLUA_DISABLE
|
||||
|
||||
/* get function: __cWebPlugin__ of class cPlugin_NewLua */
|
||||
#ifndef TOLUA_DISABLE_tolua_get_cPlugin_NewLua___cWebPlugin__
|
||||
static int tolua_get_cPlugin_NewLua___cWebPlugin__(lua_State* tolua_S)
|
||||
@ -21285,7 +21224,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
|
||||
tolua_constant(tolua_S,"HOOK_UPDATED_SIGN",cPluginManager::HOOK_UPDATED_SIGN);
|
||||
tolua_constant(tolua_S,"HOOK_UPDATING_SIGN",cPluginManager::HOOK_UPDATING_SIGN);
|
||||
tolua_constant(tolua_S,"HOOK_WEATHER_CHANGED",cPluginManager::HOOK_WEATHER_CHANGED);
|
||||
tolua_function(tolua_S,"GetPluginManager",tolua_AllToLua_cPluginManager_GetPluginManager00);
|
||||
tolua_function(tolua_S,"Get",tolua_AllToLua_cPluginManager_Get00);
|
||||
tolua_function(tolua_S,"GetPlugin",tolua_AllToLua_cPluginManager_GetPlugin00);
|
||||
tolua_function(tolua_S,"FindPlugins",tolua_AllToLua_cPluginManager_FindPlugins00);
|
||||
tolua_function(tolua_S,"ReloadPlugins",tolua_AllToLua_cPluginManager_ReloadPlugins00);
|
||||
@ -21293,22 +21232,17 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
|
||||
tolua_function(tolua_S,"GetNumPlugins",tolua_AllToLua_cPluginManager_GetNumPlugins00);
|
||||
tolua_function(tolua_S,"DisablePlugin",tolua_AllToLua_cPluginManager_DisablePlugin00);
|
||||
tolua_function(tolua_S,"LoadPlugin",tolua_AllToLua_cPluginManager_LoadPlugin00);
|
||||
tolua_function(tolua_S,"IsCommandBound",tolua_AllToLua_cPluginManager_IsCommandBound00);
|
||||
tolua_function(tolua_S,"GetCommandPermission",tolua_AllToLua_cPluginManager_GetCommandPermission00);
|
||||
tolua_endmodule(tolua_S);
|
||||
tolua_cclass(tolua_S,"cPlugin","cPlugin","",NULL);
|
||||
tolua_beginmodule(tolua_S,"cPlugin");
|
||||
tolua_cclass(tolua_S,"CommandStruct","cPlugin::CommandStruct","",NULL);
|
||||
tolua_beginmodule(tolua_S,"CommandStruct");
|
||||
tolua_variable(tolua_S,"Command",tolua_get_cPlugin__CommandStruct_Command,tolua_set_cPlugin__CommandStruct_Command);
|
||||
tolua_variable(tolua_S,"Description",tolua_get_cPlugin__CommandStruct_Description,tolua_set_cPlugin__CommandStruct_Description);
|
||||
tolua_variable(tolua_S,"Permission",tolua_get_cPlugin__CommandStruct_Permission,tolua_set_cPlugin__CommandStruct_Permission);
|
||||
tolua_endmodule(tolua_S);
|
||||
tolua_function(tolua_S,"GetName",tolua_AllToLua_cPlugin_GetName00);
|
||||
tolua_function(tolua_S,"SetName",tolua_AllToLua_cPlugin_SetName00);
|
||||
tolua_function(tolua_S,"GetVersion",tolua_AllToLua_cPlugin_GetVersion00);
|
||||
tolua_function(tolua_S,"SetVersion",tolua_AllToLua_cPlugin_SetVersion00);
|
||||
tolua_function(tolua_S,"GetDirectory",tolua_AllToLua_cPlugin_GetDirectory00);
|
||||
tolua_function(tolua_S,"GetLocalDirectory",tolua_AllToLua_cPlugin_GetLocalDirectory00);
|
||||
tolua_function(tolua_S,"AddCommand",tolua_AllToLua_cPlugin_AddCommand00);
|
||||
tolua_endmodule(tolua_S);
|
||||
tolua_cclass(tolua_S,"cPlugin_NewLua","cPlugin_NewLua","cPlugin",NULL);
|
||||
tolua_beginmodule(tolua_S,"cPlugin_NewLua");
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Lua binding: AllToLua
|
||||
** Generated automatically by tolua++-1.0.92 on 01/28/13 17:46:13.
|
||||
** Generated automatically by tolua++-1.0.92 on 02/01/13 20:11:44.
|
||||
*/
|
||||
|
||||
/* Exported function */
|
||||
|
@ -1,154 +0,0 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "LuaCommandBinder.h"
|
||||
#include "Player.h"
|
||||
#include "Plugin.h"
|
||||
|
||||
#include "tolua++.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool report_errors(lua_State * lua, int status)
|
||||
{
|
||||
if (status == 0)
|
||||
{
|
||||
// No error to report
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGERROR("LUA: %s", lua_tostring(lua, -1));
|
||||
lua_pop(lua, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cLuaCommandBinder::cLuaCommandBinder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cLuaCommandBinder::~cLuaCommandBinder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaCommandBinder::ClearBindings()
|
||||
{
|
||||
m_BoundCommands.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaCommandBinder::RemoveBindingsForPlugin( cPlugin* a_Plugin )
|
||||
{
|
||||
for( CommandMap::iterator itr = m_BoundCommands.begin(); itr != m_BoundCommands.end(); )
|
||||
{
|
||||
if( itr->second.Plugin == a_Plugin )
|
||||
{
|
||||
LOGINFO("Unbinding %s ", itr->first.c_str( ) );
|
||||
luaL_unref( itr->second.LuaState, LUA_REGISTRYINDEX, itr->second.Reference ); // unreference
|
||||
CommandMap::iterator eraseme = itr;
|
||||
++itr;
|
||||
m_BoundCommands.erase( eraseme );
|
||||
continue;
|
||||
}
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaCommandBinder::BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference )
|
||||
{
|
||||
if( !a_Plugin->CanBindCommands() )
|
||||
{
|
||||
LOGERROR("ERROR: Trying to bind command \"%s\" to a plugin that is not initialized.", a_Command.c_str() );
|
||||
return false;
|
||||
}
|
||||
if( m_BoundCommands.find( a_Command ) != m_BoundCommands.end() )
|
||||
{
|
||||
LOGERROR("ERROR: Trying to bind command \"%s\" that has already been bound.", a_Command.c_str() );
|
||||
return false;
|
||||
}
|
||||
LOGINFO("Binding %s (%s)", a_Command.c_str(), a_Permission.c_str() );
|
||||
m_BoundCommands[ a_Command ] = BoundFunction( a_Plugin, a_LuaState, a_FunctionReference, a_Permission );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaCommandBinder::HandleCommand( const std::string & a_Command, cPlayer* a_Player )
|
||||
{
|
||||
AStringVector Split = StringSplit(a_Command, " ");
|
||||
if (Split.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CommandMap::iterator FoundCommand = m_BoundCommands.find( Split[0] );
|
||||
if( FoundCommand != m_BoundCommands.end() )
|
||||
{
|
||||
const BoundFunction & func = FoundCommand->second;
|
||||
if( func.Permission.size() > 0 )
|
||||
{
|
||||
if( !a_Player->HasPermission( func.Permission.c_str() ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOGD("1. Stack size: %i", lua_gettop(func.LuaState) );
|
||||
lua_rawgeti( func.LuaState, LUA_REGISTRYINDEX, func.Reference); // same as lua_getref()
|
||||
|
||||
// Push the split
|
||||
LOGD("2. Stack size: %i", lua_gettop(func.LuaState) );
|
||||
lua_createtable(func.LuaState, Split.size(), 0);
|
||||
int newTable = lua_gettop(func.LuaState);
|
||||
int index = 1;
|
||||
std::vector<std::string>::const_iterator iter = Split.begin();
|
||||
while(iter != Split.end()) {
|
||||
tolua_pushstring( func.LuaState, (*iter).c_str() );
|
||||
lua_rawseti(func.LuaState, newTable, index);
|
||||
++iter;
|
||||
++index;
|
||||
}
|
||||
LOGD("3. Stack size: %i", lua_gettop(func.LuaState) );
|
||||
// Push player
|
||||
tolua_pushusertype( func.LuaState, a_Player, "cPlayer" );
|
||||
LOGD("Calling bound function! :D");
|
||||
int s = lua_pcall(func.LuaState, 2, 1, 0);
|
||||
if( report_errors( func.LuaState, s ) )
|
||||
{
|
||||
LOGERROR("error. Stack size: %i", lua_gettop(func.LuaState) );
|
||||
return false;
|
||||
}
|
||||
bool RetVal = (tolua_toboolean(func.LuaState, -1, 0) > 0);
|
||||
lua_pop(func.LuaState, 1); // Pop return value
|
||||
LOGD("ok. Stack size: %i", lua_gettop(func.LuaState) );
|
||||
return RetVal;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,42 +0,0 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
struct lua_State;
|
||||
class cPlugin;
|
||||
class cPlayer;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cLuaCommandBinder
|
||||
{
|
||||
public:
|
||||
cLuaCommandBinder();
|
||||
~cLuaCommandBinder();
|
||||
|
||||
bool HandleCommand( const std::string & a_Command, cPlayer* a_Player );
|
||||
|
||||
bool BindCommand( const std::string & a_Command, const std::string & a_Permission, cPlugin* a_Plugin, lua_State * a_LuaState, int a_FunctionReference );
|
||||
|
||||
void ClearBindings();
|
||||
void RemoveBindingsForPlugin( cPlugin* a_Plugin );
|
||||
private:
|
||||
struct BoundFunction
|
||||
{
|
||||
BoundFunction() : Plugin( 0 ), LuaState( 0 ), Reference( 0 ) {}
|
||||
BoundFunction( cPlugin* a_Plugin, lua_State * a_LuaState, int a_Reference, const std::string & a_Permission ) : Plugin( a_Plugin ), LuaState( a_LuaState ), Reference( a_Reference ), Permission( a_Permission ) {}
|
||||
cPlugin* Plugin;
|
||||
lua_State* LuaState;
|
||||
int Reference;
|
||||
std::string Permission;
|
||||
};
|
||||
|
||||
typedef std::map< std::string, BoundFunction > CommandMap;
|
||||
CommandMap m_BoundCommands;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "Plugin.h"
|
||||
#include "Plugin_NewLua.h"
|
||||
#include "PluginManager.h"
|
||||
#include "LuaCommandBinder.h"
|
||||
#include "Player.h"
|
||||
#include "WebAdmin.h"
|
||||
#include "StringMap.h"
|
||||
@ -488,24 +487,74 @@ DEFINE_LUA_FOREACHINCHUNK(cWorld, cFurnaceEntity, ForEachFurnaceInChunk, tolua_c
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlugin_GetCommands(lua_State * tolua_S)
|
||||
static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S)
|
||||
{
|
||||
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
|
||||
|
||||
const std::vector< cPlugin::CommandStruct > & AllCommands = self->GetCommands();
|
||||
|
||||
lua_createtable(tolua_S, AllCommands.size(), 0);
|
||||
int newTable = lua_gettop(tolua_S);
|
||||
int index = 1;
|
||||
std::vector< cPlugin::CommandStruct >::const_iterator iter = AllCommands.begin();
|
||||
while(iter != AllCommands.end())
|
||||
int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */
|
||||
if( NumArgs != 1)
|
||||
{
|
||||
const cPlugin::CommandStruct & CS = *iter;
|
||||
tolua_pushusertype( tolua_S, (void*)&CS, "const cPlugin::CommandStruct" );
|
||||
lua_rawseti(tolua_S, newTable, index);
|
||||
++iter;
|
||||
++index;
|
||||
LOGWARN("Error in function call 'ForEachCommand': Requires 1 argument, got %i", NumArgs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cPluginManager * self = (cPluginManager *)tolua_tousertype(tolua_S, 1, 0);
|
||||
if (self == NULL)
|
||||
{
|
||||
LOGWARN("Error in function call 'ForEachCommand': Not called on an object instance");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lua_isfunction(tolua_S, 2))
|
||||
{
|
||||
LOGWARN("Error in function call 'ForEachCommand': Expected a function for parameter #1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FuncRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
|
||||
if (FuncRef == LUA_REFNIL)
|
||||
{
|
||||
LOGWARN("Error in function call 'ForEachCommand': Could not get function reference of parameter #1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
class cLuaCallback : public cPluginManager::cCommandEnumCallback
|
||||
{
|
||||
public:
|
||||
cLuaCallback(lua_State * a_LuaState, int a_FuncRef)
|
||||
: LuaState( a_LuaState )
|
||||
, FuncRef( a_FuncRef )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) override
|
||||
{
|
||||
lua_rawgeti( LuaState, LUA_REGISTRYINDEX, FuncRef); /* Push function reference */
|
||||
tolua_pushcppstring(LuaState, a_Command);
|
||||
tolua_pushcppstring(LuaState, a_Permission);
|
||||
tolua_pushcppstring(LuaState, a_HelpString);
|
||||
|
||||
int s = lua_pcall(LuaState, 3, 1, 0);
|
||||
if (report_errors(LuaState, s))
|
||||
{
|
||||
return true; /* Abort enumeration */
|
||||
}
|
||||
|
||||
if (lua_isboolean(LuaState, -1))
|
||||
{
|
||||
return (tolua_toboolean( LuaState, -1, 0) > 0);
|
||||
}
|
||||
return false; /* Continue enumeration */
|
||||
}
|
||||
lua_State * LuaState;
|
||||
int FuncRef;
|
||||
} Callback(tolua_S, FuncRef);
|
||||
|
||||
bool bRetVal = self->ForEachCommand(Callback);
|
||||
|
||||
/* Unreference the values again, so the LUA_REGISTRYINDEX can make place for other references */
|
||||
luaL_unref(tolua_S, LUA_REGISTRYINDEX, FuncRef);
|
||||
|
||||
/* Push return value on stack */
|
||||
tolua_pushboolean(tolua_S, bRetVal);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -547,6 +596,64 @@ static int tolua_cPluginManager_GetAllPlugins(lua_State* tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPluginManager_BindCommand(lua_State * L)
|
||||
{
|
||||
// Function signature: cPluginManager:BindCommand(Command, Permission, Function, HelpString)
|
||||
|
||||
// Get the plugin identification out of LuaState:
|
||||
lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME);
|
||||
if (!lua_islightuserdata(L, -1))
|
||||
{
|
||||
LOGERROR("cPluginManager:BindCommand() cannot get plugin instance, what have you done to my Lua state? Command-binding aborted.");
|
||||
}
|
||||
cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Read the arguments to this API call:
|
||||
tolua_Error tolua_err;
|
||||
if (
|
||||
!tolua_isusertype (L, 1, "cPluginManager", 0, &tolua_err) ||
|
||||
!tolua_iscppstring(L, 2, 0, &tolua_err) ||
|
||||
!tolua_iscppstring(L, 3, 0, &tolua_err) ||
|
||||
!tolua_iscppstring(L, 5, 0, &tolua_err) ||
|
||||
!tolua_isnoobj (L, 6, &tolua_err)
|
||||
)
|
||||
{
|
||||
tolua_error(L, "#ferror in function 'BindCommand'.", &tolua_err);
|
||||
return 0;
|
||||
}
|
||||
if (!lua_isfunction(L, 4))
|
||||
{
|
||||
luaL_error(L, "\"BindCommand\" function expects a function as its 3rd parameter. Command-binding aborted.");
|
||||
return 0;
|
||||
}
|
||||
cPluginManager * self = (cPluginManager *)tolua_tousertype(L, 1, 0);
|
||||
AString Command (tolua_tocppstring(L, 2, ""));
|
||||
AString Permission(tolua_tocppstring(L, 3, ""));
|
||||
AString HelpString(tolua_tocppstring(L, 5, ""));
|
||||
|
||||
// Store the function reference:
|
||||
lua_pop(L, 1); // Pop the help string off the stack
|
||||
int FnRef = luaL_ref(L, LUA_REGISTRYINDEX); // Store function reference
|
||||
if (FnRef == LUA_REFNIL)
|
||||
{
|
||||
LOGERROR("\"BindCommand\": Cannot create a function reference. Command \"%s\" not bound.", Command);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!self->BindCommand(Command, Plugin, Permission, HelpString))
|
||||
{
|
||||
// Refused. Possibly already bound. Error message has been given, bail out silently.
|
||||
return 0;
|
||||
}
|
||||
|
||||
Plugin->BindCommand(Command, FnRef);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
|
||||
{
|
||||
@ -598,6 +705,8 @@ static int tolua_cPlayer_GetResolvedPermissions(lua_State* tolua_S)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
// TODO: rewrite this for the new API
|
||||
static int tolua_cPlugin_BindCommand(lua_State* tolua_S)
|
||||
{
|
||||
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
|
||||
@ -651,6 +760,7 @@ static int tolua_cPlugin_BindCommand(lua_State* tolua_S)
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@ -927,13 +1037,13 @@ void ManualBindings::Bind( lua_State* tolua_S )
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cPlugin");
|
||||
tolua_function(tolua_S, "GetCommands", tolua_cPlugin_GetCommands);
|
||||
tolua_function(tolua_S, "BindCommand", tolua_cPlugin_BindCommand);
|
||||
tolua_function(tolua_S, "Call", tolua_cPlugin_Call);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cPluginManager");
|
||||
tolua_function(tolua_S, "GetAllPlugins", tolua_cPluginManager_GetAllPlugins);
|
||||
tolua_function(tolua_S, "BindCommand", tolua_cPluginManager_BindCommand);
|
||||
tolua_function(tolua_S, "ForEachCommand", tolua_cPluginManager_ForEachCommand);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cPlayer");
|
||||
|
@ -10,10 +10,9 @@
|
||||
|
||||
|
||||
cPlugin::cPlugin( const AString & a_PluginDirectory )
|
||||
: m_Version( 0 )
|
||||
, m_Language( E_CPP )
|
||||
, m_bCanBindCommands( false )
|
||||
, m_Directory( a_PluginDirectory )
|
||||
: m_Version(0)
|
||||
, m_Language(E_CPP)
|
||||
, m_Directory(a_PluginDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
@ -126,6 +125,17 @@ bool cPlugin::OnDisconnect(cPlayer * a_Player, const AString & a_Reason)
|
||||
|
||||
|
||||
|
||||
bool cPlugin::OnHandshake(cClientHandle * a_Client, const AString & a_Username)
|
||||
{
|
||||
UNUSED(a_Client);
|
||||
UNUSED(a_Username);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlugin::OnKilling(cPawn & a_Victim, cEntity * a_Killer)
|
||||
{
|
||||
UNUSED(a_Victim);
|
||||
@ -464,10 +474,10 @@ bool cPlugin::OnWeatherChanged(cWorld * a_World)
|
||||
|
||||
|
||||
|
||||
bool cPlugin::OnHandshake(cClientHandle * a_Client, const AString & a_Username)
|
||||
bool cPlugin::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player)
|
||||
{
|
||||
UNUSED(a_Client);
|
||||
UNUSED(a_Username);
|
||||
UNUSED(a_Split);
|
||||
UNUSED(a_Player);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -475,19 +485,6 @@ bool cPlugin::OnHandshake(cClientHandle * a_Client, const AString & a_Username)
|
||||
|
||||
|
||||
|
||||
void cPlugin::AddCommand(const AString & a_Command, const AString & a_Description, const AString & a_Permission)
|
||||
{
|
||||
CommandStruct Command;
|
||||
Command.Command = a_Command;
|
||||
Command.Description = a_Description;
|
||||
Command.Permission = a_Permission;
|
||||
m_Commands.push_back( Command );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cPlugin::GetLocalDirectory(void) const
|
||||
{
|
||||
return std::string("Plugins/") + m_Directory;
|
||||
|
@ -81,6 +81,12 @@ public:
|
||||
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
|
||||
virtual bool OnWeatherChanged (cWorld * a_World);
|
||||
|
||||
/// Handles the command split into a_Split, issued by player a_Player. Command permissions have already been checked.
|
||||
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player);
|
||||
|
||||
/// All bound commands are to be removed, do any language-dependent cleanup here
|
||||
virtual void ClearCommands(void) {} ;
|
||||
|
||||
/** Called from cPluginManager::AddHook() to check if the hook can be added.
|
||||
Plugin API providers may check if the plugin is written correctly (has the hook handler function)
|
||||
Returns true if the hook can be added (handler exists)
|
||||
@ -89,13 +95,6 @@ public:
|
||||
virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) { return false; }
|
||||
|
||||
// tolua_begin
|
||||
struct CommandStruct
|
||||
{
|
||||
AString Command;
|
||||
AString Description;
|
||||
AString Permission;
|
||||
};
|
||||
|
||||
const AString & GetName(void) const { return m_Name; }
|
||||
void SetName(const AString & a_Name) { m_Name = a_Name; }
|
||||
|
||||
@ -104,14 +103,8 @@ public:
|
||||
|
||||
const AString & GetDirectory(void) const {return m_Directory; }
|
||||
AString GetLocalDirectory(void) const;
|
||||
|
||||
void AddCommand(const AString & a_Command, const AString & a_Description, const AString & a_Permission);
|
||||
// tolua_end
|
||||
|
||||
typedef bool (FuncCommandHandler)( AString & a_Command, std::vector< std::string > & a_Split );
|
||||
void BindCommand( FuncCommandHandler* a_Function, AString & a_Command ); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
const std::vector< CommandStruct > & GetCommands() const { return m_Commands; } // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
|
||||
/* This should not be exposed to scripting languages */
|
||||
enum PluginLanguage
|
||||
@ -123,13 +116,8 @@ public:
|
||||
PluginLanguage GetLanguage() { return m_Language; }
|
||||
void SetLanguage( PluginLanguage a_Language ) { m_Language = a_Language; }
|
||||
|
||||
bool CanBindCommands() { return m_bCanBindCommands; }
|
||||
private:
|
||||
friend class cPluginManager;
|
||||
bool m_bCanBindCommands; // Only changed by cPluginManager
|
||||
|
||||
PluginLanguage m_Language;
|
||||
std::vector< CommandStruct > m_Commands;
|
||||
AString m_Name;
|
||||
int m_Version;
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "PluginManager.h"
|
||||
@ -6,32 +7,17 @@
|
||||
#include "WebAdmin.h"
|
||||
#include "Item.h"
|
||||
#include "Root.h"
|
||||
#include "LuaCommandBinder.h"
|
||||
|
||||
#ifdef USE_SQUIRREL
|
||||
#include "Plugin_Squirrel.h"
|
||||
#include "SquirrelCommandBinder.h"
|
||||
#endif
|
||||
|
||||
#include "../iniFile/iniFile.h"
|
||||
#include "tolua++.h"
|
||||
#include "Player.h"
|
||||
|
||||
#ifdef USE_SQUIRREL
|
||||
#include "squirrelbindings/SquirrelBindings.h"
|
||||
#include "squirrelbindings/SquirrelFunctions.h"
|
||||
#pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus
|
||||
|
||||
#pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPluginManager* cPluginManager::GetPluginManager()
|
||||
cPluginManager * cPluginManager::Get(void)
|
||||
{
|
||||
LOGWARN("WARNING: Using deprecated function cPluginManager::GetPluginManager() use cRoot::Get()->GetPluginManager() instead!");
|
||||
return cRoot::Get()->GetPluginManager();
|
||||
}
|
||||
|
||||
@ -39,12 +25,8 @@ cPluginManager* cPluginManager::GetPluginManager()
|
||||
|
||||
|
||||
|
||||
cPluginManager::cPluginManager()
|
||||
: m_LuaCommandBinder( new cLuaCommandBinder() )
|
||||
#ifdef USE_SQUIRREL
|
||||
, m_SquirrelCommandBinder( new cSquirrelCommandBinder() )
|
||||
#endif
|
||||
, m_bReloadPlugins(false)
|
||||
cPluginManager::cPluginManager(void) :
|
||||
m_bReloadPlugins(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -55,18 +37,13 @@ cPluginManager::cPluginManager()
|
||||
cPluginManager::~cPluginManager()
|
||||
{
|
||||
UnloadPluginsNow();
|
||||
|
||||
delete m_LuaCommandBinder;
|
||||
#ifdef USE_SQUIRREL
|
||||
delete m_SquirrelCommandBinder;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPluginManager::ReloadPlugins()
|
||||
void cPluginManager::ReloadPlugins(void)
|
||||
{
|
||||
m_bReloadPlugins = true;
|
||||
}
|
||||
@ -75,12 +52,12 @@ void cPluginManager::ReloadPlugins()
|
||||
|
||||
|
||||
|
||||
void cPluginManager::FindPlugins()
|
||||
void cPluginManager::FindPlugins(void)
|
||||
{
|
||||
AString PluginsPath = FILE_IO_PREFIX + AString( "Plugins/" );
|
||||
|
||||
// First get a clean list of only the currently running plugins, we don't want to mess those up
|
||||
for( PluginMap::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); )
|
||||
for (PluginMap::iterator itr = m_Plugins.begin(); itr != m_Plugins.end();)
|
||||
{
|
||||
if( itr->second == NULL )
|
||||
{
|
||||
@ -103,7 +80,7 @@ void cPluginManager::FindPlugins()
|
||||
}
|
||||
|
||||
// Add plugin name/directory to the list
|
||||
if( m_Plugins.find( *itr ) == m_Plugins.end() )
|
||||
if (m_Plugins.find( *itr ) == m_Plugins.end())
|
||||
{
|
||||
m_Plugins[ *itr ] = NULL;
|
||||
}
|
||||
@ -114,71 +91,51 @@ void cPluginManager::FindPlugins()
|
||||
|
||||
|
||||
|
||||
void cPluginManager::ReloadPluginsNow()
|
||||
void cPluginManager::ReloadPluginsNow(void)
|
||||
{
|
||||
LOG("Loading plugins");
|
||||
m_bReloadPlugins = false;
|
||||
UnloadPluginsNow();
|
||||
|
||||
#ifdef USE_SQUIRREL
|
||||
CloseSquirrelVM();
|
||||
OpenSquirrelVM();
|
||||
#endif // USE_SQUIRREL
|
||||
|
||||
FindPlugins();
|
||||
|
||||
cIniFile IniFile("settings.ini");
|
||||
if (!IniFile.ReadFile() )
|
||||
if (!IniFile.ReadFile())
|
||||
{
|
||||
LOGWARNING("cPluginManager: Can't find settings.ini, so can't load any plugins.");
|
||||
}
|
||||
|
||||
unsigned int KeyNum = IniFile.FindKey("Plugins");
|
||||
unsigned int NumPlugins = IniFile.GetNumValues( KeyNum );
|
||||
if( NumPlugins > 0 )
|
||||
unsigned int NumPlugins = IniFile.GetNumValues(KeyNum);
|
||||
if (NumPlugins > 0)
|
||||
{
|
||||
for(unsigned int i = 0; i < NumPlugins; i++)
|
||||
{
|
||||
AString ValueName = IniFile.GetValueName(KeyNum, i );
|
||||
if( (ValueName.compare("NewPlugin") == 0) || (ValueName.compare("Plugin") == 0) ) // New plugin style
|
||||
if (
|
||||
(ValueName.compare("NewPlugin") == 0) ||
|
||||
(ValueName.compare("Plugin") == 0)
|
||||
)
|
||||
{
|
||||
AString PluginFile = IniFile.GetValue(KeyNum, i );
|
||||
if( !PluginFile.empty() )
|
||||
AString PluginFile = IniFile.GetValue(KeyNum, i);
|
||||
if (!PluginFile.empty())
|
||||
{
|
||||
if( m_Plugins.find( PluginFile ) != m_Plugins.end() )
|
||||
if (m_Plugins.find(PluginFile) != m_Plugins.end())
|
||||
{
|
||||
LoadPlugin( PluginFile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_SQUIRREL
|
||||
else if( ValueName.compare("Squirrel") == 0 ) // Squirrel plugin
|
||||
{
|
||||
AString PluginFile = IniFile.GetValue(KeyNum, i );
|
||||
if( !PluginFile.empty() )
|
||||
{
|
||||
LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() );
|
||||
|
||||
cPlugin_Squirrel *Plugin = new cPlugin_Squirrel(PluginFile.c_str());
|
||||
|
||||
if( !AddPlugin( Plugin ) )
|
||||
{
|
||||
delete Plugin;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // USE_SQUIRREL
|
||||
}
|
||||
}
|
||||
|
||||
if( GetNumPlugins() == 0 )
|
||||
if (GetNumPlugins() == 0)
|
||||
{
|
||||
LOG("No plugins loaded");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Loaded %i plugin(s)", GetNumPlugins() );
|
||||
LOG("Loaded %i plugin(s)", GetNumPlugins());
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,23 +145,23 @@ void cPluginManager::ReloadPluginsNow()
|
||||
|
||||
void cPluginManager::Tick(float a_Dt)
|
||||
{
|
||||
while( m_DisablePluginList.size() > 0 )
|
||||
while (!m_DisablePluginList.empty())
|
||||
{
|
||||
RemovePlugin( m_DisablePluginList.front(), true );
|
||||
RemovePlugin(m_DisablePluginList.front());
|
||||
m_DisablePluginList.pop_front();
|
||||
}
|
||||
|
||||
if( m_bReloadPlugins )
|
||||
if (m_bReloadPlugins)
|
||||
{
|
||||
ReloadPluginsNow();
|
||||
}
|
||||
|
||||
HookMap::iterator Plugins = m_Hooks.find(HOOK_TICK);
|
||||
if( Plugins != m_Hooks.end() )
|
||||
if (Plugins != m_Hooks.end())
|
||||
{
|
||||
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
|
||||
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
|
||||
{
|
||||
(*itr)->Tick( a_Dt );
|
||||
(*itr)->Tick(a_Dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -240,22 +197,17 @@ bool cPluginManager::CallHookBlockToPickups(
|
||||
|
||||
bool cPluginManager::CallHookChat(cPlayer * a_Player, const AString & a_Message)
|
||||
{
|
||||
#ifdef USE_SQUIRREL
|
||||
if (m_SquirrelCommandBinder->HandleCommand(a_Message, a_Player))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif // USE_SQUIRREL
|
||||
|
||||
if (m_LuaCommandBinder->HandleCommand(a_Message, a_Player))
|
||||
if (ExecuteCommand(a_Player, a_Message))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it was a standard command (starts with a slash)
|
||||
if (a_Message[0] == '/')
|
||||
if (!a_Message.empty() && (a_Message[0] == '/'))
|
||||
{
|
||||
a_Player->SendMessage("Unknown Command");
|
||||
AStringVector Split(StringSplit(a_Message, " "));
|
||||
ASSERT(!Split.empty()); // This should not happen - we know there's at least one char in the message so the split needs to be at least one item long
|
||||
a_Player->SendMessage(Printf("Unknown Command: \"%s\"", Split[0].c_str()));
|
||||
LOGINFO("Player \"%s\" issued an unknown command: \"%s\"", a_Player->GetName().c_str(), a_Message.c_str());
|
||||
return true; // Cancel sending
|
||||
}
|
||||
@ -911,7 +863,43 @@ bool cPluginManager::CallHookWeatherChanged(cWorld * a_World)
|
||||
|
||||
|
||||
|
||||
cPlugin* cPluginManager::GetPlugin( const AString & a_Plugin ) const
|
||||
bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions)
|
||||
{
|
||||
ASSERT(a_Player != NULL);
|
||||
|
||||
AStringVector Split(StringSplit(a_Command, " "));
|
||||
if (Split.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CommandMap::iterator cmd = m_Commands.find(Split[0]);
|
||||
if (cmd == m_Commands.end())
|
||||
{
|
||||
// Command not found
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
a_ShouldCheckPermissions &&
|
||||
!cmd->second.m_Permission.empty() &&
|
||||
!a_Player->HasPermission(cmd->second.m_Permission)
|
||||
)
|
||||
{
|
||||
LOGINFO("Player \"%s\" tried to execute forbidden command \"%s\".", a_Player->GetName().c_str(), Split[0].c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERT(cmd->second.m_Plugin != NULL);
|
||||
|
||||
return cmd->second.m_Plugin->HandleCommand(Split, a_Player);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPlugin * cPluginManager::GetPlugin( const AString & a_Plugin ) const
|
||||
{
|
||||
for( PluginMap::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr )
|
||||
{
|
||||
@ -941,9 +929,9 @@ void cPluginManager::UnloadPluginsNow()
|
||||
{
|
||||
m_Hooks.clear();
|
||||
|
||||
while( m_Plugins.size() > 0 )
|
||||
while (!m_Plugins.empty())
|
||||
{
|
||||
RemovePlugin( m_Plugins.begin()->second, true );
|
||||
RemovePlugin(m_Plugins.begin()->second);
|
||||
}
|
||||
|
||||
//SquirrelVM::Shutdown(); // This breaks shit
|
||||
@ -953,18 +941,20 @@ void cPluginManager::UnloadPluginsNow()
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::DisablePlugin( AString & a_PluginName )
|
||||
bool cPluginManager::DisablePlugin(const AString & a_PluginName)
|
||||
{
|
||||
PluginMap::iterator itr = m_Plugins.find( a_PluginName );
|
||||
if (itr != m_Plugins.end())
|
||||
PluginMap::iterator itr = m_Plugins.find(a_PluginName);
|
||||
if (itr == m_Plugins.end())
|
||||
{
|
||||
if (itr->first.compare( a_PluginName ) == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (itr->first.compare(a_PluginName) == 0) // _X 2013_02_01: wtf? Isn't this supposed to be what find() does?
|
||||
{
|
||||
m_DisablePluginList.push_back( itr->second );
|
||||
m_DisablePluginList.push_back(itr->second);
|
||||
itr->second = NULL; // Get rid of this thing right away
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -972,15 +962,9 @@ bool cPluginManager::DisablePlugin( AString & a_PluginName )
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::LoadPlugin( AString & a_PluginName )
|
||||
bool cPluginManager::LoadPlugin(const AString & a_PluginName)
|
||||
{
|
||||
cPlugin_NewLua* Plugin = new cPlugin_NewLua( a_PluginName.c_str() );
|
||||
if (!AddPlugin(Plugin))
|
||||
{
|
||||
delete Plugin;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return AddPlugin(new cPlugin_NewLua(a_PluginName.c_str()));
|
||||
}
|
||||
|
||||
|
||||
@ -999,47 +983,137 @@ void cPluginManager::RemoveHooks(cPlugin * a_Plugin)
|
||||
|
||||
|
||||
|
||||
void cPluginManager::RemovePlugin( cPlugin * a_Plugin, bool a_bDelete /* = false */ )
|
||||
void cPluginManager::RemovePlugin(cPlugin * a_Plugin)
|
||||
{
|
||||
if( a_bDelete )
|
||||
for (PluginMap::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr)
|
||||
{
|
||||
m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin );
|
||||
#ifdef USE_SQUIRREL
|
||||
m_SquirrelCommandBinder->RemoveBindingsForPlugin( a_Plugin );
|
||||
#endif
|
||||
|
||||
for( PluginMap::iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr )
|
||||
if (itr->second == a_Plugin)
|
||||
{
|
||||
if( itr->second == a_Plugin )
|
||||
{
|
||||
m_Plugins.erase( itr );
|
||||
m_Plugins.erase(itr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( a_Plugin != NULL )
|
||||
|
||||
RemovePluginCommands(a_Plugin);
|
||||
RemoveHooks(a_Plugin);
|
||||
if (a_Plugin != NULL)
|
||||
{
|
||||
RemoveHooks( a_Plugin );
|
||||
a_Plugin->OnDisable();
|
||||
}
|
||||
delete a_Plugin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::AddPlugin( cPlugin* a_Plugin )
|
||||
void cPluginManager::RemovePluginCommands(cPlugin * a_Plugin)
|
||||
{
|
||||
a_Plugin->m_bCanBindCommands = true;
|
||||
if( a_Plugin->Initialize() )
|
||||
if (a_Plugin != NULL)
|
||||
{
|
||||
m_Plugins[ a_Plugin->GetDirectory() ] = a_Plugin;
|
||||
a_Plugin->ClearCommands();
|
||||
}
|
||||
|
||||
for (CommandMap::iterator itr = m_Commands.begin(); itr != m_Commands.end();)
|
||||
{
|
||||
if (itr->second.m_Plugin == a_Plugin)
|
||||
{
|
||||
itr = m_Commands.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
} // for itr - m_Commands[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::BindCommand(const AString & a_Command, cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString)
|
||||
{
|
||||
CommandMap::iterator cmd = m_Commands.find(a_Command);
|
||||
if (cmd != m_Commands.end())
|
||||
{
|
||||
LOGWARNING("Command \"%s\" is already bound to plugin \"%s\".", a_Command.c_str(), cmd->second.m_Plugin->GetName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Commands[a_Command].m_Plugin = a_Plugin;
|
||||
m_Commands[a_Command].m_Permission = a_Permission;
|
||||
m_Commands[a_Command].m_HelpString = a_HelpString;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::ForEachCommand(cCommandEnumCallback & a_Callback)
|
||||
{
|
||||
for (CommandMap::iterator itr = m_Commands.begin(), end = m_Commands.end(); itr != end; ++itr)
|
||||
{
|
||||
if (a_Callback.Command(itr->first, itr->second.m_Plugin, itr->second.m_Permission, itr->second.m_HelpString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // for itr - m_Commands[]
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::IsCommandBound(const AString & a_Command)
|
||||
{
|
||||
return (m_Commands.find(a_Command) != m_Commands.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cPluginManager::GetCommandPermission(const AString & a_Command)
|
||||
{
|
||||
CommandMap::iterator cmd = m_Commands.find(a_Command);
|
||||
return (cmd == m_Commands.end()) ? "" : cmd->second.m_Permission;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command)
|
||||
{
|
||||
return HandleCommand(a_Player, a_Command, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command)
|
||||
{
|
||||
return HandleCommand(a_Player, a_Command, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::AddPlugin(cPlugin * a_Plugin)
|
||||
{
|
||||
m_Plugins[a_Plugin->GetDirectory()] = a_Plugin;
|
||||
if (a_Plugin->Initialize())
|
||||
{
|
||||
// Initialization OK
|
||||
return true;
|
||||
}
|
||||
|
||||
a_Plugin->m_bCanBindCommands = false;
|
||||
RemoveHooks( a_Plugin ); // Undo any damage the Initialize() might have done
|
||||
// Initialization failed
|
||||
RemovePlugin(a_Plugin); // Also undoes any registrations that Initialize() might have made
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1075,17 +1149,3 @@ unsigned int cPluginManager::GetNumPlugins() const
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::HasPlugin( cPlugin* a_Plugin ) const
|
||||
{
|
||||
for( PluginMap::const_iterator itr = m_Plugins.begin(); itr != m_Plugins.end(); ++itr )
|
||||
{
|
||||
if( itr->second == a_Plugin )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3,13 +3,6 @@
|
||||
|
||||
#include "Item.h"
|
||||
|
||||
struct lua_State;
|
||||
class cLuaCommandBinder;
|
||||
|
||||
#ifdef USE_SQUIRREL
|
||||
class cSquirrelCommandBinder;
|
||||
#endif // USE_SQUIRREL
|
||||
|
||||
class cPlugin;
|
||||
|
||||
// fwd: World.h
|
||||
@ -84,7 +77,16 @@ public: // tolua_export
|
||||
} ;
|
||||
// tolua_end
|
||||
|
||||
static cPluginManager * GetPluginManager(); // tolua_export
|
||||
/// Used as a callback for enumerating bound commands
|
||||
class cCommandEnumCallback
|
||||
{
|
||||
public:
|
||||
/// Called for each command; return true to abort enumeration
|
||||
virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) = 0;
|
||||
} ;
|
||||
|
||||
/// Returns the instance of the Plugin Manager (there is only ever one)
|
||||
static cPluginManager * Get(void); // tolua_export
|
||||
|
||||
typedef std::map< AString, cPlugin * > PluginMap;
|
||||
typedef std::list< cPlugin * > PluginList;
|
||||
@ -93,7 +95,6 @@ public: // tolua_export
|
||||
|
||||
void FindPlugins(); // tolua_export
|
||||
void ReloadPlugins(); // tolua_export
|
||||
bool AddPlugin( cPlugin* a_Plugin );
|
||||
void AddHook( cPlugin* a_Plugin, PluginHook a_Hook ); // tolua_export
|
||||
|
||||
unsigned int GetNumPlugins() const; // tolua_export
|
||||
@ -131,45 +132,69 @@ public: // tolua_export
|
||||
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
|
||||
bool CallHookWeatherChanged (cWorld * a_World);
|
||||
|
||||
bool DisablePlugin( AString & a_PluginName ); // tolua_export
|
||||
bool LoadPlugin( AString & a_PluginName ); // tolua_export
|
||||
bool DisablePlugin(const AString & a_PluginName); // tolua_export
|
||||
bool LoadPlugin (const AString & a_PluginName); // tolua_export
|
||||
|
||||
void RemoveHooks( cPlugin * a_Plugin );
|
||||
void RemovePlugin( cPlugin * a_Plugin, bool a_bDelete = false );
|
||||
/// Removes all hooks the specified plugin has registered
|
||||
void RemoveHooks(cPlugin * a_Plugin);
|
||||
|
||||
cLuaCommandBinder* GetLuaCommandBinder() const { return m_LuaCommandBinder; }
|
||||
/// Removes the plugin from the internal structures and deletes its object.
|
||||
void RemovePlugin(cPlugin * a_Plugin);
|
||||
|
||||
#ifdef USE_SQUIRREL
|
||||
cSquirrelCommandBinder * GetSquirrelCommandBinder() { return m_SquirrelCommandBinder; }
|
||||
#endif // USE_SQUIRREL
|
||||
/// Removes all command bindings that the specified plugin has made
|
||||
void RemovePluginCommands(cPlugin * a_Plugin);
|
||||
|
||||
bool HasPlugin( cPlugin* a_Plugin ) const;
|
||||
/// Binds a command to the specified plugin. Returns true if successful, false if command already bound.
|
||||
bool BindCommand(const AString & a_Command, cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString); // Exported in ManualBindings.cpp, without the a_Plugin param
|
||||
|
||||
/// Calls a_Callback for each bound command, returns true if all commands were enumerated
|
||||
bool ForEachCommand(cCommandEnumCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Returns true if the command is in the command map
|
||||
bool IsCommandBound(const AString & a_Command); // tolua_export
|
||||
|
||||
/// Returns the permission needed for the specified command; empty string if command not found
|
||||
AString GetCommandPermission(const AString & a_Command); // tolua_export
|
||||
|
||||
/// Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed.
|
||||
bool ExecuteCommand(cPlayer * a_Player, const AString & a_Command);
|
||||
|
||||
/// Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found)
|
||||
bool ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command);
|
||||
|
||||
private:
|
||||
|
||||
friend class cRoot;
|
||||
|
||||
class cCommandReg
|
||||
{
|
||||
public:
|
||||
cPlugin * m_Plugin;
|
||||
AString m_Permission;
|
||||
AString m_HelpString;
|
||||
} ;
|
||||
|
||||
typedef std::map< cPluginManager::PluginHook, cPluginManager::PluginList > HookMap;
|
||||
typedef std::map<AString, cCommandReg> CommandMap;
|
||||
|
||||
PluginList m_DisablePluginList;
|
||||
PluginMap m_Plugins;
|
||||
HookMap m_Hooks;
|
||||
CommandMap m_Commands;
|
||||
|
||||
bool m_bReloadPlugins;
|
||||
|
||||
cPluginManager();
|
||||
~cPluginManager();
|
||||
|
||||
typedef std::map< cPluginManager::PluginHook, cPluginManager::PluginList > HookMap;
|
||||
void ReloadPluginsNow(void);
|
||||
void UnloadPluginsNow(void);
|
||||
|
||||
PluginList m_DisablePluginList;
|
||||
/// Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again.
|
||||
bool AddPlugin(cPlugin * a_Plugin);
|
||||
|
||||
PluginMap m_Plugins;
|
||||
HookMap m_Hooks;
|
||||
|
||||
void ReloadPluginsNow();
|
||||
void UnloadPluginsNow();
|
||||
|
||||
cLuaCommandBinder * m_LuaCommandBinder;
|
||||
|
||||
#ifdef USE_SQUIRREL
|
||||
cSquirrelCommandBinder * m_SquirrelCommandBinder;
|
||||
#endif // USE_SQUIRREL
|
||||
|
||||
bool m_bReloadPlugins;
|
||||
}; // tolua_export
|
||||
/// Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled.
|
||||
bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions);
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
@ -18,7 +18,18 @@ extern "C"
|
||||
|
||||
|
||||
|
||||
extern bool report_errors(lua_State * lua, int status);
|
||||
bool report_errors(lua_State * lua, int status)
|
||||
{
|
||||
if (status == 0)
|
||||
{
|
||||
// No error to report
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGERROR("LUA: %s", lua_tostring(lua, -1));
|
||||
lua_pop(lua, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -53,15 +64,21 @@ cPlugin_NewLua::~cPlugin_NewLua()
|
||||
|
||||
|
||||
|
||||
bool cPlugin_NewLua::Initialize()
|
||||
bool cPlugin_NewLua::Initialize(void)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
if( !m_LuaState )
|
||||
if (m_LuaState == NULL)
|
||||
{
|
||||
m_LuaState = lua_open();
|
||||
luaL_openlibs( m_LuaState );
|
||||
luaL_openlibs(m_LuaState);
|
||||
tolua_AllToLua_open(m_LuaState);
|
||||
ManualBindings::Bind( m_LuaState );
|
||||
ManualBindings::Bind(m_LuaState);
|
||||
|
||||
// Inject the identification global variables into the state:
|
||||
lua_pushlightuserdata(m_LuaState, this);
|
||||
lua_setglobal(m_LuaState, LUA_PLUGIN_INSTANCE_VAR_NAME);
|
||||
lua_pushstring(m_LuaState, GetName().c_str());
|
||||
lua_setglobal(m_LuaState, LUA_PLUGIN_NAME_VAR_NAME);
|
||||
}
|
||||
|
||||
std::string PluginPath = FILE_IO_PREFIX + GetLocalDirectory() + "/";
|
||||
@ -1134,6 +1151,80 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld * a_World)
|
||||
|
||||
|
||||
|
||||
bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Player)
|
||||
{
|
||||
ASSERT(!a_Split.empty());
|
||||
CommandMap::iterator cmd = m_Commands.find(a_Split[0]);
|
||||
if (cmd == m_Commands.end())
|
||||
{
|
||||
LOGWARNING("Command handler registered in cPluginManager but not in cPlugin, wtf? Command \"%s\".", a_Split[0].c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
|
||||
// Push the function to be called:
|
||||
LOGD("1. Stack size: %i", lua_gettop(m_LuaState));
|
||||
lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref()
|
||||
|
||||
// Push the split:
|
||||
LOGD("2. Stack size: %i", lua_gettop(m_LuaState));
|
||||
lua_createtable(m_LuaState, a_Split.size(), 0);
|
||||
int newTable = lua_gettop(m_LuaState);
|
||||
int index = 1;
|
||||
std::vector<std::string>::const_iterator iter = a_Split.begin(), end = a_Split.end();
|
||||
while(iter != end)
|
||||
{
|
||||
tolua_pushstring(m_LuaState, (*iter).c_str());
|
||||
lua_rawseti(m_LuaState, newTable, index);
|
||||
++iter;
|
||||
++index;
|
||||
}
|
||||
LOGD("3. Stack size: %i", lua_gettop(m_LuaState));
|
||||
|
||||
// Push player:
|
||||
tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
|
||||
|
||||
// Call function:
|
||||
LOGD("Calling bound function! :D");
|
||||
int s = lua_pcall(m_LuaState, 2, 1, 0);
|
||||
if (report_errors(m_LuaState, s))
|
||||
{
|
||||
LOGERROR("error. Stack size: %i", lua_gettop(m_LuaState));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle return value:
|
||||
bool RetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0);
|
||||
lua_pop(m_LuaState, 1); // Pop return value
|
||||
LOGD("ok. Stack size: %i", lua_gettop(m_LuaState));
|
||||
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlugin_NewLua::ClearCommands(void)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
|
||||
// Unreference the bound functions so that Lua can GC them
|
||||
if (m_LuaState != NULL)
|
||||
{
|
||||
for (CommandMap::iterator itr = m_Commands.begin(), end = m_Commands.end(); itr != end; ++itr)
|
||||
{
|
||||
luaL_unref(m_LuaState, LUA_REGISTRYINDEX, itr->second);
|
||||
}
|
||||
}
|
||||
m_Commands.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlugin_NewLua::CanAddHook(cPluginManager::PluginHook a_Hook)
|
||||
{
|
||||
const char * FnName = GetHookFnName(a_Hook);
|
||||
@ -1305,9 +1396,25 @@ bool cPlugin_NewLua::AddWebTab( const AString & a_Title, lua_State * a_LuaState,
|
||||
|
||||
|
||||
|
||||
void cPlugin_NewLua::BindCommand(const AString & a_Command, int a_FnRef)
|
||||
{
|
||||
ASSERT(m_Commands.find(a_Command) == m_Commands.end());
|
||||
m_Commands[a_Command] = a_FnRef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Helper functions
|
||||
bool cPlugin_NewLua::PushFunction(const char * a_FunctionName, bool a_bLogError /* = true */)
|
||||
{
|
||||
if (m_LuaState == NULL)
|
||||
{
|
||||
// This happens if Initialize() fails with an error
|
||||
return false;
|
||||
}
|
||||
|
||||
lua_getglobal(m_LuaState, a_FunctionName);
|
||||
if (!lua_isfunction(m_LuaState, -1))
|
||||
{
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include "Plugin.h"
|
||||
#include "WebPlugin.h"
|
||||
|
||||
// Names for the global variables through which the plugin is identified in its LuaState
|
||||
#define LUA_PLUGIN_NAME_VAR_NAME "_MCServerInternal_PluginName"
|
||||
#define LUA_PLUGIN_INSTANCE_VAR_NAME "_MCServerInternal_PluginInstance"
|
||||
|
||||
|
||||
|
||||
@ -63,6 +66,10 @@ public:
|
||||
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override;
|
||||
virtual bool OnWeatherChanged (cWorld * a_World) override;
|
||||
|
||||
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override;
|
||||
|
||||
virtual void ClearCommands(void) override;
|
||||
|
||||
virtual bool CanAddHook(cPluginManager::PluginHook a_Hook) override;
|
||||
|
||||
// cWebPlugin override
|
||||
@ -72,20 +79,27 @@ public:
|
||||
virtual AString HandleWebRequest( HTTPRequest * a_Request ) override;
|
||||
bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
/// Binds the command to call the function specified by a Lua function reference. Simply adds to CommandMap.
|
||||
void BindCommand(const AString & a_Command, int a_FnRef);
|
||||
|
||||
lua_State* GetLuaState() { return m_LuaState; }
|
||||
|
||||
cCriticalSection & GetCriticalSection() { return m_CriticalSection; }
|
||||
|
||||
protected:
|
||||
cCriticalSection m_CriticalSection;
|
||||
lua_State * m_LuaState;
|
||||
|
||||
/// Maps command name into Lua function reference
|
||||
typedef std::map<AString, int> CommandMap;
|
||||
|
||||
CommandMap m_Commands;
|
||||
|
||||
bool PushFunction(const char * a_FunctionName, bool a_bLogError = true);
|
||||
bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName ); // a_FunctionName is only used for error messages, nothing else
|
||||
|
||||
/// Returns the name of Lua function that should handle the specified hook
|
||||
const char * GetHookFnName(cPluginManager::PluginHook a_Hook);
|
||||
|
||||
cCriticalSection m_CriticalSection;
|
||||
|
||||
lua_State * m_LuaState;
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user