summaryrefslogtreecommitdiffstats
path: root/MCServer
diff options
context:
space:
mode:
Diffstat (limited to 'MCServer')
-rw-r--r--MCServer/.gitignore1
-rw-r--r--MCServer/Plugins/APIDump/APIDesc.lua17
-rw-r--r--MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua7
-rw-r--r--MCServer/Plugins/APIDump/Writing-a-MCServer-plugin.html25
m---------MCServer/Plugins/Core0
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua35
-rw-r--r--MCServer/Plugins/InfoDump.lua218
-rw-r--r--MCServer/monsters.ini2
8 files changed, 236 insertions, 69 deletions
diff --git a/MCServer/.gitignore b/MCServer/.gitignore
index c18dd7a67..e3aebbf92 100644
--- a/MCServer/.gitignore
+++ b/MCServer/.gitignore
@@ -4,6 +4,7 @@
*.lib
*.ini
MCServer
+CommLogs/
logs
players
world*
diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua
index 347299a50..cbdb7797b 100644
--- a/MCServer/Plugins/APIDump/APIDesc.lua
+++ b/MCServer/Plugins/APIDump/APIDesc.lua
@@ -813,6 +813,20 @@ cFile:Delete("/usr/bin/virus.exe");
},
}, -- cFile
+ cFloater =
+ {
+ Desc = [[
+ When a player uses his/her fishing rod it creates a floater entity. This class manages it.
+ ]],
+ Functions =
+ {
+ CanPickup = { Params = "", Return = "bool", Notes = "Returns true if the floater gives an item when the player right clicks." },
+ GetAttachedMobID = { Params = "", Return = "EntityID", Notes = "A floater can get attached to an mob. When it is and this functions gets called it returns the mob ID. If it isn't attached to a mob it returns -1" },
+ GetOwnerID = { Params = "", Return = "EntityID", Notes = "Returns the EntityID of the player who owns the floater." },
+ },
+ Inherits = "cEntity",
+ },
+
cGroup =
{
Desc = [[
@@ -1667,7 +1681,7 @@ a_Player:OpenWindow(Window);
]],
Functions =
{
- Call = { Params = "Function name, [All the parameters divided with commas]", Notes = "This function allows you to call a function from another plugin. It can only use pass: integers, booleans, strings and usertypes (cPlayer, cEntity, cCuboid, etc.)." },
+ Call = { Params = "Function name, [All the parameters divided with commas]", Notes = "(<b>OBSOLETE</b>) This function allows you to call a function from another plugin. It can only use pass: integers, booleans, strings and usertypes (cPlayer, cEntity, cCuboid, etc.).<br /><br /><b>This function is obsolete and unsafe, use {{cPluginManager}}:CallPlugin() instead!</b>" },
GetDirectory = { Return = "string", Notes = "Returns the name of the folder where the plugin's files are. (APIDump)" },
GetLocalDirectory = { Notes = "OBSOLETE use GetLocalFolder instead." },
GetLocalFolder = { Return = "string", Notes = "Returns the path where the plugin's files are. (Plugins/APIDump)" },
@@ -1719,6 +1733,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
{ Params = "Command, Callback, HelpString", Return = "", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command." },
{ Params = "Command, Callback, HelpString", Return = "", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command." },
},
+ CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." },
DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." },
ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns true if executed." },
FindPlugins = { Params = "", Return = "", Notes = "Refreshes the list of plugins to include all folders inside the Plugins folder (potentially new disabled plugins)" },
diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua
index 85c943721..82d5bb390 100644
--- a/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua
+++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerTossingItem.lua
@@ -5,7 +5,7 @@ return
CalledWhen = "A player is tossing an item. Plugin may override / refuse.",
DefaultFnName = "OnPlayerTossingItem", -- also used as pagename
Desc = [[
- This hook is called when a {{cPlayer|player}} has tossed an item (Q keypress). The
+ This hook is called when a {{cPlayer|player}} has tossed an item. The
{{cPickup|pickup}} has not been spawned yet. Plugins may disallow the tossing, but in that case they
need to clean up - the player's client already thinks the item has been tossed so the
{{cInventory|inventory}} needs to be re-sent to the player.</p>
@@ -18,8 +18,9 @@ return
},
Returns = [[
If the function returns false or no value, other plugins' callbacks are called and finally MCServer
- creates the pickup for the item and tosses it, using {{cPlayer}}:TossItem. If the function returns
- true, no other callbacks are called for this event and MCServer doesn't toss the item.
+ creates the pickup for the item and tosses it, using {{cPlayer}}:TossHeldItem, {{cPlayer}}:TossEquippedItem,
+ or {{cPlayer}}:TossPickup. If the function returns true, no other callbacks are called for this event
+ and MCServer doesn't toss the item.
]],
}, -- HOOK_PLAYER_TOSSING_ITEM
}
diff --git a/MCServer/Plugins/APIDump/Writing-a-MCServer-plugin.html b/MCServer/Plugins/APIDump/Writing-a-MCServer-plugin.html
index 0e07cebdf..1eec4842a 100644
--- a/MCServer/Plugins/APIDump/Writing-a-MCServer-plugin.html
+++ b/MCServer/Plugins/APIDump/Writing-a-MCServer-plugin.html
@@ -25,7 +25,7 @@
</p>
<p>
Next, we must obtain a copy of CoreMessaging.lua. This can be found
- <a href="https://raw.github.com/mc-server/MCServer/master/MCServer/Plugins/MagicCarpet/coremessaging.lua">here.</a>
+ <a href="https://gist.github.com/bearbin/8715888">here.</a>
This is used to provide messaging support that is compliant with MCServer standards.
</p>
<h2>Creating the basic template</h2>
@@ -35,19 +35,14 @@
Format it like so:
</p>
<pre class="prettyprint lang-lua">
-local PLUGIN
+PLUGIN = nil
function Initialize(Plugin)
- Plugin:SetName("DerpyPlugin")
+ Plugin:SetName("NewPlugin")
Plugin:SetVersion(1)
PLUGIN = Plugin
- -- Hooks
-
- local PluginManager = cPluginManager:Get()
- -- Command bindings
-
LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
return true
end
@@ -84,7 +79,7 @@ end
To register a hook, insert the following code template into the "-- Hooks" area in the previous code example.
</p>
<pre class="prettyprint lang-lua">
-cPluginManager:AddHook(cPluginManager.HOOK_NAME_HERE, FunctionNameToBeCalled)
+cPluginManager.AddHook(cPluginManager.HOOK_NAME_HERE, FunctionNameToBeCalled)
</pre>
<p>
What does this code do?
@@ -102,10 +97,7 @@ function Initialize(Plugin)
Plugin:SetName("DerpyPlugin")
Plugin:SetVersion(1)
- cPluginManager:AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
-
- local PluginManager = cPluginManager:Get()
- -- Command bindings
+ cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
return true
@@ -127,10 +119,10 @@ end
</p>
<pre class="prettyprint lang-lua">
-- ADD THIS IF COMMAND DOES NOT REQUIRE A PARAMETER (/explode)
-PluginManager:BindCommand("/commandname", "permissionnode", FunctionToCall, " - Description of command")
+cPluginManager.BindCommand("/commandname", "permissionnode", FunctionToCall, " - Description of command")
-- ADD THIS IF COMMAND DOES REQUIRE A PARAMETER (/explode Notch)
-PluginManager:BindCommand("/commandname", "permissionnode", FunctionToCall, " ~ Description of command and parameter(s)")
+cPluginManager.BindCommand("/commandname", "permissionnode", FunctionToCall, " ~ Description of command and parameter(s)")
</pre>
<p>
What does it do, and why are there two?
@@ -197,8 +189,7 @@ function Initialize(Plugin)
Plugin:SetName("DerpyPluginThatBlowsPeopleUp")
Plugin:SetVersion(9001)
- local PluginManager = cPluginManager:Get()
- PluginManager:BindCommand("/explode", "derpyplugin.explode", Explode, " ~ Explode a player");
+ cPluginManager.BindCommand("/explode", "derpyplugin.explode", Explode, " ~ Explode a player");
cPluginManager:AddHook(cPluginManager.HOOK_COLLECTING_PICKUP, OnCollectingPickup)
diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core
-Subproject 759cf48ba3f1409e6d7b60cb821ee17e589bdef
+Subproject 1a36a2922d97062230fd93dee3d4638d69feb7c
diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua
index 2d2d2736d..624261cbf 100644
--- a/MCServer/Plugins/Debuggers/Debuggers.lua
+++ b/MCServer/Plugins/Debuggers/Debuggers.lua
@@ -64,7 +64,8 @@ function Initialize(Plugin)
-- TestBlockAreas();
-- TestSQLiteBindings();
-- TestExpatBindings();
-
+ TestPluginCalls();
+
return true
end;
@@ -72,6 +73,38 @@ end;
+function TestPluginCalls()
+ -- In order to test the inter-plugin communication, we're going to call Core's ReturnColorFromChar() function
+ -- It is a rather simple function that doesn't need any tables as its params and returns a value, too
+ -- Note the signature: function ReturnColorFromChar( Split, char ) ... return cChatColog.Gray ... end
+ -- The Split parameter should be a table, but it is not used in that function anyway,
+ -- so we can get away with passing nil to it.
+
+ -- Use the old, deprecated and unsafe method:
+ local Core = cPluginManager:Get():GetPlugin("Core")
+ if (Core ~= nil) then
+ LOGINFO("Calling Core::ReturnColorFromChar() the old-fashioned way...")
+ local Gray = Core:Call("ReturnColorFromChar", nil, "8")
+ if (Gray ~= cChatColor.Gray) then
+ LOGWARNING("Call failed, exp " .. cChatColor.Gray .. ", got " .. (Gray or "<nil>"))
+ else
+ LOGINFO("Call succeeded")
+ end
+ end
+
+ -- Use the new method:
+ LOGINFO("Calling Core::ReturnColorFromChar() the recommended way...")
+ local Gray = cPluginManager:CallPlugin("Core", "ReturnColorFromChar", nil, "8")
+ if (Gray ~= cChatColor.Gray) then
+ LOGWARNING("Call failed, exp " .. cChatColor.Gray .. ", got " .. (Gray or "<nil>"))
+ else
+ LOGINFO("Call succeeded")
+ end
+end
+
+
+
+
function TestBlockAreas()
LOG("Testing block areas...");
diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua
index df47d566b..6b1da7a77 100644
--- a/MCServer/Plugins/InfoDump.lua
+++ b/MCServer/Plugins/InfoDump.lua
@@ -2,10 +2,17 @@
-- InfoDump.lua
--- Goes through all subfolders, loads Info.lua and dumps its g_PluginInfo into various text formats
--- This is used for generating plugin documentation for the forum and for GitHub's INFO.md files
+--[[
+Loads plugins' Info.lua and dumps its g_PluginInfo into various text formats
+This is used for generating plugin documentation for the forum and for GitHub's INFO.md files
--- This script requires LuaRocks with LFS installed, instructions are printed when this is not present.
+This script can be used in two ways:
+Executing "lua InfoDump.lua" will go through all subfolders and dump each Info.lua file it can find
+ Note that this mode of operation requires LuaRocks with LFS installed; instructions are printed
+ when the prerequisites are not met.
+Executing "lua InfoDump.lua PluginName" will load the Info.lua file from PluginName's folder and dump
+only that one plugin's documentation. This mode of operation doesn't require LuaRocks
+--]]
@@ -17,33 +24,6 @@ if (_VERSION ~= "Lua 5.1") then
return;
end
--- Try to load lfs, do not abort if not found
-local lfs, err = pcall(
- function()
- return require("lfs")
- end
-);
-
--- Rather, print a nice message with instructions:
-if not(lfs) then
- print([[
-Cannot load LuaFileSystem
-Install it through luarocks by executing the following command:
- sudo luarocks install luafilesystem
-
-If you don't have luarocks installed, you need to install them using your OS's package manager, usually:
- sudo apt-get install luarocks
-On windows, a binary distribution can be downloaded from the LuaRocks homepage, http://luarocks.org/en/Download
-]]);
-
- print("Original error text: ", err);
- return;
-end
-
--- We now know that LFS is present, get it normally:
-lfs = require("lfs");
-
-
@@ -161,6 +141,21 @@ end
+--- Returns a string specifying the command.
+-- If a_Command is a simple string, returns a_Command colorized to blue
+-- If a_Command is a table, expects members Name (full command name) and Params (command parameters),
+-- colorizes command name blue and params green
+local function GetCommandRefForum(a_Command)
+ if (type(a_Command) == "string") then
+ return "[color=blue]" .. a_Command .. "[/color]";
+ end
+ return "[color=blue]" .. a_Command.Name .. "[/color] [color=green]" .. a_Command.Params .. "[/color]";
+end
+
+
+
+
+
--- Writes the specified command detailed help array to the output file, in the forum dump format
local function WriteCommandParameterCombinationsForum(a_CmdString, a_ParameterCombinations, f)
assert(type(a_CmdString) == "string");
@@ -270,6 +265,97 @@ end
+--- Collects all permissions mentioned in the info, returns them as a sorted array
+-- Each array item is {Name = "PermissionName", Info = { PermissionInfo }}
+local function BuildPermissions(a_PluginInfo)
+ -- Collect all used permissions from Commands, reference the commands that use the permission:
+ local Permissions = a_PluginInfo.Permissions or {};
+ local function CollectPermissions(a_CmdPrefix, a_Commands)
+ for cmd, info in pairs(a_Commands) do
+ CommandString = a_CmdPrefix .. cmd;
+ if ((info.Permission ~= nil) and (info.Permission ~= "")) then
+ -- Add the permission to the list of permissions:
+ local Permission = Permissions[info.Permission] or {};
+ Permissions[info.Permission] = Permission;
+ -- Add the command to the list of commands using this permission:
+ Permission.CommandsAffected = Permission.CommandsAffected or {};
+ table.insert(Permission.CommandsAffected, CommandString);
+ end
+
+ -- Process the command param combinations for permissions:
+ local ParamCombinations = info.ParameterCombinations or {};
+ for idx, comb in ipairs(ParamCombinations) do
+ if ((comb.Permission ~= nil) and (comb.Permission ~= "")) then
+ -- Add the permission to the list of permissions:
+ local Permission = Permissions[comb.Permission] or {};
+ Permissions[info.Permission] = Permission;
+ -- Add the command to the list of commands using this permission:
+ Permission.CommandsAffected = Permission.CommandsAffected or {};
+ table.insert(Permission.CommandsAffected, {Name = CommandString, Params = comb.Params});
+ end
+ end
+
+ -- Process subcommands:
+ if (info.Subcommands ~= nil) then
+ CollectPermissions(CommandString .. " ", info.Subcommands);
+ end
+ end
+ end
+ CollectPermissions("", a_PluginInfo.Commands);
+
+ -- Copy the list of permissions to an array:
+ local PermArray = {};
+ for name, perm in pairs(Permissions) do
+ table.insert(PermArray, {Name = name, Info = perm});
+ end
+
+ -- Sort the permissions array:
+ table.sort(PermArray,
+ function(p1, p2)
+ return (p1.Name < p2.Name);
+ end
+ );
+ return PermArray;
+end
+
+
+
+
+
+local function DumpPermissionsForum(a_PluginInfo, f)
+ -- Get the processed sorted array of permissions:
+ local Permissions = BuildPermissions(a_PluginInfo);
+ if ((Permissions == nil) or (#Permissions <= 0)) then
+ return;
+ end
+
+ -- Dump the permissions:
+ f:write("\n[size=X-Large]Permissions[/size]\n[list]\n");
+ for idx, perm in ipairs(Permissions) do
+ f:write(" - [color=red]", perm.Name, "[/color] - ");
+ f:write(perm.Info.Description or "");
+ local CommandsAffected = perm.Info.CommandsAffected or {};
+ if (#CommandsAffected > 0) then
+ f:write("\n[list] Commands affected:\n- ");
+ local Affects = {};
+ for idx2, cmd in ipairs(CommandsAffected) do
+ table.insert(Affects, GetCommandRefForum(cmd));
+ end
+ f:write(table.concat(Affects, "\n - "));
+ f:write("\n[/list]");
+ end
+ if (perm.Info.RecommendedGroups ~= nil) then
+ f:write("\n[list] Recommended groups: ", perm.Info.RecommendedGroups, "[/list]");
+ end
+ f:write("\n");
+ end
+ f:write("[/list]");
+end
+
+
+
+
+
local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo)
-- Open the output file:
local f, msg = io.open(a_PluginInfo.Name .. "_forum.txt", "w");
@@ -282,6 +368,7 @@ local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo)
f:write(ForumizeString(a_PluginInfo.Description), "\n");
DumpAdditionalInfoForum(a_PluginInfo, f);
DumpCommandsForum(a_PluginInfo, f);
+ DumpPermissionsForum(a_PluginInfo, f);
f:close();
end
@@ -301,12 +388,6 @@ end
--- Tries to load the g_PluginInfo from the plugin's Info.lua file
-- Returns the g_PluginInfo table on success, or nil and error message on failure
local function LoadPluginInfo(a_FolderName)
- -- Check if the Info file is present at all:
- local Attribs = lfs.attributes(a_FolderName .. "/Info.lua");
- if ((Attribs == nil) or (Attribs.mode ~= "file")) then
- return nil;
- end
-
-- Load and compile the Info file:
local cfg, err = loadfile(a_FolderName .. "/Info.lua");
if (cfg == nil) then
@@ -332,7 +413,7 @@ local function ProcessPluginFolder(a_FolderName)
local PluginInfo, Msg = LoadPluginInfo(a_FolderName);
if (PluginInfo == nil) then
if (Msg ~= nil) then
- print("\tCannot load Info.lua: " .. Msg);
+ print("\t" .. Msg);
end
return;
end
@@ -343,19 +424,64 @@ end
-print("Processing plugin subfolders:");
-for fnam in lfs.dir(".") do
- if ((fnam ~= ".") and (fnam ~= "..")) then
- local Attributes = lfs.attributes(fnam);
- if (Attributes ~= nil) then
- if (Attributes.mode == "directory") then
- print(fnam);
- ProcessPluginFolder(fnam);
- end
+--- Tries to load LFS through LuaRocks, returns the LFS instance, or nil on error
+local function LoadLFS()
+ -- Try to load lfs, do not abort if not found ...
+ local lfs, err = pcall(
+ function()
+ return require("lfs")
end
+ );
+
+ -- ... rather, print a nice message with instructions:
+ if not(lfs) then
+ print([[
+ Cannot load LuaFileSystem
+ Install it through luarocks by executing the following command:
+ luarocks install luafilesystem (Windows)
+ sudo luarocks install luafilesystem (*nix)
+
+ If you don't have luarocks installed, you need to install them using your OS's package manager, usually:
+ sudo apt-get install luarocks (Ubuntu / Debian)
+ On windows, a binary distribution can be downloaded from the LuaRocks homepage, http://luarocks.org/en/Download
+ ]]);
+
+ print("Original error text: ", err);
+ return nil;
end
+
+ -- We now know that LFS is present, get it normally:
+ return require("lfs");
end
+
+local Arg1 = ...;
+if ((Arg1 ~= nil) and (Arg1 ~= "")) then
+ -- Called with a plugin folder name, export only that one
+ ProcessPluginFolder(Arg1)
+else
+ -- Called without any arguments, process all subfolders:
+ local lfs = LoadLFS();
+ if (lfs == nil) then
+ -- LFS not loaded, error has already been printed, just bail out
+ return;
+ end
+ print("Processing plugin subfolders:");
+ for fnam in lfs.dir(".") do
+ if ((fnam ~= ".") and (fnam ~= "..")) then
+ local Attributes = lfs.attributes(fnam);
+ if (Attributes ~= nil) then
+ if (Attributes.mode == "directory") then
+ print(fnam);
+ ProcessPluginFolder(fnam);
+ end
+ end
+ end
+ end
+end
+print("Done.");
+
+
diff --git a/MCServer/monsters.ini b/MCServer/monsters.ini
index 94454c355..a1b63423e 100644
--- a/MCServer/monsters.ini
+++ b/MCServer/monsters.ini
@@ -62,7 +62,7 @@ SightDistance=25.0
MaxHealth=12
[Creeper]
-AttackRange=5.0
+AttackRange=3.0
AttackRate=1
AttackDamage=0.0
SightDistance=25.0