1
0

Merge remote-tracking branch 'origin/master' into playerimprovements

Conflicts:
	src/Root.cpp
	src/Root.h
	src/World.cpp
This commit is contained in:
Tiger Wang 2014-02-09 00:14:42 +00:00
commit 9d1c9097e3
38 changed files with 2325 additions and 1902 deletions

View File

@ -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:

View File

@ -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
View File

@ -0,0 +1,2 @@
*.txt
*.md

View File

@ -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 =

View File

@ -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

View File

@ -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");

View File

@ -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"},

View File

@ -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;

View File

@ -6,7 +6,7 @@
#include "Simulator/FireSimulator.h"
#include "Simulator/SandSimulator.h"
#include "Simulator/RedstoneSimulator.h"
#include "Simulator/IncrementalRedstoneSimulator.h"

View File

@ -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)
{
}

View File

@ -132,8 +132,6 @@ protected:
class cAESCFBEncryptor
{
public:
Byte test;
cAESCFBEncryptor(void);
~cAESCFBEncryptor();

View File

@ -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++;

View File

@ -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);

View File

@ -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!!

View File

@ -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)
{
}

View File

@ -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())

View File

@ -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 <<

View File

@ -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();
}

View File

@ -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;

View File

@ -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 --");
}

View File

@ -15,6 +15,7 @@ class cGroupManager
{
public:
cGroup * GetGroup(const AString & a_Name);
void LoadGroups(void);
private:
friend class cRoot;

View File

@ -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)
{
}

View File

@ -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())
{

View File

@ -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)
{
}

View File

@ -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;

View File

@ -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)

View File

@ -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 <<

View File

@ -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)
{}

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View 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;
}
}
};

View 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

View File

@ -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;
}
}
};
} ;

View File

@ -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;
}

View File

@ -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:

View File

@ -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;

View File

@ -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