Merge remote-tracking branch 'origin/master' into playerimprovements
Conflicts: src/Root.cpp src/Root.h src/World.cpp
This commit is contained in:
commit
9d1c9097e3
@ -3,7 +3,7 @@ compiler:
|
||||
- gcc
|
||||
- clang
|
||||
# Build MCServer
|
||||
script: cmake . -DCMAKE_BUILD_TYPE=RELEASE && make -j 2
|
||||
script: cmake . -DCMAKE_BUILD_TYPE=RELEASE -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | ./MCServer)
|
||||
|
||||
# Notification Settings
|
||||
notifications:
|
||||
|
@ -60,6 +60,9 @@ else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
||||
endif()
|
||||
|
||||
# We use a signed char (fixes #640 on RasPi)
|
||||
add_flags_cxx("-fsigned-char")
|
||||
endif()
|
||||
|
||||
|
||||
@ -121,6 +124,10 @@ endif()
|
||||
# The Expat library is linked in statically, make the source files aware of that:
|
||||
add_definitions(-DXML_STATIC)
|
||||
|
||||
# Self Test Mode enables extra checks at startup
|
||||
if(${SELF_TEST})
|
||||
add_definitions(-DSELF_TEST)
|
||||
endif()
|
||||
|
||||
# Declare the flags used for profiling builds:
|
||||
if (MSVC)
|
||||
|
2
MCServer/Plugins/.gitignore
vendored
Normal file
2
MCServer/Plugins/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.txt
|
||||
*.md
|
@ -1748,10 +1748,11 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
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." },
|
||||
GetNumPlugins = { Params = "", Return = "number", Notes = "Returns the number of plugins, including the disabled ones" },
|
||||
GetPlugin = { Params = "PluginName", Return = "{{cPlugin}}", Notes = "Returns a plugin handle of the specified plugin" },
|
||||
GetPlugin = { Params = "PluginName", Return = "{{cPlugin}}", Notes = "(<b>DEPRECATED, UNSAFE</b>) Returns a plugin handle of the specified plugin, or nil if such plugin is not loaded. Note thatdue to multithreading the handle is not guaranteed to be safe for use when stored - a single-plugin reload may have been triggered in the mean time for the requested plugin." },
|
||||
IsCommandBound = { Params = "Command", Return = "bool", Notes = "Returns true if in-game Command is already bound (by any plugin)" },
|
||||
IsConsoleCommandBound = { Params = "Command", Return = "bool", Notes = "Returns true if console Command is already bound (by any plugin)" },
|
||||
LoadPlugin = { Params = "PluginFolder", Return = "", Notes = "(<b>DEPRECATED</b>) Loads a plugin from the specified folder. NOTE: Loading plugins may be an unsafe operation and may result in a deadlock or a crash. This API is deprecated and might be removed." },
|
||||
LogStackTrace = { Params = "", Return = "", Notes = "(STATIC) Logs a current stack trace of the Lua engine to the server console log. Same format as is used when the plugin fails." },
|
||||
ReloadPlugins = { Params = "", Return = "", Notes = "Reloads all active plugins" },
|
||||
},
|
||||
Constants =
|
||||
|
@ -69,6 +69,47 @@ end
|
||||
|
||||
|
||||
|
||||
--- Replaces generic formatting with forum-specific formatting
|
||||
-- Also removes the single line-ends
|
||||
local function GithubizeString(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}", "**"):gsub("{%%/b}", "**");
|
||||
a_Str = a_Str:gsub("{%%i}", "*"):gsub("{%%/i}", "*");
|
||||
a_Str = a_Str:gsub("{%%list}", ""):gsub("{%%/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:
|
||||
@ -156,6 +197,28 @@ end
|
||||
|
||||
|
||||
|
||||
--- Returns a string specifying the command.
|
||||
-- If a_CommandParams is nil, returns a_CommandName apostrophed
|
||||
-- If a_CommandParams is a string, apostrophes a_CommandName with a_CommandParams
|
||||
local function GetCommandRefGithub(a_CommandName, a_CommandParams)
|
||||
assert(type(a_CommandName) == "string");
|
||||
if (a_CommandParams == nil) then
|
||||
return "`" .. a_CommandName .. "`";
|
||||
end
|
||||
|
||||
assert(type(a_CommandParams) == "table");
|
||||
if ((a_CommandParams.Params == nil) or (a_CommandParams.Params == "")) then
|
||||
return "`" .. a_CommandName .. "`";
|
||||
end
|
||||
|
||||
assert(type(a_CommandParams.Params) == "string");
|
||||
return "`" .. a_CommandName .. " " .. a_CommandParams.Params .. "`";
|
||||
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");
|
||||
@ -184,6 +247,34 @@ end
|
||||
|
||||
|
||||
|
||||
--- Writes the specified command detailed help array to the output file, in the forum dump format
|
||||
local function WriteCommandParameterCombinationsGithub(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\n");
|
||||
for idx, combination in ipairs(a_ParameterCombinations) do
|
||||
f:write(GetCommandRefGithub(a_CmdString, combination));
|
||||
if (combination.Help ~= nil) then
|
||||
f:write(" - ", GithubizeString(combination.Help));
|
||||
end
|
||||
if (combination.Permission ~= nil) then
|
||||
f:write(" (Requires permission '**", combination.Permission, "**')");
|
||||
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:
|
||||
@ -206,7 +297,7 @@ local function WriteCommandsCategoryForum(a_Category, f)
|
||||
f:write("Permission required: [color=red]", cmd.Info.Permission, "[/color]\n");
|
||||
end
|
||||
if (cmd.Info.DetailedDescription ~= nil) then
|
||||
f:write(cmd.Info.DetailedDescription);
|
||||
f:write(ForumizeString(cmd.Info.DetailedDescription));
|
||||
end
|
||||
if (cmd.Info.ParameterCombinations ~= nil) then
|
||||
WriteCommandParameterCombinationsForum(cmd.CommandString, cmd.Info.ParameterCombinations, f);
|
||||
@ -219,6 +310,41 @@ end
|
||||
|
||||
|
||||
|
||||
--- Writes all commands in the specified category to the output file, in the Github dump format
|
||||
local function WriteCommandsCategoryGithub(a_Category, f)
|
||||
-- Write category name:
|
||||
local CategoryName = a_Category.Name;
|
||||
if (CategoryName == "") then
|
||||
CategoryName = "General";
|
||||
end
|
||||
f:write("\n## ", GithubizeString(a_Category.DisplayName or CategoryName), "\n");
|
||||
|
||||
-- Write description:
|
||||
if (a_Category.Description ~= "") then
|
||||
f:write(GithubizeString(a_Category.Description), "\n");
|
||||
end
|
||||
|
||||
-- Write commands:
|
||||
f:write("\n");
|
||||
for idx2, cmd in ipairs(a_Category.Commands) do
|
||||
f:write("\n### ", cmd.CommandString, "\n", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n\n");
|
||||
if (cmd.Info.Permission ~= nil) then
|
||||
f:write("Permission required: **", cmd.Info.Permission, "**\n\n");
|
||||
end
|
||||
if (cmd.Info.DetailedDescription ~= nil) then
|
||||
f:write(GithubizeString(cmd.Info.DetailedDescription));
|
||||
end
|
||||
if (cmd.Info.ParameterCombinations ~= nil) then
|
||||
WriteCommandParameterCombinationsGithub(cmd.CommandString, cmd.Info.ParameterCombinations, f);
|
||||
end
|
||||
end
|
||||
f:write("\n\n")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function DumpCommandsForum(a_PluginInfo, f)
|
||||
-- Copy all Categories from a dictionary into an array:
|
||||
local Categories = BuildCategories(a_PluginInfo);
|
||||
@ -246,9 +372,36 @@ end
|
||||
|
||||
|
||||
|
||||
local function DumpCommandsGithub(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# Commands\n");
|
||||
|
||||
-- Dump per-category commands:
|
||||
for idx, cat in ipairs(Categories) do
|
||||
WriteCommandsCategoryGithub(cat, f);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function DumpAdditionalInfoForum(a_PluginInfo, f)
|
||||
local AInfo = a_PluginInfo.AdditionalInfo;
|
||||
if ((AInfo == nil) or (type(AInfo) ~= "table")) then
|
||||
if (type(AInfo) ~= "table") then
|
||||
-- There is no AdditionalInfo in a_PluginInfo
|
||||
return;
|
||||
end
|
||||
@ -265,6 +418,25 @@ end
|
||||
|
||||
|
||||
|
||||
local function DumpAdditionalInfoGithub(a_PluginInfo, f)
|
||||
local AInfo = a_PluginInfo.AdditionalInfo;
|
||||
if (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# ", GithubizeString(info.Title), "\n");
|
||||
f:write(GithubizeString(info.Contents), "\n");
|
||||
end
|
||||
end
|
||||
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)
|
||||
@ -333,7 +505,7 @@ local function DumpPermissionsForum(a_PluginInfo, f)
|
||||
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 "");
|
||||
f:write(ForumizeString(perm.Info.Description or ""));
|
||||
local CommandsAffected = perm.Info.CommandsAffected or {};
|
||||
if (#CommandsAffected > 0) then
|
||||
f:write("\n[list] Commands affected:\n- ");
|
||||
@ -356,6 +528,43 @@ end
|
||||
|
||||
|
||||
|
||||
local function DumpPermissionsGithub(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# Permissions\n");
|
||||
for idx, perm in ipairs(Permissions) do
|
||||
f:write("### ", perm.Name, "\n");
|
||||
f:write(GithubizeString(perm.Info.Description or ""));
|
||||
local CommandsAffected = perm.Info.CommandsAffected or {};
|
||||
if (#CommandsAffected > 0) then
|
||||
f:write("\n\nCommands affected:\n - ");
|
||||
local Affects = {};
|
||||
for idx2, cmd in ipairs(CommandsAffected) do
|
||||
if (type(cmd) == "string") then
|
||||
table.insert(Affects, GetCommandRefGithub(cmd));
|
||||
else
|
||||
table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd));
|
||||
end
|
||||
end
|
||||
f:write(table.concat(Affects, "\n - "));
|
||||
f:write("\n");
|
||||
end
|
||||
if (perm.Info.RecommendedGroups ~= nil) then
|
||||
f:write("\n\nRecommended groups: ", perm.Info.RecommendedGroups, "\n");
|
||||
end
|
||||
f:write("\n");
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo)
|
||||
-- Open the output file:
|
||||
local f, msg = io.open(a_PluginInfo.Name .. "_forum.txt", "w");
|
||||
@ -377,8 +586,21 @@ end
|
||||
|
||||
|
||||
|
||||
local function DumpPluginInfoGitHub()
|
||||
-- TODO
|
||||
local function DumpPluginInfoGithub(a_PluginFolder, a_PluginInfo)
|
||||
-- Open the output file:
|
||||
local f, msg = io.open(a_PluginInfo.Name .. ".md", "w"); -- TODO: Save to a_PluginFolder .. "/Readme.md" instead
|
||||
if (f == nil) then
|
||||
print("\tCannot dump github info for plugin " .. a_PluginFolder .. ": " .. msg);
|
||||
return;
|
||||
end
|
||||
|
||||
-- Write the description:
|
||||
f:write(GithubizeString(a_PluginInfo.Description), "\n");
|
||||
DumpAdditionalInfoGithub(a_PluginInfo, f);
|
||||
DumpCommandsGithub(a_PluginInfo, f);
|
||||
DumpPermissionsGithub(a_PluginInfo, f);
|
||||
|
||||
f:close();
|
||||
end
|
||||
|
||||
|
||||
@ -418,6 +640,7 @@ local function ProcessPluginFolder(a_FolderName)
|
||||
return;
|
||||
end
|
||||
DumpPluginInfoForum(a_FolderName, PluginInfo);
|
||||
DumpPluginInfoGithub(a_FolderName, PluginInfo);
|
||||
end
|
||||
|
||||
|
||||
|
@ -906,8 +906,12 @@ static int tolua_cWorld_TryGetHeight(lua_State * tolua_S)
|
||||
{
|
||||
int Height = 0;
|
||||
bool res = self->TryGetHeight(BlockX, BlockZ, Height);
|
||||
tolua_pushnumber(tolua_S, Height);
|
||||
tolua_pushboolean(tolua_S, res ? 1 : 0);
|
||||
if (res)
|
||||
{
|
||||
tolua_pushnumber(tolua_S, Height);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -1106,6 +1110,16 @@ static int tolua_cPluginManager_GetCurrentPlugin(lua_State * S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPluginManager_LogStackTrace(lua_State * S)
|
||||
{
|
||||
cLuaState::LogStackTrace(S);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, cLuaState & S, int a_ParamIdx)
|
||||
{
|
||||
// Helper function for cPluginmanager:AddHook() binding
|
||||
@ -2386,6 +2400,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "ForEachConsoleCommand", tolua_cPluginManager_ForEachConsoleCommand);
|
||||
tolua_function(tolua_S, "GetAllPlugins", tolua_cPluginManager_GetAllPlugins);
|
||||
tolua_function(tolua_S, "GetCurrentPlugin", tolua_cPluginManager_GetCurrentPlugin);
|
||||
tolua_function(tolua_S, "LogStackTrace", tolua_cPluginManager_LogStackTrace);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cPlayer");
|
||||
|
@ -380,7 +380,7 @@ AString DamageTypeToString(eDamageType a_DamageType)
|
||||
case dtRangedAttack: return "dtRangedAttack";
|
||||
case dtStarving: return "dtStarving";
|
||||
case dtSuffocating: return "dtSuffocation";
|
||||
|
||||
case dtExplosion: return "dtExplosion";
|
||||
}
|
||||
|
||||
// Unknown damage type:
|
||||
@ -426,6 +426,7 @@ eDamageType StringToDamageType(const AString & a_DamageTypeString)
|
||||
{ dtInVoid, "dtInVoid"},
|
||||
{ dtPotionOfHarming, "dtPotionOfHarming"},
|
||||
{ dtAdmin, "dtAdmin"},
|
||||
{ dtExplosion, "dtExplosion"},
|
||||
|
||||
// Common synonyms:
|
||||
{ dtAttack, "dtPawnAttack"},
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
// BoundingBox.cpp
|
||||
|
||||
// Implements the cBoundingBox class representing an axis-aligned bounding box with floatingpoint coords
|
||||
@ -11,7 +10,7 @@
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
#if SELF_TEST
|
||||
|
||||
/// A simple self-test that is executed on program start, used to verify bbox functionality
|
||||
class SelfTest
|
||||
@ -30,20 +29,39 @@ public:
|
||||
Vector3d(1.999, 0, 1.5), Vector3d(1.999, 4, 1.5), // Should intersect at 0.25, face 0 (YM)
|
||||
Vector3d(2.001, 0, 1.5), Vector3d(2.001, 4, 1.5), // Should not intersect
|
||||
} ;
|
||||
bool Results[] = {true,true,true,false,true,false};
|
||||
double LineCoeffs[] = {2,0.25,0.5,0,0.25,0};
|
||||
|
||||
for (size_t i = 0; i < ARRAYCOUNT(LineDefs) / 2; i++)
|
||||
{
|
||||
double LineCoeff;
|
||||
char Face;
|
||||
eBlockFace Face;
|
||||
Vector3d Line1 = LineDefs[2 * i];
|
||||
Vector3d Line2 = LineDefs[2 * i + 1];
|
||||
bool res = cBoundingBox::CalcLineIntersection(Min, Max, Line1, Line2, LineCoeff, Face);
|
||||
printf("LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d\n",
|
||||
Line1.x, Line1.y, Line1.z,
|
||||
Line2.x, Line2.y, Line2.z,
|
||||
res ? 1 : 0, LineCoeff, Face
|
||||
);
|
||||
if (res != Results[i])
|
||||
{
|
||||
fprintf(stderr,"LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d\n",
|
||||
Line1.x, Line1.y, Line1.z,
|
||||
Line2.x, Line2.y, Line2.z,
|
||||
res ? 1 : 0, LineCoeff, Face
|
||||
);
|
||||
abort();
|
||||
}
|
||||
if (res)
|
||||
{
|
||||
if (LineCoeff != LineCoeffs[i])
|
||||
{
|
||||
fprintf(stderr,"LineIntersection({%.02f, %.02f, %.02f}, {%.02f, %.02f, %.02f}) -> %d, %.05f, %d\n",
|
||||
Line1.x, Line1.y, Line1.z,
|
||||
Line2.x, Line2.y, Line2.z,
|
||||
res ? 1 : 0, LineCoeff, Face
|
||||
);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
} // for i - LineDefs[]
|
||||
printf("BoundingBox selftest complete.");
|
||||
fprintf(stderr,"BoundingBox selftest complete.");
|
||||
}
|
||||
} Test;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "Simulator/FireSimulator.h"
|
||||
#include "Simulator/SandSimulator.h"
|
||||
#include "Simulator/RedstoneSimulator.h"
|
||||
#include "Simulator/IncrementalRedstoneSimulator.h"
|
||||
|
||||
|
||||
|
||||
|
@ -308,8 +308,8 @@ void cPublicKey::InitRnd(void)
|
||||
// cAESCFBDecryptor:
|
||||
|
||||
cAESCFBDecryptor::cAESCFBDecryptor(void) :
|
||||
m_IsValid(false),
|
||||
m_IVOffset(0)
|
||||
m_IVOffset(0),
|
||||
m_IsValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -366,8 +366,8 @@ void cAESCFBDecryptor::ProcessData(Byte * a_DecryptedOut, const Byte * a_Encrypt
|
||||
// cAESCFBEncryptor:
|
||||
|
||||
cAESCFBEncryptor::cAESCFBEncryptor(void) :
|
||||
m_IsValid(false),
|
||||
m_IVOffset(0)
|
||||
m_IVOffset(0),
|
||||
m_IsValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -132,8 +132,6 @@ protected:
|
||||
class cAESCFBEncryptor
|
||||
{
|
||||
public:
|
||||
Byte test;
|
||||
|
||||
cAESCFBEncryptor(void);
|
||||
~cAESCFBEncryptor();
|
||||
|
||||
|
@ -50,6 +50,8 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
|
||||
, m_TicksSinceLastFireDamage(0)
|
||||
, m_TicksLeftBurning(0)
|
||||
, m_TicksSinceLastVoidDamage(0)
|
||||
, m_IsSwimming(false)
|
||||
, m_IsSubmerged(false)
|
||||
, m_HeadYaw( 0.0 )
|
||||
, m_Rot(0.0, 0.0, 0.0)
|
||||
, m_Pos(a_X, a_Y, a_Z)
|
||||
@ -57,8 +59,6 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
|
||||
, m_Mass (0.001) // Default 1g
|
||||
, m_Width(a_Width)
|
||||
, m_Height(a_Height)
|
||||
, m_IsSubmerged(false)
|
||||
, m_IsSwimming(false)
|
||||
{
|
||||
cCSLock Lock(m_CSCount);
|
||||
m_EntityCount++;
|
||||
|
@ -103,10 +103,10 @@ protected:
|
||||
|
||||
cFloater::cFloater(double a_X, double a_Y, double a_Z, Vector3d a_Speed, int a_PlayerID, int a_CountDownTime) :
|
||||
cEntity(etFloater, a_X, a_Y, a_Z, 0.2, 0.2),
|
||||
m_PickupCountDown(0),
|
||||
m_PlayerID(a_PlayerID),
|
||||
m_CanPickupItem(false),
|
||||
m_PickupCountDown(0),
|
||||
m_CountDownTime(a_CountDownTime),
|
||||
m_PlayerID(a_PlayerID),
|
||||
m_AttachedMobID(-1)
|
||||
{
|
||||
SetSpeed(a_Speed);
|
||||
|
@ -24,11 +24,11 @@ class cMinecartCollisionCallback :
|
||||
{
|
||||
public:
|
||||
cMinecartCollisionCallback(Vector3d a_Pos, double a_Height, double a_Width, int a_UniqueID, int a_AttacheeUniqueID) :
|
||||
m_DoesInteserct(false),
|
||||
m_CollidedEntityPos(0, 0, 0),
|
||||
m_Pos(a_Pos),
|
||||
m_Height(a_Height),
|
||||
m_Width(a_Width),
|
||||
m_DoesInteserct(false),
|
||||
m_CollidedEntityPos(0, 0, 0),
|
||||
m_UniqueID(a_UniqueID),
|
||||
m_AttacheeUniqueID(a_AttacheeUniqueID)
|
||||
{
|
||||
@ -1057,8 +1057,8 @@ void cMinecartWithChest::OnRightClicked(cPlayer & a_Player)
|
||||
|
||||
cMinecartWithFurnace::cMinecartWithFurnace(double a_X, double a_Y, double a_Z) :
|
||||
super(mpFurnace, a_X, a_Y, a_Z),
|
||||
m_IsFueled(false),
|
||||
m_FueledTimeLeft(-1)
|
||||
m_FueledTimeLeft(-1),
|
||||
m_IsFueled(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1137,4 +1137,4 @@ cMinecartWithHopper::cMinecartWithHopper(double a_X, double a_Y, double a_Z) :
|
||||
}
|
||||
|
||||
// TODO: Make it suck up blocks and travel further than any other cart and physics and put and take blocks
|
||||
// AND AVARYTHING!!
|
||||
// AND AVARYTHING!!
|
||||
|
@ -22,9 +22,9 @@ class cPickupCombiningCallback :
|
||||
{
|
||||
public:
|
||||
cPickupCombiningCallback(Vector3d a_Position, cPickup * a_Pickup) :
|
||||
m_FoundMatchingPickup(false),
|
||||
m_Position(a_Position),
|
||||
m_Pickup(a_Pickup),
|
||||
m_FoundMatchingPickup(false)
|
||||
m_Pickup(a_Pickup)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1261,19 +1261,6 @@ void cPlayer::RemoveFromGroup( const AString & a_GroupName )
|
||||
|
||||
|
||||
|
||||
bool cPlayer::CanUseCommand( const AString & a_Command )
|
||||
{
|
||||
for( GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr )
|
||||
{
|
||||
if( (*itr)->HasCommand( a_Command ) ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPlayer::HasPermission(const AString & a_Permission)
|
||||
{
|
||||
if (a_Permission.empty())
|
||||
|
@ -218,7 +218,6 @@ public:
|
||||
/// Removes a player from the group, resolves permissions and group inheritance (case sensitive)
|
||||
void RemoveFromGroup( const AString & a_GroupName ); // tolua_export
|
||||
|
||||
bool CanUseCommand( const AString & a_Command ); // tolua_export
|
||||
bool HasPermission( const AString & a_Permission ); // tolua_export
|
||||
const GroupList & GetGroups() { return m_Groups; } // >> EXPORTED IN MANUALBINDINGS <<
|
||||
StringList GetResolvedPermissions(); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
@ -3,35 +3,39 @@
|
||||
|
||||
#include "Group.h"
|
||||
|
||||
void cGroup::AddCommand( std::string a_Command )
|
||||
|
||||
|
||||
|
||||
|
||||
void cGroup::AddCommand( AString a_Command )
|
||||
{
|
||||
m_Commands[ a_Command ] = true;
|
||||
}
|
||||
|
||||
void cGroup::AddPermission( std::string a_Permission )
|
||||
|
||||
|
||||
|
||||
|
||||
void cGroup::AddPermission( AString a_Permission )
|
||||
{
|
||||
m_Permissions[ a_Permission ] = true;
|
||||
}
|
||||
|
||||
bool cGroup::HasCommand( std::string a_Command )
|
||||
{
|
||||
if( m_Commands.find("*") != m_Commands.end() ) return true;
|
||||
|
||||
CommandMap::iterator itr = m_Commands.find( a_Command );
|
||||
if( itr != m_Commands.end() )
|
||||
{
|
||||
if( itr->second ) return true;
|
||||
}
|
||||
|
||||
for( GroupList::iterator itr = m_Inherits.begin(); itr != m_Inherits.end(); ++itr )
|
||||
{
|
||||
if( (*itr)->HasCommand( a_Command ) ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void cGroup::InheritFrom( cGroup* a_Group )
|
||||
{
|
||||
m_Inherits.remove( a_Group );
|
||||
m_Inherits.push_back( a_Group );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cGroup::ClearPermission()
|
||||
{
|
||||
m_Permissions.clear();
|
||||
}
|
24
src/Group.h
24
src/Group.h
@ -11,19 +11,19 @@ public: // tolua_export
|
||||
cGroup() {}
|
||||
~cGroup() {}
|
||||
|
||||
void SetName( std::string a_Name ) { m_Name = a_Name; } // tolua_export
|
||||
const std::string & GetName() const { return m_Name; } // tolua_export
|
||||
void SetColor( std::string a_Color ) { m_Color = a_Color; } // tolua_export
|
||||
void AddCommand( std::string a_Command ); // tolua_export
|
||||
void AddPermission( std::string a_Permission ); // tolua_export
|
||||
void InheritFrom( cGroup* a_Group ); // tolua_export
|
||||
void SetName( AString a_Name ) { m_Name = a_Name; } // tolua_export
|
||||
const AString & GetName() const { return m_Name; } // tolua_export
|
||||
void SetColor( AString a_Color ) { m_Color = a_Color; } // tolua_export
|
||||
void AddCommand( AString a_Command ); // tolua_export
|
||||
void AddPermission( AString a_Permission ); // tolua_export
|
||||
void InheritFrom( cGroup* a_Group ); // tolua_export
|
||||
|
||||
bool HasCommand( std::string a_Command ); // tolua_export
|
||||
|
||||
typedef std::map< std::string, bool > PermissionMap;
|
||||
typedef std::map< AString, bool > PermissionMap;
|
||||
const PermissionMap & GetPermissions() const { return m_Permissions; }
|
||||
|
||||
typedef std::map< std::string, bool > CommandMap;
|
||||
void ClearPermission(void);
|
||||
|
||||
typedef std::map< AString, bool > CommandMap;
|
||||
const CommandMap & GetCommands() const { return m_Commands; }
|
||||
|
||||
const AString & GetColor() const { return m_Color; } // tolua_export
|
||||
@ -31,8 +31,8 @@ public: // tolua_export
|
||||
typedef std::list< cGroup* > GroupList;
|
||||
const GroupList & GetInherits() const { return m_Inherits; }
|
||||
private:
|
||||
std::string m_Name;
|
||||
std::string m_Color;
|
||||
AString m_Name;
|
||||
AString m_Color;
|
||||
|
||||
PermissionMap m_Permissions;
|
||||
CommandMap m_Commands;
|
||||
|
@ -44,6 +44,18 @@ cGroupManager::cGroupManager()
|
||||
: m_pState( new sGroupManagerState )
|
||||
{
|
||||
LOGD("-- Loading Groups --");
|
||||
|
||||
LoadGroups();
|
||||
|
||||
LOGD("-- Groups Successfully Loaded --");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cGroupManager::LoadGroups()
|
||||
{
|
||||
cIniFile IniFile;
|
||||
if (!IniFile.ReadFile("groups.ini"))
|
||||
{
|
||||
@ -71,8 +83,10 @@ cGroupManager::cGroupManager()
|
||||
unsigned int NumKeys = IniFile.GetNumKeys();
|
||||
for (size_t i = 0; i < NumKeys; i++)
|
||||
{
|
||||
std::string KeyName = IniFile.GetKeyName( i );
|
||||
AString KeyName = IniFile.GetKeyName( i );
|
||||
cGroup* Group = GetGroup( KeyName.c_str() );
|
||||
|
||||
Group->ClearPermission(); // Needed in case the groups are reloaded.
|
||||
|
||||
LOGD("Loading group: %s", KeyName.c_str() );
|
||||
|
||||
@ -107,7 +121,7 @@ cGroupManager::cGroupManager()
|
||||
}
|
||||
}
|
||||
|
||||
std::string Groups = IniFile.GetValue(KeyName, "Inherits", "");
|
||||
AString Groups = IniFile.GetValue(KeyName, "Inherits", "");
|
||||
if (!Groups.empty())
|
||||
{
|
||||
AStringVector Split = StringSplitAndTrim(Groups, ",");
|
||||
@ -117,7 +131,6 @@ cGroupManager::cGroupManager()
|
||||
}
|
||||
}
|
||||
}
|
||||
LOGD("-- Groups Successfully Loaded --");
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,6 +15,7 @@ class cGroupManager
|
||||
{
|
||||
public:
|
||||
cGroup * GetGroup(const AString & a_Name);
|
||||
void LoadGroups(void);
|
||||
|
||||
private:
|
||||
friend class cRoot;
|
||||
|
@ -55,9 +55,9 @@ public:
|
||||
m_ItemType (a_ItemType),
|
||||
m_ItemCount (a_ItemCount),
|
||||
m_ItemDamage (a_ItemDamage),
|
||||
m_Enchantments(a_Enchantments),
|
||||
m_CustomName (a_CustomName),
|
||||
m_Lore (a_Lore)
|
||||
m_Lore (a_Lore),
|
||||
m_Enchantments(a_Enchantments)
|
||||
{
|
||||
if (!IsValidItem(m_ItemType))
|
||||
{
|
||||
@ -75,9 +75,9 @@ public:
|
||||
m_ItemType (a_CopyFrom.m_ItemType),
|
||||
m_ItemCount (a_CopyFrom.m_ItemCount),
|
||||
m_ItemDamage (a_CopyFrom.m_ItemDamage),
|
||||
m_Enchantments(a_CopyFrom.m_Enchantments),
|
||||
m_CustomName (a_CopyFrom.m_CustomName),
|
||||
m_Lore (a_CopyFrom.m_Lore)
|
||||
m_Lore (a_CopyFrom.m_Lore),
|
||||
m_Enchantments(a_CopyFrom.m_Enchantments)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -69,20 +69,20 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString
|
||||
: super(etMonster, a_Width, a_Height)
|
||||
, m_EMState(IDLE)
|
||||
, m_EMPersonality(AGGRESSIVE)
|
||||
, m_SightDistance(25)
|
||||
, m_Target(NULL)
|
||||
, m_AttackRate(3)
|
||||
, m_IdleInterval(0)
|
||||
, m_bMovingToDestination(false)
|
||||
, m_LastGroundHeight(POSY_TOINT)
|
||||
, m_IdleInterval(0)
|
||||
, m_DestroyTimer(0)
|
||||
, m_MobType(a_MobType)
|
||||
, m_SoundHurt(a_SoundHurt)
|
||||
, m_SoundDeath(a_SoundDeath)
|
||||
, m_AttackRate(3)
|
||||
, m_AttackDamage(1)
|
||||
, m_AttackRange(2)
|
||||
, m_AttackInterval(0)
|
||||
, m_SightDistance(25)
|
||||
, m_BurnsInDaylight(false)
|
||||
, m_LastGroundHeight(POSY_TOINT)
|
||||
{
|
||||
if (!a_ConfigName.empty())
|
||||
{
|
||||
|
@ -13,9 +13,9 @@
|
||||
|
||||
cVillager::cVillager(eVillagerType VillagerType) :
|
||||
super("Villager", mtVillager, "", "", 0.6, 1.8),
|
||||
m_ActionCountDown(-1),
|
||||
m_Type(VillagerType),
|
||||
m_VillagerAction(false),
|
||||
m_ActionCountDown(-1)
|
||||
m_VillagerAction(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ void cProtocol172::DataReceived(const char * a_Data, int a_Size)
|
||||
Byte Decrypted[512];
|
||||
while (a_Size > 0)
|
||||
{
|
||||
int NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size;
|
||||
size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size;
|
||||
m_Decryptor.ProcessData(Decrypted, (Byte *)a_Data, NumBytes);
|
||||
AddReceivedData((const char *)Decrypted, NumBytes);
|
||||
a_Size -= NumBytes;
|
||||
@ -1836,7 +1836,7 @@ void cProtocol172::SendData(const char * a_Data, int a_Size)
|
||||
Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks)
|
||||
while (a_Size > 0)
|
||||
{
|
||||
int NumBytes = (a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Size;
|
||||
size_t NumBytes = ((size_t)a_Size > sizeof(Encrypted)) ? sizeof(Encrypted) : (size_t)a_Size;
|
||||
m_Encryptor.ProcessData(Encrypted, (Byte *)a_Data, NumBytes);
|
||||
m_Client->SendData((const char *)Encrypted, NumBytes);
|
||||
a_Size -= NumBytes;
|
||||
|
17
src/Root.cpp
17
src/Root.cpp
@ -132,7 +132,7 @@ void cRoot::Start(void)
|
||||
LOGWARN("Regenerating settings.ini, all settings will be reset");
|
||||
IniFile.AddHeaderComment(" This is the main server configuration");
|
||||
IniFile.AddHeaderComment(" Most of the settings here can be configured using the webadmin interface, if enabled in webadmin.ini");
|
||||
IniFile.AddHeaderComment(" See: http://www.mc-server.org/wiki/doku.php?id=configure:settings.ini for further configuration help");
|
||||
IniFile.AddHeaderComment(" See: http://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help");
|
||||
}
|
||||
|
||||
m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0);
|
||||
@ -219,16 +219,14 @@ void cRoot::Start(void)
|
||||
delete m_InputThread; m_InputThread = NULL;
|
||||
#endif
|
||||
|
||||
// Deallocate stuffs
|
||||
// Stop the server:
|
||||
m_WebAdmin->Stop();
|
||||
LOG("Shutting down server...");
|
||||
m_Server->Shutdown();
|
||||
|
||||
LOGD("Shutting down deadlock detector...");
|
||||
dd.Stop();
|
||||
|
||||
LOGD("Stopping world threads...");
|
||||
StopWorlds();
|
||||
|
||||
LOGD("Stopping authenticator...");
|
||||
m_Authenticator.Stop();
|
||||
|
||||
@ -536,6 +534,15 @@ void cRoot::SaveAllChunks(void)
|
||||
|
||||
|
||||
|
||||
void cRoot::ReloadGroups(void)
|
||||
{
|
||||
m_GroupManager->LoadGroups();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cRoot::LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix)
|
||||
{
|
||||
for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr)
|
||||
|
@ -99,6 +99,9 @@ public:
|
||||
/// Saves all chunks in all worlds
|
||||
void SaveAllChunks(void); // tolua_export
|
||||
|
||||
/// Reloads all the groups
|
||||
void ReloadGroups(void); // tolua_export
|
||||
|
||||
/// Calls the callback for each player in all worlds
|
||||
bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
|
@ -197,8 +197,8 @@ cTeam::cTeam(const AString & a_Name, const AString & a_DisplayName,
|
||||
const AString & a_Prefix, const AString & a_Suffix)
|
||||
: m_AllowsFriendlyFire(true)
|
||||
, m_CanSeeFriendlyInvisible(false)
|
||||
, m_Name(a_Name)
|
||||
, m_DisplayName(a_DisplayName)
|
||||
, m_Name(a_Name)
|
||||
, m_Prefix(a_Prefix)
|
||||
, m_Suffix(a_Suffix)
|
||||
{}
|
||||
|
@ -459,6 +459,17 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac
|
||||
if (split[0] == "reload")
|
||||
{
|
||||
cPluginManager::Get()->ReloadPlugins();
|
||||
cRoot::Get()->ReloadGroups();
|
||||
return;
|
||||
}
|
||||
if (split[0] == "reloadplugins")
|
||||
{
|
||||
cPluginManager::Get()->ReloadPlugins();
|
||||
return;
|
||||
}
|
||||
if (split[0] == "reloadgroups")
|
||||
{
|
||||
cRoot::Get()->ReloadGroups();
|
||||
return;
|
||||
}
|
||||
|
||||
|
1534
src/Simulator/IncrementalRedstoneSimulator.cpp
Normal file
1534
src/Simulator/IncrementalRedstoneSimulator.cpp
Normal file
File diff suppressed because it is too large
Load Diff
263
src/Simulator/IncrementalRedstoneSimulator.h
Normal file
263
src/Simulator/IncrementalRedstoneSimulator.h
Normal file
@ -0,0 +1,263 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RedstoneSimulator.h"
|
||||
|
||||
/// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used
|
||||
typedef cCoordWithBlockAndBoolVector cRedstoneSimulatorChunkData;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cIncrementalRedstoneSimulator :
|
||||
public cRedstoneSimulator
|
||||
{
|
||||
typedef cRedstoneSimulator super;
|
||||
public:
|
||||
|
||||
cIncrementalRedstoneSimulator(cWorld & a_World);
|
||||
~cIncrementalRedstoneSimulator();
|
||||
|
||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
||||
virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType ) override { return IsRedstone(a_BlockType); }
|
||||
|
||||
enum eRedstoneDirection
|
||||
{
|
||||
REDSTONE_NONE = 0,
|
||||
REDSTONE_X_POS = 0x1,
|
||||
REDSTONE_X_NEG = 0x2,
|
||||
REDSTONE_Z_POS = 0x4,
|
||||
REDSTONE_Z_NEG = 0x8,
|
||||
};
|
||||
eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
private:
|
||||
|
||||
struct sPoweredBlocks // Define structure of the directly powered blocks list
|
||||
{
|
||||
Vector3i a_BlockPos; // Position of powered block
|
||||
Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos
|
||||
};
|
||||
|
||||
struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side)
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
Vector3i a_MiddlePos;
|
||||
Vector3i a_SourcePos;
|
||||
};
|
||||
|
||||
struct sSimulatedPlayerToggleableList
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
bool WasLastStatePowered;
|
||||
};
|
||||
|
||||
struct sRepeatersDelayList
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
short a_DelayTicks;
|
||||
short a_ElapsedTicks;
|
||||
bool ShouldPowerOn;
|
||||
};
|
||||
|
||||
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
|
||||
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
|
||||
typedef std::vector <sSimulatedPlayerToggleableList> SimulatedPlayerToggleableList;
|
||||
typedef std::vector <sRepeatersDelayList> RepeatersDelayList;
|
||||
|
||||
PoweredBlocksList m_PoweredBlocks;
|
||||
LinkedBlocksList m_LinkedPoweredBlocks;
|
||||
SimulatedPlayerToggleableList m_SimulatedPlayerToggleableBlocks;
|
||||
RepeatersDelayList m_RepeatersDelayList;
|
||||
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
|
||||
|
||||
// We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly
|
||||
// In addition to being non-performant, it would stop the player from actually breaking said device
|
||||
|
||||
/* ====== SOURCES ====== */
|
||||
/** Handles the redstone torch */
|
||||
void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles the redstone block */
|
||||
void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles levers */
|
||||
void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles buttons */
|
||||
void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType);
|
||||
/** Handles daylight sensors */
|
||||
void HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles pressure plates */
|
||||
void HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
/* ==================== */
|
||||
|
||||
/* ====== CARRIERS ====== */
|
||||
/** Handles redstone wire */
|
||||
void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles repeaters */
|
||||
void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/* ====================== */
|
||||
|
||||
/* ====== DEVICES ====== */
|
||||
/** Handles pistons */
|
||||
void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles dispensers and droppers */
|
||||
void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles TNT (exploding) */
|
||||
void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles redstone lamps */
|
||||
void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles doords */
|
||||
void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles command blocks */
|
||||
void HandleCommandBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles activator, detector, and powered rails */
|
||||
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
/** Handles trapdoors */
|
||||
void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles noteblocks */
|
||||
void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/* ===================== */
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
/** Marks a block as powered */
|
||||
void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock);
|
||||
/** Marks a block as being powered through another block */
|
||||
void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock);
|
||||
/** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */
|
||||
void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered);
|
||||
/** Marks the second block in a direction as linked powered */
|
||||
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock);
|
||||
/** Marks all blocks immediately surrounding a coordinate as powered */
|
||||
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
|
||||
/** Queues a repeater to be powered or unpowered */
|
||||
void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn);
|
||||
|
||||
/** Returns if a coordinate is powered or linked powered */
|
||||
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }
|
||||
/** Returns if a coordinate is in the directly powered blocks list */
|
||||
bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Returns if a coordinate is in the indirectly powered blocks list */
|
||||
bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
|
||||
bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
|
||||
/** Returns if a repeater is powered */
|
||||
bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a piston is powered */
|
||||
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a wire is powered
|
||||
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire
|
||||
*/
|
||||
bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
|
||||
/** Returns if lever metadata marks it as emitting power */
|
||||
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
||||
/** Returns if button metadata marks it as emitting power */
|
||||
bool IsButtonOn(NIBBLETYPE a_BlockMeta);
|
||||
/* ============================== */
|
||||
|
||||
/* ====== Misc Functions ====== */
|
||||
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
||||
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return g_BlockFullyOccupiesVoxel[Block]; }
|
||||
|
||||
/** Returns if a block is a mechanism (something that accepts power and does something) */
|
||||
inline static bool IsMechanism(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
case E_BLOCK_ACTIVATOR_RAIL:
|
||||
case E_BLOCK_COMMAND_BLOCK:
|
||||
case E_BLOCK_PISTON:
|
||||
case E_BLOCK_STICKY_PISTON:
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_HOPPER:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_TNT:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
case E_BLOCK_WOODEN_DOOR:
|
||||
case E_BLOCK_IRON_DOOR:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns if a block has the potential to output power */
|
||||
inline static bool IsPotentialSource(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns if a block is any sort of redstone device */
|
||||
inline static bool IsRedstone(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
// All redstone devices, please alpha sort
|
||||
case E_BLOCK_ACTIVATOR_RAIL:
|
||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||
case E_BLOCK_COMMAND_BLOCK:
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_HOPPER:
|
||||
case E_BLOCK_INACTIVE_COMPARATOR:
|
||||
case E_BLOCK_IRON_DOOR:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_STICKY_PISTON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_TNT:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_TRIPWIRE_HOOK:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_DOOR:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_PISTON:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
};
|
40
src/Simulator/NoopRedstoneSimulator.h
Normal file
40
src/Simulator/NoopRedstoneSimulator.h
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RedstoneSimulator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cRedstoneNoopSimulator :
|
||||
public cRedstoneSimulator
|
||||
{
|
||||
typedef cRedstoneSimulator super;
|
||||
public:
|
||||
|
||||
cRedstoneNoopSimulator(cWorld & a_World) :
|
||||
super(a_World)
|
||||
{
|
||||
}
|
||||
|
||||
//~cRedstoneNoopSimulator();
|
||||
|
||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override
|
||||
{
|
||||
UNUSED(a_Dt);
|
||||
UNUSED(a_ChunkX);
|
||||
UNUSED(a_ChunkZ);
|
||||
UNUSED(a_Chunk);
|
||||
}
|
||||
virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType ) override { return false; }
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override
|
||||
{
|
||||
UNUSED(a_BlockX);
|
||||
UNUSED(a_BlockY);
|
||||
UNUSED(a_BlockZ);
|
||||
UNUSED(a_Chunk);
|
||||
}
|
||||
|
||||
} ;
|
File diff suppressed because it is too large
Load Diff
@ -3,10 +3,6 @@
|
||||
|
||||
#include "Simulator.h"
|
||||
|
||||
/// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used
|
||||
typedef cCoordWithBlockAndBoolVector cRedstoneSimulatorChunkData;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -14,250 +10,8 @@ class cRedstoneSimulator :
|
||||
public cSimulator
|
||||
{
|
||||
typedef cSimulator super;
|
||||
public:
|
||||
|
||||
cRedstoneSimulator(cWorld & a_World);
|
||||
~cRedstoneSimulator();
|
||||
|
||||
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used
|
||||
virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override;
|
||||
virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType ) override { return IsRedstone(a_BlockType); }
|
||||
|
||||
enum eRedstoneDirection
|
||||
{
|
||||
REDSTONE_NONE = 0,
|
||||
REDSTONE_X_POS = 0x1,
|
||||
REDSTONE_X_NEG = 0x2,
|
||||
REDSTONE_Z_POS = 0x4,
|
||||
REDSTONE_Z_NEG = 0x8,
|
||||
};
|
||||
eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
private:
|
||||
|
||||
struct sPoweredBlocks // Define structure of the directly powered blocks list
|
||||
{
|
||||
Vector3i a_BlockPos; // Position of powered block
|
||||
Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos
|
||||
};
|
||||
|
||||
struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side)
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
Vector3i a_MiddlePos;
|
||||
Vector3i a_SourcePos;
|
||||
};
|
||||
|
||||
struct sSimulatedPlayerToggleableList
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
bool WasLastStatePowered;
|
||||
};
|
||||
|
||||
struct sRepeatersDelayList
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
short a_DelayTicks;
|
||||
short a_ElapsedTicks;
|
||||
bool ShouldPowerOn;
|
||||
};
|
||||
|
||||
typedef std::vector <sPoweredBlocks> PoweredBlocksList;
|
||||
typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList;
|
||||
typedef std::vector <sSimulatedPlayerToggleableList> SimulatedPlayerToggleableList;
|
||||
typedef std::vector <sRepeatersDelayList> RepeatersDelayList;
|
||||
public:
|
||||
cRedstoneSimulator(cWorld & a_World);
|
||||
|
||||
PoweredBlocksList m_PoweredBlocks;
|
||||
LinkedBlocksList m_LinkedPoweredBlocks;
|
||||
SimulatedPlayerToggleableList m_SimulatedPlayerToggleableBlocks;
|
||||
RepeatersDelayList m_RepeatersDelayList;
|
||||
|
||||
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override;
|
||||
|
||||
// We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly
|
||||
// In addition to being non-performant, it would stop the player from actually breaking said device
|
||||
|
||||
/* ====== SOURCES ====== */
|
||||
/** Handles the redstone torch */
|
||||
void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles the redstone block */
|
||||
void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles levers */
|
||||
void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles buttons */
|
||||
void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType);
|
||||
/** Handles daylight sensors */
|
||||
void HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles pressure plates */
|
||||
void HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
/* ==================== */
|
||||
|
||||
/* ====== CARRIERS ====== */
|
||||
/** Handles redstone wire */
|
||||
void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles repeaters */
|
||||
void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/* ====================== */
|
||||
|
||||
/* ====== DEVICES ====== */
|
||||
/** Handles pistons */
|
||||
void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles dispensers and droppers */
|
||||
void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles TNT (exploding) */
|
||||
void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles redstone lamps */
|
||||
void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles doords */
|
||||
void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles command blocks */
|
||||
void HandleCommandBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles activator, detector, and powered rails */
|
||||
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
/** Handles trapdoors */
|
||||
void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Handles noteblocks */
|
||||
void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/* ===================== */
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
/** Marks a block as powered */
|
||||
void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock);
|
||||
/** Marks a block as being powered through another block */
|
||||
void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock);
|
||||
/** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */
|
||||
void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered);
|
||||
/** Marks the second block in a direction as linked powered */
|
||||
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock);
|
||||
/** Marks all blocks immediately surrounding a coordinate as powered */
|
||||
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
|
||||
/** Queues a repeater to be powered or unpowered */
|
||||
void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn);
|
||||
|
||||
/** Returns if a coordinate is powered or linked powered */
|
||||
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }
|
||||
/** Returns if a coordinate is in the directly powered blocks list */
|
||||
bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Returns if a coordinate is in the indirectly powered blocks list */
|
||||
bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
|
||||
bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
|
||||
/** Returns if a repeater is powered */
|
||||
bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a piston is powered */
|
||||
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a wire is powered
|
||||
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire
|
||||
*/
|
||||
bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
|
||||
/** Returns if lever metadata marks it as emitting power */
|
||||
bool IsLeverOn(NIBBLETYPE a_BlockMeta);
|
||||
/** Returns if button metadata marks it as emitting power */
|
||||
bool IsButtonOn(NIBBLETYPE a_BlockMeta);
|
||||
/* ============================== */
|
||||
|
||||
/* ====== Misc Functions ====== */
|
||||
/** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */
|
||||
inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return g_BlockFullyOccupiesVoxel[Block]; }
|
||||
|
||||
/** Returns if a block is a mechanism (something that accepts power and does something) */
|
||||
inline static bool IsMechanism(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
case E_BLOCK_ACTIVATOR_RAIL:
|
||||
case E_BLOCK_COMMAND_BLOCK:
|
||||
case E_BLOCK_PISTON:
|
||||
case E_BLOCK_STICKY_PISTON:
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_HOPPER:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_TNT:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
case E_BLOCK_WOODEN_DOOR:
|
||||
case E_BLOCK_IRON_DOOR:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns if a block has the potential to output power */
|
||||
inline static bool IsPotentialSource(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns if a block is any sort of redstone device */
|
||||
inline static bool IsRedstone(BLOCKTYPE Block)
|
||||
{
|
||||
switch (Block)
|
||||
{
|
||||
// All redstone devices, please alpha sort
|
||||
case E_BLOCK_ACTIVATOR_RAIL:
|
||||
case E_BLOCK_ACTIVE_COMPARATOR:
|
||||
case E_BLOCK_BLOCK_OF_REDSTONE:
|
||||
case E_BLOCK_COMMAND_BLOCK:
|
||||
case E_BLOCK_DETECTOR_RAIL:
|
||||
case E_BLOCK_DISPENSER:
|
||||
case E_BLOCK_DAYLIGHT_SENSOR:
|
||||
case E_BLOCK_DROPPER:
|
||||
case E_BLOCK_FENCE_GATE:
|
||||
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_HOPPER:
|
||||
case E_BLOCK_INACTIVE_COMPARATOR:
|
||||
case E_BLOCK_IRON_DOOR:
|
||||
case E_BLOCK_LEVER:
|
||||
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
|
||||
case E_BLOCK_NOTE_BLOCK:
|
||||
case E_BLOCK_POWERED_RAIL:
|
||||
case E_BLOCK_REDSTONE_LAMP_OFF:
|
||||
case E_BLOCK_REDSTONE_LAMP_ON:
|
||||
case E_BLOCK_REDSTONE_REPEATER_OFF:
|
||||
case E_BLOCK_REDSTONE_REPEATER_ON:
|
||||
case E_BLOCK_REDSTONE_TORCH_OFF:
|
||||
case E_BLOCK_REDSTONE_TORCH_ON:
|
||||
case E_BLOCK_REDSTONE_WIRE:
|
||||
case E_BLOCK_STICKY_PISTON:
|
||||
case E_BLOCK_STONE_BUTTON:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_TNT:
|
||||
case E_BLOCK_TRAPDOOR:
|
||||
case E_BLOCK_TRIPWIRE_HOOK:
|
||||
case E_BLOCK_WOODEN_BUTTON:
|
||||
case E_BLOCK_WOODEN_DOOR:
|
||||
case E_BLOCK_WOODEN_PRESSURE_PLATE:
|
||||
case E_BLOCK_PISTON:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
} ;
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
|
||||
cWebAdmin::cWebAdmin(void) :
|
||||
m_IsInitialized(false),
|
||||
m_IsRunning(false),
|
||||
m_TemplateScript("<webadmin_template>")
|
||||
{
|
||||
}
|
||||
@ -52,29 +53,26 @@ cWebAdmin::cWebAdmin(void) :
|
||||
|
||||
cWebAdmin::~cWebAdmin()
|
||||
{
|
||||
if (m_IsInitialized)
|
||||
{
|
||||
LOGD("Stopping WebAdmin...");
|
||||
}
|
||||
ASSERT(!m_IsRunning); // Was the HTTP server stopped properly?
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWebAdmin::AddPlugin( cWebPlugin * a_Plugin )
|
||||
void cWebAdmin::AddPlugin(cWebPlugin * a_Plugin)
|
||||
{
|
||||
m_Plugins.remove( a_Plugin );
|
||||
m_Plugins.push_back( a_Plugin );
|
||||
m_Plugins.remove(a_Plugin);
|
||||
m_Plugins.push_back(a_Plugin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWebAdmin::RemovePlugin( cWebPlugin * a_Plugin )
|
||||
void cWebAdmin::RemovePlugin(cWebPlugin * a_Plugin)
|
||||
{
|
||||
m_Plugins.remove( a_Plugin );
|
||||
m_Plugins.remove(a_Plugin);
|
||||
}
|
||||
|
||||
|
||||
@ -87,7 +85,8 @@ bool cWebAdmin::Init(void)
|
||||
{
|
||||
LOGWARN("Regenerating webadmin.ini, all settings will be reset");
|
||||
m_IniFile.AddHeaderComment(" This file controls the webadmin feature of MCServer");
|
||||
m_IniFile.AddHeaderComment(" Username format: [User:*username*] | Password format: Password=*password*; for example:");
|
||||
m_IniFile.AddHeaderComment(" Username format: [User:*username*]");
|
||||
m_IniFile.AddHeaderComment(" Password format: Password=*password*; for example:");
|
||||
m_IniFile.AddHeaderComment(" [User:admin]");
|
||||
m_IniFile.AddHeaderComment(" Password=admin");
|
||||
}
|
||||
@ -134,7 +133,24 @@ bool cWebAdmin::Start(void)
|
||||
m_TemplateScript.Close();
|
||||
}
|
||||
|
||||
return m_HTTPServer.Start(*this);
|
||||
m_IsRunning = m_HTTPServer.Start(*this);
|
||||
return m_IsRunning;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWebAdmin::Stop(void)
|
||||
{
|
||||
if (!m_IsRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("Stopping WebAdmin...");
|
||||
m_HTTPServer.Stop();
|
||||
m_IsRunning = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,13 +56,13 @@ struct HTTPRequest
|
||||
AString Username;
|
||||
// tolua_end
|
||||
|
||||
/// Parameters given in the URL, after the questionmark
|
||||
/** Parameters given in the URL, after the questionmark */
|
||||
StringStringMap Params; // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
/// Parameters posted as a part of a form - either in the URL (GET method) or in the body (POST method)
|
||||
/** Parameters posted as a part of a form - either in the URL (GET method) or in the body (POST method) */
|
||||
StringStringMap PostParams; // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
/// Same as PostParams
|
||||
/** Same as PostParams */
|
||||
FormDataMap FormData; // >> EXPORTED IN MANUALBINDINGS <<
|
||||
} ; // tolua_export
|
||||
|
||||
@ -107,14 +107,17 @@ public:
|
||||
cWebAdmin(void);
|
||||
virtual ~cWebAdmin();
|
||||
|
||||
/// Initializes the object. Returns true if successfully initialized and ready to start
|
||||
/** Initializes the object. Returns true if successfully initialized and ready to start */
|
||||
bool Init(void);
|
||||
|
||||
/// Starts the HTTP server taking care of the admin. Returns true if successful
|
||||
/** Starts the HTTP server taking care of the admin. Returns true if successful */
|
||||
bool Start(void);
|
||||
|
||||
/** Stops the HTTP server, if it was started. */
|
||||
void Stop(void);
|
||||
|
||||
void AddPlugin( cWebPlugin* a_Plugin );
|
||||
void RemovePlugin( cWebPlugin* a_Plugin );
|
||||
void AddPlugin(cWebPlugin * a_Plugin);
|
||||
void RemovePlugin(cWebPlugin * a_Plugin);
|
||||
|
||||
// TODO: Convert this to the auto-locking callback mechanism used for looping players in worlds and such
|
||||
PluginList GetPlugins() const { return m_Plugins; } // >> EXPORTED IN MANUALBINDINGS <<
|
||||
@ -123,13 +126,13 @@ public:
|
||||
|
||||
sWebAdminPage GetPage(const HTTPRequest & a_Request);
|
||||
|
||||
/// Returns the contents of the default page - the list of plugins and players
|
||||
/** Returns the contents of the default page - the list of plugins and players */
|
||||
AString GetDefaultPage(void);
|
||||
|
||||
/// Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style)
|
||||
/** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */
|
||||
AString GetBaseURL(const AString & a_URL);
|
||||
|
||||
/// Escapes text passed into it, so it can be embedded into html.
|
||||
/** Escapes text passed into it, so it can be embedded into html. */
|
||||
static AString GetHTMLEscapedString(const AString & a_Input);
|
||||
|
||||
AString GetIPv4Ports(void) const { return m_PortsIPv4; }
|
||||
@ -137,21 +140,21 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
/// Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style)
|
||||
/** Returns the prefix needed for making a link point to the webadmin root from the given URL ("../../../webadmin"-style) */
|
||||
AString GetBaseURL(const AStringVector& a_URLSplit);
|
||||
|
||||
protected:
|
||||
/// Common base class for request body data handlers
|
||||
/** Common base class for request body data handlers */
|
||||
class cRequestData
|
||||
{
|
||||
public:
|
||||
virtual ~cRequestData() {} // Force a virtual destructor in all descendants
|
||||
|
||||
/// Called when a new chunk of body data is received
|
||||
/** Called when a new chunk of body data is received */
|
||||
virtual void OnBody(const char * a_Data, int a_Size) = 0;
|
||||
} ;
|
||||
|
||||
/// The body handler for requests in the "/webadmin" and "/~webadmin" paths
|
||||
/** The body handler for requests in the "/webadmin" and "/~webadmin" paths */
|
||||
class cWebadminRequestData :
|
||||
public cRequestData,
|
||||
public cHTTPFormParser::cCallbacks
|
||||
@ -182,10 +185,13 @@ protected:
|
||||
} ;
|
||||
|
||||
|
||||
/// Set to true if Init() succeeds and the webadmin isn't to be disabled
|
||||
/** Set to true if Init() succeeds and the webadmin isn't to be disabled */
|
||||
bool m_IsInitialized;
|
||||
|
||||
/** Set to true if Start() succeeds in starting the server, reset back to false in Stop(). */
|
||||
bool m_IsRunning;
|
||||
|
||||
/// The webadmin.ini file, used for the settings and allowed logins
|
||||
/** The webadmin.ini file, used for the settings and allowed logins */
|
||||
cIniFile m_IniFile;
|
||||
|
||||
PluginList m_Plugins;
|
||||
@ -193,19 +199,19 @@ protected:
|
||||
AString m_PortsIPv4;
|
||||
AString m_PortsIPv6;
|
||||
|
||||
/// The Lua template script to provide templates:
|
||||
/** The Lua template script to provide templates: */
|
||||
cLuaState m_TemplateScript;
|
||||
|
||||
/// The HTTP server which provides the underlying HTTP parsing, serialization and events
|
||||
/** The HTTP server which provides the underlying HTTP parsing, serialization and events */
|
||||
cHTTPServer m_HTTPServer;
|
||||
|
||||
|
||||
AString GetTemplate(void);
|
||||
|
||||
/// Handles requests coming to the "/webadmin" or "/~webadmin" URLs
|
||||
/** Handles requests coming to the "/webadmin" or "/~webadmin" URLs */
|
||||
void HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
|
||||
|
||||
/// Handles requests for the root page
|
||||
/** Handles requests for the root page */
|
||||
void HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);
|
||||
|
||||
// cHTTPServer::cCallbacks overrides:
|
||||
|
@ -29,8 +29,9 @@
|
||||
#include "Simulator/FluidSimulator.h"
|
||||
#include "Simulator/FireSimulator.h"
|
||||
#include "Simulator/NoopFluidSimulator.h"
|
||||
#include "Simulator/NoopRedstoneSimulator.h"
|
||||
#include "Simulator/SandSimulator.h"
|
||||
#include "Simulator/RedstoneSimulator.h"
|
||||
#include "Simulator/IncrementalRedstoneSimulator.h"
|
||||
#include "Simulator/VaporizeFluidSimulator.h"
|
||||
|
||||
// Mobs:
|
||||
@ -247,11 +248,13 @@ cWorld::cWorld(const AString & a_WorldName) :
|
||||
m_SkyDarkness(0),
|
||||
m_Weather(eWeather_Sunny),
|
||||
m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
|
||||
m_Scoreboard(this),
|
||||
m_GeneratorCallbacks(*this),
|
||||
m_TickThread(*this),
|
||||
m_Scoreboard(this),
|
||||
m_bCommandBlocksEnabled(false),
|
||||
m_bUseChatPrefixes(true)
|
||||
m_TickThread(*this)
|
||||
{
|
||||
LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str());
|
||||
|
||||
@ -599,12 +602,11 @@ void cWorld::Start(void)
|
||||
m_LavaSimulator = InitializeFluidSimulator(IniFile, "Lava", E_BLOCK_LAVA, E_BLOCK_STATIONARY_LAVA);
|
||||
m_SandSimulator = new cSandSimulator(*this, IniFile);
|
||||
m_FireSimulator = new cFireSimulator(*this, IniFile);
|
||||
m_RedstoneSimulator = new cRedstoneSimulator(*this);
|
||||
m_RedstoneSimulator = InitializeRedstoneSimulator(IniFile);
|
||||
|
||||
// Water and Lava simulators get registered in InitializeFluidSimulator()
|
||||
// Water, Lava and Redstone simulators get registered in their initialize function.
|
||||
m_SimulatorManager->RegisterSimulator(m_SandSimulator, 1);
|
||||
m_SimulatorManager->RegisterSimulator(m_FireSimulator, 1);
|
||||
m_SimulatorManager->RegisterSimulator(m_RedstoneSimulator, 1);
|
||||
|
||||
m_Lighting.Start(this);
|
||||
m_Storage.Start(this, m_StorageSchema, m_StorageCompressionFactor );
|
||||
@ -2874,6 +2876,36 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul
|
||||
|
||||
|
||||
|
||||
cRedstoneSimulator * cWorld::InitializeRedstoneSimulator(cIniFile & a_IniFile)
|
||||
{
|
||||
AString SimulatorName = a_IniFile.GetValueSet("Physics", "RedstoneSimulator", "");
|
||||
|
||||
if (SimulatorName.empty())
|
||||
{
|
||||
LOGWARNING("[Physics] RedstoneSimulator not present or empty in %s, using the default of \"incremental\".", GetIniFileName().c_str());
|
||||
SimulatorName = "incremental";
|
||||
}
|
||||
|
||||
cRedstoneSimulator * res = NULL;
|
||||
|
||||
if (NoCaseCompare(SimulatorName, "incremental") == 0)
|
||||
{
|
||||
res = new cIncrementalRedstoneSimulator(*this);
|
||||
}
|
||||
else if (NoCaseCompare(SimulatorName, "noop") == 0)
|
||||
{
|
||||
res = new cRedstoneNoopSimulator(*this);
|
||||
}
|
||||
|
||||
m_SimulatorManager->RegisterSimulator(res, 1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock)
|
||||
{
|
||||
AString SimulatorNameKey;
|
||||
|
@ -875,6 +875,9 @@ private:
|
||||
|
||||
/** Creates a new fluid simulator, loads its settings from the inifile (a_FluidName section) */
|
||||
cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock);
|
||||
|
||||
/** Creates a new redstone simulator.*/
|
||||
cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile);
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user