Merge branch 'master' of github.com:mc-server/MCServer
This commit is contained in:
commit
0b79ad0d5d
@ -1713,7 +1713,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Same as ExecuteCommand, but doesn't check permissions" },
|
||||
ForEachCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindCommand(). The CallbackFn has the following signature: <pre class=\"prettyprint lang-lua\">function(Command, Permission, HelpString)</pre>. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." },
|
||||
ForEachConsoleCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindConsoleCommand(). The CallbackFn has the following signature: <pre class=\"prettyprint lang-lua\">function (Command, HelpString)</pre>. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." },
|
||||
Get = { Params = "", Return = "cPluginManager", Notes = "Returns the single instance of the plugin manager" },
|
||||
Get = { Params = "", Return = "cPluginManager", Notes = "(STATIC) Returns the single instance of the plugin manager" },
|
||||
GetAllPlugins = { Params = "", Return = "table", Notes = "Returns a table (dictionary) of all plugins, [name => {{cPlugin}}] pairing." },
|
||||
GetCommandPermission = { Params = "Command", Return = "Permission", Notes = "Returns the permission needed for executing the specified command" },
|
||||
GetCurrentPlugin = { Params = "", Return = "{{cPlugin}}", Notes = "Returns the {{cPlugin}} object for the calling plugin. This is the same object that the Initialize function receives as the argument." },
|
||||
|
@ -84,7 +84,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,7 +102,7 @@ function Initialize(Plugin)
|
||||
Plugin:SetName("DerpyPlugin")
|
||||
Plugin:SetVersion(1)
|
||||
|
||||
cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
|
||||
cPluginManager:AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
|
||||
|
||||
local PluginManager = cPluginManager:Get()
|
||||
-- Command bindings
|
||||
@ -200,7 +200,7 @@ function Initialize(Plugin)
|
||||
local PluginManager = cPluginManager:Get()
|
||||
PluginManager:BindCommand("/explode", "derpyplugin.explode", Explode, " ~ Explode a player");
|
||||
|
||||
cPluginManager.AddHook(cPluginManager.HOOK_COLLECTING_PICKUP, OnCollectingPickup)
|
||||
cPluginManager:AddHook(cPluginManager.HOOK_COLLECTING_PICKUP, OnCollectingPickup)
|
||||
|
||||
LOG("Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
|
||||
return true
|
||||
|
@ -1177,7 +1177,7 @@ function WriteHtmlHook(a_Hook, a_HookNav)
|
||||
f:write("</table>\n<p>" .. (a_Hook.Returns or "") .. "</p>\n\n");
|
||||
f:write([[<hr /><h1>Code examples</h1><h2>Registering the callback</h2>]]);
|
||||
f:write("<pre class=\"prettyprint lang-lua\">\n");
|
||||
f:write([[cPluginManager.AddHook(cPluginManager.]] .. a_Hook.Name .. ", My" .. a_Hook.DefaultFnName .. [[);]]);
|
||||
f:write([[cPluginManager:AddHook(cPluginManager.]] .. a_Hook.Name .. ", My" .. a_Hook.DefaultFnName .. [[);]]);
|
||||
f:write("</pre>\n\n");
|
||||
local Examples = a_Hook.CodeExamples or {};
|
||||
for i, example in ipairs(Examples) do
|
||||
|
@ -963,3 +963,22 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
-- Test the hook adding formats in #121 and #401
|
||||
local function DoNothing()
|
||||
end
|
||||
|
||||
LOG("Trying cPluginManager:AddHook()");
|
||||
cPluginManager:AddHook(cPluginManager.HOOK_CHAT, DoNothing);
|
||||
|
||||
LOG("Trying cPluginManager.AddHook()");
|
||||
cPluginManager.AddHook(cPluginManager.HOOK_CHAT, DoNothing);
|
||||
|
||||
LOG("Trying cPluginManager:Get():AddHook()");
|
||||
cPluginManager:Get():AddHook(cPluginManager.HOOK_CHAT, DoNothing);
|
||||
|
||||
LOG("Trying cPluginManager:Get():AddHook(Plugin, Hook)");
|
||||
cPluginManager:Get():AddHook(cPluginManager:GetCurrentPlugin(), cPluginManager.HOOK_CHAT);
|
||||
|
||||
LOG("Trying cPluginManager.AddHook(Plugin, Hook)");
|
||||
cPluginManager.AddHook(cPluginManager:GetCurrentPlugin(), cPluginManager.HOOK_CHAT);
|
||||
|
6
MCServer/Plugins/InfoDump.deproj
Normal file
6
MCServer/Plugins/InfoDump.deproj
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<file>
|
||||
<filename>InfoDump.lua</filename>
|
||||
</file>
|
||||
</project>
|
361
MCServer/Plugins/InfoDump.lua
Normal file
361
MCServer/Plugins/InfoDump.lua
Normal file
@ -0,0 +1,361 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
-- 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
|
||||
|
||||
-- This script requires LuaRocks with LFS installed, instructions are printed when this is not present.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Check Lua version. We use 5.1-specific construct when loading the plugin info, 5.2 is not compatible!
|
||||
if (_VERSION ~= "Lua 5.1") then
|
||||
print("Unsupported Lua version. This script requires Lua version 5.1, this Lua is version " .. (_VERSION or "<nil>"));
|
||||
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");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Replaces generic formatting with forum-specific formatting
|
||||
-- Also removes the single line-ends
|
||||
local function ForumizeString(a_Str)
|
||||
assert(type(a_Str) == "string");
|
||||
|
||||
-- Remove the indentation, unless in the code tag:
|
||||
-- Only one code or /code tag per line is supported!
|
||||
local IsInCode = false;
|
||||
local function RemoveIndentIfNotInCode(s)
|
||||
if (IsInCode) then
|
||||
-- we're in code section, check if this line terminates it
|
||||
IsInCode = (s:find("{%%/code}") ~= nil);
|
||||
return s .. "\n";
|
||||
else
|
||||
-- we're not in code section, check if this line starts it
|
||||
IsInCode = (s:find("{%%code}") ~= nil);
|
||||
return s:gsub("^%s*", "") .. "\n";
|
||||
end
|
||||
end
|
||||
a_Str = a_Str:gsub("(.-)\n", RemoveIndentIfNotInCode);
|
||||
|
||||
-- Replace multiple line ends with {%p} and single line ends with a space,
|
||||
-- so that manual word-wrap in the Info.lua file doesn't wrap in the forum.
|
||||
a_Str = a_Str:gsub("\n\n", "{%%p}");
|
||||
a_Str = a_Str:gsub("\n", " ");
|
||||
|
||||
-- Replace the generic formatting:
|
||||
a_Str = a_Str:gsub("{%%p}", "\n\n");
|
||||
a_Str = a_Str:gsub("{%%b}", "[b]"):gsub("{%%/b}", "[/b]");
|
||||
a_Str = a_Str:gsub("{%%i}", "[i]"):gsub("{%%/i}", "[/i]");
|
||||
a_Str = a_Str:gsub("{%%list}", "[list]"):gsub("{%%/list}", "[/list]");
|
||||
a_Str = a_Str:gsub("{%%li}", "[*]"):gsub("{%%/li}", "");
|
||||
-- TODO: Other formatting
|
||||
|
||||
return a_Str;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Builds an array of categories, each containing all the commands belonging to the category,
|
||||
-- and the category description, if available.
|
||||
-- Returns the array table, each item has the following format:
|
||||
-- { Name = "CategoryName", Description = "CategoryDescription", Commands = {{CommandString = "/cmd verb", Info = {...}}, ...}}
|
||||
local function BuildCategories(a_PluginInfo)
|
||||
-- The returned result
|
||||
-- This will contain both an array and a dict of the categories, to allow fast search
|
||||
local res = {};
|
||||
|
||||
-- For each command add a reference to it into all of its categories:
|
||||
local function AddCommands(a_CmdPrefix, a_Commands)
|
||||
for cmd, info in pairs(a_Commands) do
|
||||
local NewCmd =
|
||||
{
|
||||
CommandString = a_CmdPrefix .. cmd,
|
||||
Info = info,
|
||||
}
|
||||
|
||||
if ((info.HelpString ~= nil) and (info.HelpString ~= "")) then
|
||||
-- Add to each specified category:
|
||||
local Category = info.Category;
|
||||
if (type(Category) == "string") then
|
||||
Category = {Category};
|
||||
end
|
||||
for idx, cat in ipairs(Category or {""}) do
|
||||
local CatEntry = res[cat];
|
||||
if (CatEntry == nil) then
|
||||
-- First time we came across this category, create it:
|
||||
local NewCat = {Name = cat, Description = "", Commands = {NewCmd}};
|
||||
table.insert(res, NewCat);
|
||||
res[cat] = NewCat;
|
||||
else
|
||||
-- We already have this category, just add the command to its list of commands:
|
||||
table.insert(CatEntry.Commands, NewCmd);
|
||||
end
|
||||
end -- for idx, cat - Category[]
|
||||
end -- if (HelpString valid)
|
||||
|
||||
-- Recurse all subcommands:
|
||||
if (info.Subcommands ~= nil) then
|
||||
AddCommands(a_CmdPrefix .. cmd .. " ", info.Subcommands);
|
||||
end
|
||||
end -- for cmd, info - a_Commands[]
|
||||
end -- AddCommands()
|
||||
|
||||
AddCommands("", a_PluginInfo.Commands);
|
||||
|
||||
-- Assign descriptions to categories:
|
||||
for name, desc in pairs(a_PluginInfo.Categories or {}) do
|
||||
local CatEntry = res[name];
|
||||
if (CatEntry ~= nil) then
|
||||
-- The result has this category, add the description:
|
||||
CatEntry.Description = desc.Description;
|
||||
end
|
||||
end
|
||||
|
||||
-- Alpha-sort each category's command list:
|
||||
for idx, cat in ipairs(res) do
|
||||
table.sort(cat.Commands,
|
||||
function (cmd1, cmd2)
|
||||
return (string.lower(cmd1.CommandString) < string.lower(cmd2.CommandString));
|
||||
end
|
||||
);
|
||||
end
|
||||
|
||||
return res;
|
||||
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");
|
||||
assert(type(a_ParameterCombinations) == "table");
|
||||
assert(f ~= nil);
|
||||
|
||||
if (#a_ParameterCombinations == 0) then
|
||||
-- No explicit parameter combinations to write
|
||||
return;
|
||||
end
|
||||
|
||||
f:write("The following parameter combinations are recognized:\n");
|
||||
for idx, combination in ipairs(a_ParameterCombinations) do
|
||||
f:write("[color=blue]", a_CmdString, "[/color] [color=green]", combination.Params, "[/color]");
|
||||
if (combination.Help ~= nil) then
|
||||
f:write(" - ", ForumizeString(combination.Help));
|
||||
end
|
||||
if (combination.Permission ~= nil) then
|
||||
f:write(" (Requires permission '[color=red]", combination.Permission, "[/color]')");
|
||||
end
|
||||
f:write("\n");
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Writes all commands in the specified category to the output file, in the forum dump format
|
||||
local function WriteCommandsCategoryForum(a_Category, f)
|
||||
-- Write category name:
|
||||
local CategoryName = a_Category.Name;
|
||||
if (CategoryName == "") then
|
||||
CategoryName = "General";
|
||||
end
|
||||
f:write("\n[size=Large]", ForumizeString(a_Category.DisplayName or CategoryName), "[/size]\n");
|
||||
|
||||
-- Write description:
|
||||
if (a_Category.Description ~= "") then
|
||||
f:write(ForumizeString(a_Category.Description), "\n");
|
||||
end
|
||||
|
||||
-- Write commands:
|
||||
f:write("\n[list]");
|
||||
for idx2, cmd in ipairs(a_Category.Commands) do
|
||||
f:write("\n[b]", cmd.CommandString, "[/b] - ", ForumizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n");
|
||||
if (cmd.Info.Permission ~= nil) then
|
||||
f:write("Permission required: [color=red]", cmd.Info.Permission, "[/color]\n");
|
||||
end
|
||||
if (cmd.Info.DetailedDescription ~= nil) then
|
||||
f:write(cmd.Info.DetailedDescription);
|
||||
end
|
||||
if (cmd.Info.ParameterCombinations ~= nil) then
|
||||
WriteCommandParameterCombinationsForum(cmd.CommandString, cmd.Info.ParameterCombinations, f);
|
||||
end
|
||||
end
|
||||
f:write("[/list]\n\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function DumpCommandsForum(a_PluginInfo, f)
|
||||
-- Copy all Categories from a dictionary into an array:
|
||||
local Categories = BuildCategories(a_PluginInfo);
|
||||
|
||||
-- Sort the categories by name:
|
||||
table.sort(Categories,
|
||||
function(cat1, cat2)
|
||||
return (string.lower(cat1.Name) < string.lower(cat2.Name));
|
||||
end
|
||||
);
|
||||
|
||||
if (#Categories == 0) then
|
||||
return;
|
||||
end
|
||||
|
||||
f:write("\n[size=X-Large]Commands[/size]\n");
|
||||
|
||||
-- Dump per-category commands:
|
||||
for idx, cat in ipairs(Categories) do
|
||||
WriteCommandsCategoryForum(cat, f);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function DumpAdditionalInfoForum(a_PluginInfo, f)
|
||||
local AInfo = a_PluginInfo.AdditionalInfo;
|
||||
if ((AInfo == nil) or (type(AInfo) ~= "table")) then
|
||||
-- There is no AdditionalInfo in a_PluginInfo
|
||||
return;
|
||||
end
|
||||
|
||||
for idx, info in ipairs(a_PluginInfo.AdditionalInfo) do
|
||||
if ((info.Title ~= nil) and (info.Contents ~= nil)) then
|
||||
f:write("\n[size=X-Large]", ForumizeString(info.Title), "[/size]\n");
|
||||
f:write(ForumizeString(info.Contents), "\n");
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo)
|
||||
-- Open the output file:
|
||||
local f, msg = io.open(a_PluginInfo.Name .. "_forum.txt", "w");
|
||||
if (f == nil) then
|
||||
print("\tCannot dump forum info for plugin " .. a_PluginFolder .. ": " .. msg);
|
||||
return;
|
||||
end
|
||||
|
||||
-- Write the description:
|
||||
f:write(ForumizeString(a_PluginInfo.Description), "\n");
|
||||
DumpAdditionalInfoForum(a_PluginInfo, f);
|
||||
DumpCommandsForum(a_PluginInfo, f);
|
||||
|
||||
f:close();
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function DumpPluginInfoGitHub()
|
||||
-- TODO
|
||||
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
|
||||
return nil, "Cannot open 'Info.lua': " .. err;
|
||||
end
|
||||
|
||||
-- Execute the loaded file in a sandbox:
|
||||
-- This is Lua-5.1-specific and won't work in Lua 5.2!
|
||||
local Sandbox = {};
|
||||
setfenv(cfg, Sandbox);
|
||||
cfg();
|
||||
if (Sandbox.g_PluginInfo == nil) then
|
||||
return nil, "Info.lua doesn't contain the g_PluginInfo declaration";
|
||||
end
|
||||
return Sandbox.g_PluginInfo;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
end
|
||||
return;
|
||||
end
|
||||
DumpPluginInfoForum(a_FolderName, PluginInfo);
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
MCServer
|
||||
========
|
||||
|
||||
**Current Protocol Supported:** Minecraft v1.2 -> v1.7
|
||||
|
||||
MCServer is a performant C++ Minecraft server designed for use in memory and cpu-limited places, or just to make regular server perform better.
|
||||
|
||||
MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis.
|
||||
@ -26,7 +28,7 @@ MCServer is licensed under the Apache license V2, and we welcome anybody to fork
|
||||
Other Stuff
|
||||
-----------
|
||||
|
||||
For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [wiki](http://mc-server.org/wiki/).
|
||||
For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [wiki](http://wiki.mc-server.org/).
|
||||
|
||||
Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Version="9.00"
|
||||
Name="CryptoPP"
|
||||
ProjectGUID="{3423EC9A-52E4-4A4D-9753-EDEBC38785EF}"
|
||||
RootNamespace="cryptlib"
|
||||
@ -60,6 +60,7 @@
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4702"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -1578,6 +1578,10 @@
|
||||
RelativePath="..\src\OSSupport\ListenThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\OSSupport\Queue.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\OSSupport\Semaphore.cpp"
|
||||
>
|
||||
|
@ -1137,16 +1137,17 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S)
|
||||
{
|
||||
/*
|
||||
Function signatures:
|
||||
cPluginManager.AddHook(HOOK_TYPE, CallbackFunction) -- (1) recommended
|
||||
cPluginManager:Get():AddHook(HOOK_TYPE, CallbackFunction) -- (2) accepted silently
|
||||
cPluginManager:Get():AddHook(Plugin, HOOK_TYPE) -- (3) old style (#121), accepted but complained about
|
||||
cPluginManager.AddHook(Plugin, HOOK_TYPE) -- (4) old style (#121) mangled, accepted but complained about
|
||||
cPluginManager:AddHook(HOOK_TYPE, CallbackFunction) -- (1) recommended
|
||||
cPluginManager.AddHook(HOOK_TYPE, CallbackFunction) -- (2) accepted silently (#401 deprecates this)
|
||||
cPluginManager:Get():AddHook(HOOK_TYPE, CallbackFunction) -- (3) accepted silently
|
||||
cPluginManager:Get():AddHook(Plugin, HOOK_TYPE) -- (4) old style (#121), accepted but complained about in the console
|
||||
cPluginManager.AddHook(Plugin, HOOK_TYPE) -- (5) old style (#121) mangled, accepted but complained about in the console
|
||||
*/
|
||||
|
||||
cLuaState S(tolua_S);
|
||||
cPluginManager * PlgMgr = cPluginManager::Get();
|
||||
|
||||
// If the first param is a cPluginManager, use it instead of the global one:
|
||||
// If the first param is a cPluginManager instance, use it instead of the global one:
|
||||
int ParamIdx = 1;
|
||||
tolua_Error err;
|
||||
if (tolua_isusertype(S, 1, "cPluginManager", 0, &err))
|
||||
@ -1161,6 +1162,12 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S)
|
||||
}
|
||||
ParamIdx += 1;
|
||||
}
|
||||
else if (tolua_isusertable(S, 1, "cPluginManager", 0, &err))
|
||||
{
|
||||
LOGD("AddHook recommended style");
|
||||
// Style 1, use the global PlgMgr, but increment ParamIdx
|
||||
ParamIdx++;
|
||||
}
|
||||
|
||||
if (lua_isnumber(S, ParamIdx) && lua_isfunction(S, ParamIdx + 1))
|
||||
{
|
||||
@ -1177,7 +1184,7 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S)
|
||||
|
||||
AString ParamDesc;
|
||||
Printf(ParamDesc, "%s, %s, %s", S.GetTypeText(1).c_str(), S.GetTypeText(2).c_str(), S.GetTypeText(3).c_str());
|
||||
LOGWARNING("cPluginManager.AddHook(): bad parameters. Expected HOOK_TYPE and CallbackFunction, got %s. Hook not added.", ParamDesc.c_str());
|
||||
LOGWARNING("cPluginManager:AddHook(): bad parameters. Expected HOOK_TYPE and CallbackFunction, got %s. Hook not added.", ParamDesc.c_str());
|
||||
S.LogStackTrace();
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ void cFurnaceEntity::UsedBy(cPlayer * a_Player)
|
||||
if (a_Player->GetWindow() != Window)
|
||||
{
|
||||
a_Player->OpenWindow(Window);
|
||||
BroadcastProgress(PROGRESSBAR_FUEL, m_LastProgressFuel);
|
||||
BroadcastProgress(PROGRESSBAR_SMELTING, m_LastProgressCook);
|
||||
BroadcastProgress(PROGRESSBAR_FUEL, (short)m_LastProgressFuel);
|
||||
BroadcastProgress(PROGRESSBAR_SMELTING, (short)m_LastProgressCook);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -445,14 +445,14 @@ void cFurnaceEntity::UpdateProgressBars(void)
|
||||
int CurFuel = (m_FuelBurnTime > 0) ? (200 - 200 * m_TimeBurned / m_FuelBurnTime) : 0;
|
||||
if ((CurFuel / 8) != (m_LastProgressFuel / 8))
|
||||
{
|
||||
BroadcastProgress(PROGRESSBAR_FUEL, CurFuel);
|
||||
BroadcastProgress(PROGRESSBAR_FUEL, (short)CurFuel);
|
||||
m_LastProgressFuel = CurFuel;
|
||||
}
|
||||
|
||||
int CurCook = (m_NeedCookTime > 0) ? (200 * m_TimeCooked / m_NeedCookTime) : 0;
|
||||
if ((CurCook / 8) != (m_LastProgressCook / 8))
|
||||
{
|
||||
BroadcastProgress(PROGRESSBAR_SMELTING, CurCook);
|
||||
BroadcastProgress(PROGRESSBAR_SMELTING, (short)CurCook);
|
||||
m_LastProgressCook = CurCook;
|
||||
}
|
||||
}
|
||||
|
@ -488,7 +488,6 @@ bool cHopperEntity::MoveItemsToFurnace(cChunk & a_Chunk, int a_BlockX, int a_Blo
|
||||
// Feed the fuel slot of the furnace
|
||||
return MoveItemsToSlot(*Furnace, cFurnaceEntity::fsFuel);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -66,7 +66,7 @@ set(EXECUTABLE MCServer)
|
||||
|
||||
add_executable(${EXECUTABLE} ${SOURCE})
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/MCServer)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
|
||||
|
||||
if (MSVC)
|
||||
# MSVC generator adds a "Debug" or "Release" postfixes to the EXECUTABLE_OUTPUT_PATH, we need to cancel them:
|
||||
|
@ -14,7 +14,21 @@
|
||||
#pragma warning(disable:4481)
|
||||
|
||||
// Disable some warnings that we don't care about:
|
||||
#pragma warning(disable:4100)
|
||||
#pragma warning(disable:4100) // Unreferenced formal parameter
|
||||
|
||||
// Useful warnings from warning level 4:
|
||||
#pragma warning(3 : 4189) // Local variable is initialized but not referenced
|
||||
#pragma warning(3 : 4702) // Unreachable code
|
||||
#pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch
|
||||
#pragma warning(3 : 4389) // Signed/unsigned mismatch
|
||||
#pragma warning(3 : 4701) // Potentially unitialized local variable used
|
||||
#pragma warning(3 : 4310) // Cast truncates constant value
|
||||
#pragma warning(3 : 4505) // Unreferenced local function has been removed
|
||||
#pragma warning(3 : 4127) // Conditional expression is constant
|
||||
#pragma warning(3 : 4706) // Assignment within conditional expression
|
||||
|
||||
// 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places
|
||||
// #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data
|
||||
|
||||
#define OBSOLETE __declspec(deprecated)
|
||||
|
||||
@ -192,7 +206,7 @@ typedef unsigned short UInt16;
|
||||
#ifdef _DEBUG
|
||||
#define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
|
||||
#else
|
||||
#define ASSERT(x) ((void)0)
|
||||
#define ASSERT(x) ((void)(x))
|
||||
#endif
|
||||
|
||||
// Pretty much the same as ASSERT() but stays in Release builds
|
||||
|
@ -57,7 +57,7 @@ void cHTTPConnection::SendNeedAuth(const AString & a_Realm)
|
||||
|
||||
void cHTTPConnection::Send(const cHTTPResponse & a_Response)
|
||||
{
|
||||
ASSERT(m_State = wcsRecvIdle);
|
||||
ASSERT(m_State == wcsRecvIdle);
|
||||
a_Response.AppendToData(m_OutgoingData);
|
||||
m_State = wcsSendingResp;
|
||||
m_HTTPServer.NotifyConnectionWrite(*this);
|
||||
|
@ -133,7 +133,6 @@ bool cHTTPFormParser::HasFormData(const cHTTPRequest & a_Request)
|
||||
(a_Request.GetURL().find('?') != AString::npos)
|
||||
)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -253,7 +253,6 @@ void cNameValueParser::Parse(const char * a_Data, int a_Size)
|
||||
m_State = psValueRaw;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
} // while (i < a_Size)
|
||||
break;
|
||||
} // case psEqual
|
||||
|
@ -246,7 +246,7 @@ void cItems::Delete(int a_Idx)
|
||||
|
||||
|
||||
|
||||
void cItems::Set(int a_Idx, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemDamage)
|
||||
void cItems::Set(int a_Idx, short a_ItemType, char a_ItemCount, short a_ItemDamage)
|
||||
{
|
||||
if ((a_Idx < 0) || (a_Idx >= (int)size()))
|
||||
{
|
||||
|
@ -181,9 +181,9 @@ public:
|
||||
void Delete(int a_Idx);
|
||||
void Clear (void) {clear(); }
|
||||
int Size (void) {return size(); }
|
||||
void Set (int a_Idx, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemDamage);
|
||||
void Set (int a_Idx, short a_ItemType, char a_ItemCount, short a_ItemDamage);
|
||||
|
||||
void Add (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemDamage)
|
||||
void Add (short a_ItemType, char a_ItemCount, short a_ItemDamage)
|
||||
{
|
||||
push_back(cItem(a_ItemType, a_ItemCount, a_ItemDamage));
|
||||
}
|
||||
|
@ -14,9 +14,14 @@ public:
|
||||
void Lock(void);
|
||||
void Unlock(void);
|
||||
|
||||
// IsLocked/IsLockedByCurrentThread are only used in ASSERT statements, but because of the changes with ASSERT they must always be defined
|
||||
// The fake versions (in Release) will not effect the program in any way
|
||||
#ifdef _DEBUG
|
||||
bool IsLocked(void);
|
||||
bool IsLockedByCurrentThread(void);
|
||||
#else
|
||||
bool IsLocked(void) { return false; }
|
||||
bool IsLockedByCurrentThread(void) { return false; }
|
||||
#endif // _DEBUG
|
||||
|
||||
private:
|
||||
|
@ -19,123 +19,139 @@ implements the functions Delete() and Combine(). An example is given in
|
||||
cQueueFuncs and is used as the default behavior.
|
||||
*/
|
||||
|
||||
// this empty struct allows for the callback functions to be inlined
|
||||
/// This empty struct allows for the callback functions to be inlined
|
||||
template<class T>
|
||||
struct cQueueFuncs
|
||||
{
|
||||
public:
|
||||
// Called when an Item is deleted form the queue without being returned
|
||||
static void Delete(T) {};
|
||||
// Called when an Item is inserted with EnqueueItemIfNotPresent and
|
||||
// there is another equal value already inserted
|
||||
static void Combine(T& a_existing, const T& a_new) {};
|
||||
public:
|
||||
|
||||
/// Called when an Item is deleted from the queue without being returned
|
||||
static void Delete(T) {};
|
||||
|
||||
/// Called when an Item is inserted with EnqueueItemIfNotPresent and there is another equal value already inserted
|
||||
static void Combine(T & a_existing, const T & a_new) {};
|
||||
};
|
||||
|
||||
template<class ItemType, class Funcs = cQueueFuncs<ItemType> >
|
||||
|
||||
|
||||
|
||||
|
||||
template <class ItemType, class Funcs = cQueueFuncs<ItemType> >
|
||||
class cQueue
|
||||
{
|
||||
// internal typedef for a List of Items
|
||||
typedef typename std::list<ItemType> ListType;
|
||||
// magic typedef to persuade clang that the iterator is a type
|
||||
typedef typename ListType::iterator iterator;
|
||||
// The actual storage type for the queue
|
||||
typedef typename std::list<ItemType> QueueType;
|
||||
|
||||
// Make iterator an alias for the QueueType's iterator
|
||||
typedef typename QueueType::iterator iterator;
|
||||
|
||||
public:
|
||||
cQueue() {}
|
||||
~cQueue() {}
|
||||
|
||||
// Enqueues an item to the queue, may block if other threads are accessing
|
||||
// the queue.
|
||||
void EnqueueItem(ItemType a_item)
|
||||
|
||||
/// Enqueues an item to the queue, may block if other threads are accessing the queue.
|
||||
void EnqueueItem(ItemType a_Item)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
m_contents.push_back(a_item);
|
||||
m_Contents.push_back(a_Item);
|
||||
m_evtAdded.Set();
|
||||
}
|
||||
|
||||
// Enqueues an item to the queue if not already present as determined with
|
||||
// operator ==. Will block other threads from accessing the queue.
|
||||
void EnqueueItemIfNotPresent(ItemType a_item)
|
||||
|
||||
/// Enqueues an item in the queue if not already present (as determined by operator ==). Blocks other threads from accessing the queue.
|
||||
void EnqueueItemIfNotPresent(ItemType a_Item)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
|
||||
for (iterator itr = m_contents.begin(); itr != m_contents.end(); ++itr)
|
||||
for (iterator itr = m_Contents.begin(); itr != m_Contents.end(); ++itr)
|
||||
{
|
||||
if((*itr) == a_item) {
|
||||
Funcs funcTable;
|
||||
funcTable.Combine(*itr,a_item);
|
||||
if ((*itr) == a_Item)
|
||||
{
|
||||
Funcs::Combine(*itr, a_Item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_contents.push_back(a_item);
|
||||
m_Contents.push_back(a_Item);
|
||||
m_evtAdded.Set();
|
||||
}
|
||||
|
||||
// Dequeues an Item from the queue if any are present. Returns true if
|
||||
// successful. Value of item is undefined if Dequeuing was unsuccessful.
|
||||
bool TryDequeueItem(ItemType& item)
|
||||
|
||||
/// Dequeues an item from the queue if any are present.
|
||||
/// Returns true if successful. Value of item is undefined if dequeuing was unsuccessful.
|
||||
bool TryDequeueItem(ItemType & item)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
if (m_contents.size() == 0)
|
||||
if (m_Contents.size() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
item = m_contents.front();
|
||||
m_contents.pop_front();
|
||||
item = m_Contents.front();
|
||||
m_Contents.pop_front();
|
||||
m_evtRemoved.Set();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Dequeues an Item from the Queue, blocking until an Item is Available.
|
||||
ItemType DequeueItem()
|
||||
|
||||
/// Dequeues an item from the queue, blocking until an item is available.
|
||||
ItemType DequeueItem(void)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
while (m_contents.size() == 0)
|
||||
while (m_Contents.size() == 0)
|
||||
{
|
||||
cCSUnlock Unlock(m_CS);
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_evtAdded.Wait();
|
||||
}
|
||||
ItemType item = m_contents.front();
|
||||
m_contents.pop_front();
|
||||
ItemType item = m_Contents.front();
|
||||
m_Contents.pop_front();
|
||||
m_evtRemoved.Set();
|
||||
return item;
|
||||
}
|
||||
|
||||
// Blocks Until the queue is Empty, Has a slight race condition which may
|
||||
// cause it to miss the queue being empty.
|
||||
void BlockTillEmpty() {
|
||||
// There is a very slight race condition here if the load completes between the check
|
||||
// and the wait.
|
||||
while(!(Size() == 0)){m_evtRemoved.Wait();}
|
||||
}
|
||||
|
||||
// Removes all Items from the Queue, calling Delete on each of them.
|
||||
// can all be inlined when delete is a noop
|
||||
void Clear()
|
||||
/// Blocks until the queue is empty.
|
||||
void BlockTillEmpty(void)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
Funcs funcTable;
|
||||
while (!m_contents.empty())
|
||||
while (!m_Contents.empty())
|
||||
{
|
||||
funcTable.Delete(m_contents.front());
|
||||
m_contents.pop_front();
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_evtRemoved.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the Size at time of being called
|
||||
// Do not use to detirmine weather to call DequeueItem, use TryDequeue instead
|
||||
size_t Size()
|
||||
|
||||
/// Removes all Items from the Queue, calling Delete on each of them.
|
||||
void Clear(void)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
return m_contents.size();
|
||||
while (!m_Contents.empty())
|
||||
{
|
||||
Funcs::Delete(m_Contents.front());
|
||||
m_Contents.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
// Removes an Item from the queue
|
||||
bool Remove(ItemType a_item)
|
||||
|
||||
/// Returns the size at time of being called.
|
||||
/// Do not use to determine whether to call DequeueItem(), use TryDequeueItem() instead
|
||||
size_t Size(void)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
for (iterator itr = m_contents.begin(); itr != m_contents.end(); ++itr)
|
||||
return m_Contents.size();
|
||||
}
|
||||
|
||||
|
||||
/// Removes the item from the queue. If there are multiple such items, only the first one is removed.
|
||||
/// Returns true if the item has been removed, false if no such item found.
|
||||
bool Remove(ItemType a_Item)
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
for (iterator itr = m_Contents.begin(); itr != m_Contents.end(); ++itr)
|
||||
{
|
||||
if((*itr) == a_item) {
|
||||
m_contents.erase(itr);
|
||||
if ((*itr) == a_Item)
|
||||
{
|
||||
m_Contents.erase(itr);
|
||||
m_evtRemoved.Set();
|
||||
return true;
|
||||
}
|
||||
@ -144,8 +160,19 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
ListType m_contents;
|
||||
/// The contents of the queue
|
||||
QueueType m_Contents;
|
||||
|
||||
/// Mutex that protects access to the queue contents
|
||||
cCriticalSection m_CS;
|
||||
|
||||
/// Event that is signalled when an item is added
|
||||
cEvent m_evtAdded;
|
||||
|
||||
/// Event that is signalled when an item is removed (both dequeued or erased)
|
||||
cEvent m_evtRemoved;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "ChunkDataSerializer.h"
|
||||
#include "cryptopp/randpool.h"
|
||||
#include "Protocol132.h"
|
||||
#include "../Root.h"
|
||||
#include "../Server.h"
|
||||
@ -19,8 +18,20 @@
|
||||
#include "../WorldStorage/FastNBT.h"
|
||||
#include "../StringCompression.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4231)
|
||||
#pragma warning(disable:4189)
|
||||
#pragma warning(disable:4702)
|
||||
#endif
|
||||
|
||||
#include "cryptopp/randpool.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#define HANDLE_PACKET_READ(Proc, Type, Var) \
|
||||
@ -866,7 +877,7 @@ void cProtocol132::SendCompass(const cWorld & a_World)
|
||||
void cProtocol132::SendEncryptionKeyRequest(void)
|
||||
{
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte((char)0xfd);
|
||||
WriteByte(0xfd);
|
||||
WriteString(cRoot::Get()->GetServer()->GetServerID());
|
||||
WriteShort((short)m_ServerPublicKey.size());
|
||||
SendData(m_ServerPublicKey.data(), m_ServerPublicKey.size());
|
||||
@ -914,7 +925,7 @@ void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const A
|
||||
{
|
||||
// Send encryption key response:
|
||||
cCSLock Lock(m_CSPacket);
|
||||
WriteByte((char)0xfc);
|
||||
WriteByte(0xfc);
|
||||
WriteShort(0);
|
||||
WriteShort(0);
|
||||
Flush();
|
||||
|
@ -10,9 +10,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "Protocol125.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4231)
|
||||
#pragma warning(disable:4189)
|
||||
#pragma warning(disable:4702)
|
||||
#endif
|
||||
|
||||
#include "cryptopp/modes.h"
|
||||
#include "cryptopp/aes.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -16,7 +16,6 @@ Implements the 1.4.x protocol classes representing these protocols:
|
||||
#include "../Root.h"
|
||||
#include "../Server.h"
|
||||
#include "../ClientHandle.h"
|
||||
#include "cryptopp/randpool.h"
|
||||
#include "../Item.h"
|
||||
#include "ChunkDataSerializer.h"
|
||||
#include "../Entities/Player.h"
|
||||
@ -25,8 +24,20 @@ Implements the 1.4.x protocol classes representing these protocols:
|
||||
#include "../Entities/Pickup.h"
|
||||
#include "../Entities/FallingBlock.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4231)
|
||||
#pragma warning(disable:4189)
|
||||
#pragma warning(disable:4702)
|
||||
#endif
|
||||
|
||||
#include "cryptopp/randpool.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#define HANDLE_PACKET_READ(Proc, Type, Var) \
|
||||
|
@ -112,7 +112,7 @@ int cProtocol150::ParseWindowClick(void)
|
||||
}
|
||||
|
||||
// Convert Button, Mode, SlotNum and HeldItem into eClickAction:
|
||||
eClickAction Action;
|
||||
eClickAction Action = caUnknown;
|
||||
switch ((Mode << 8) | Button)
|
||||
{
|
||||
case 0x0000: Action = (SlotNum != -999) ? caLeftClick : caLeftClickOutside; break;
|
||||
|
@ -986,7 +986,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
|
||||
while (true)
|
||||
{
|
||||
UInt32 PacketLen;
|
||||
int PacketStart = m_ReceivedData.GetDataStart();
|
||||
if (!m_ReceivedData.ReadVarInt(PacketLen))
|
||||
{
|
||||
// Not enough data
|
||||
|
@ -16,9 +16,23 @@ Declares the 1.7.x protocol classes:
|
||||
|
||||
#include "Protocol.h"
|
||||
#include "../ByteBuffer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4231)
|
||||
#pragma warning(disable:4189)
|
||||
#pragma warning(disable:4702)
|
||||
#endif
|
||||
|
||||
#include "cryptopp/modes.h"
|
||||
#include "cryptopp/aes.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -198,7 +198,7 @@ void cProtocolRecognizer::SendDisconnect(const AString & a_Reason)
|
||||
else
|
||||
{
|
||||
// This is used when the client sends a server-ping, respond with the default packet:
|
||||
WriteByte ((char)0xff); // PACKET_DISCONNECT
|
||||
WriteByte (0xff); // PACKET_DISCONNECT
|
||||
WriteString(a_Reason);
|
||||
}
|
||||
}
|
||||
|
17
src/Server.h
17
src/Server.h
@ -11,9 +11,24 @@
|
||||
|
||||
#include "OSSupport/SocketThreads.h"
|
||||
#include "OSSupport/ListenThread.h"
|
||||
|
||||
#include "RCONServer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4231)
|
||||
#pragma warning(disable:4189)
|
||||
#pragma warning(disable:4702)
|
||||
#endif
|
||||
|
||||
#include "cryptopp/rsa.h"
|
||||
#include "cryptopp/randpool.h"
|
||||
#include "RCONServer.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -765,6 +765,54 @@ AString Base64Decode(const AString & a_Base64String)
|
||||
|
||||
|
||||
|
||||
AString Base64Encode(const AString & a_Input)
|
||||
{
|
||||
static const char BASE64[64] = {
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
||||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
||||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
|
||||
};
|
||||
|
||||
std::string output;
|
||||
output.resize(((a_Input.size() + 2) / 3) * 4);
|
||||
|
||||
size_t output_index = 0;
|
||||
size_t size_full24 = (a_Input.size() / 3) * 3;
|
||||
|
||||
for (size_t i = 0; i < size_full24; i += 3)
|
||||
{
|
||||
output[output_index++] = BASE64[(unsigned char)a_Input[i] >> 2];
|
||||
output[output_index++] = BASE64[((unsigned char)a_Input[i] << 4 | (unsigned char)a_Input[i + 1] >> 4) & 63];
|
||||
output[output_index++] = BASE64[((unsigned char)a_Input[i + 1] << 2 | (unsigned char)a_Input[i + 2] >> 6) & 63];
|
||||
output[output_index++] = BASE64[(unsigned char)a_Input[i + 2] & 63];
|
||||
}
|
||||
|
||||
if (size_full24 < a_Input.size())
|
||||
{
|
||||
output[output_index++] = BASE64[(unsigned char)a_Input[size_full24] >> 2];
|
||||
if (size_full24 + 1 == a_Input.size())
|
||||
{
|
||||
output[output_index++] = BASE64[((unsigned char)a_Input[size_full24] << 4) & 63];
|
||||
output[output_index++] = '=';
|
||||
}
|
||||
else
|
||||
{
|
||||
output[output_index++] = BASE64[((unsigned char)a_Input[size_full24] << 4 | (unsigned char)a_Input[size_full24 + 1] >> 4) & 63];
|
||||
output[output_index++] = BASE64[((unsigned char)a_Input[size_full24 + 1] << 2) & 63];
|
||||
}
|
||||
|
||||
output[output_index++] = '=';
|
||||
}
|
||||
assert(output_index == output.size());
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
short GetBEShort(const char * a_Mem)
|
||||
{
|
||||
return (((short)a_Mem[0]) << 8) | a_Mem[1];
|
||||
|
@ -81,6 +81,9 @@ extern AString ReplaceAllCharOccurrences(const AString & a_String, char a_From,
|
||||
/// Decodes a Base64-encoded string into the raw data
|
||||
extern AString Base64Decode(const AString & a_Base64String);
|
||||
|
||||
/// Encodes a string into Base64
|
||||
extern AString Base64Encode(const AString & a_Input);
|
||||
|
||||
/// Reads two bytes from the specified memory location and interprets them as BigEndian short
|
||||
extern short GetBEShort(const char * a_Mem);
|
||||
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
// Broadcast respective packets to all clients of the chunk where the event is taking place
|
||||
// (Please keep these alpha-sorted)
|
||||
void BroadcastAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle);
|
||||
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL); // tolua_export
|
||||
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude
|
||||
void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_export
|
||||
|
@ -117,6 +117,10 @@ void cWorldStorage::WaitForLoadQueueEmpty(void)
|
||||
m_LoadQueue.BlockTillEmpty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorldStorage::WaitForSaveQueueEmpty(void)
|
||||
{
|
||||
m_SaveQueue.BlockTillEmpty();
|
||||
@ -124,6 +128,8 @@ void cWorldStorage::WaitForSaveQueueEmpty(void)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
size_t cWorldStorage::GetLoadQueueLength(void)
|
||||
{
|
||||
return m_LoadQueue.Size();
|
||||
@ -144,8 +150,8 @@ size_t cWorldStorage::GetSaveQueueLength(void)
|
||||
|
||||
void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate)
|
||||
{
|
||||
m_Event.Set();
|
||||
m_LoadQueue.EnqueueItemIfNotPresent(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ, a_Generate));
|
||||
m_Event.Set();
|
||||
}
|
||||
|
||||
|
||||
@ -154,8 +160,8 @@ void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, boo
|
||||
|
||||
void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
|
||||
{
|
||||
m_Event.Set();
|
||||
m_SaveQueue.EnqueueItemIfNotPresent(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
|
||||
m_Event.Set();
|
||||
}
|
||||
|
||||
|
||||
@ -166,6 +172,7 @@ void cWorldStorage::QueueSavedMessage(void)
|
||||
{
|
||||
// Pushes a special coord pair into the queue, signalizing a message instead
|
||||
m_SaveQueue.EnqueueItem(cChunkCoords(0, CHUNK_Y_MESSAGE, 0));
|
||||
m_Event.Set();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user