1
0

Merge branch 'master' into cmake

This commit is contained in:
Tycho Bickerstaff 2013-12-10 23:01:35 +00:00
commit dd633d5a94
35 changed files with 641 additions and 566 deletions

View File

@ -88,7 +88,7 @@ CXX_OPTIONS += -Wall
################################################### ###################################################
# Fix Crypto++ warnings in clang # Fix Crypto++ warnings in clang
ifeq ($(shell $(CXX) --version 2>&1 | grep -i -c "clang version"),1) ifeq ($(shell $(CXX) --version 2>&1 | grep -i -c "clang"),1)
CC_OPTIONS += -DCRYPTOPP_DISABLE_ASM CC_OPTIONS += -DCRYPTOPP_DISABLE_ASM
CXX_OPTIONS += -DCRYPTOPP_DISABLE_ASM CXX_OPTIONS += -DCRYPTOPP_DISABLE_ASM
endif endif

View File

@ -1862,6 +1862,17 @@ end
}, },
}, -- cServer }, -- cServer
cTNTEntity =
{
Desc = "This class manages a TNT entity.",
Functions =
{
GetCounterTime = { Return = "number", Notes = "Returns the time until the entity explodes." },
GetMaxFuseTime = { Return = "number", Notes = "Returns how long the fuse was." },
},
Inherits = "cEntity",
},
cTracer = cTracer =
{ {
Desc = [[ Desc = [[

View File

@ -0,0 +1,24 @@
return
{
HOOK_WORLD_STARTED =
{
CalledWhen = "A {{cWorld|world}} is initialized",
DefaultFnName = "OnWorldStarted", -- also used as pagename
Desc = [[
This hook is called whenever a {{cWorld|world}} is initialized.
]],
Params =
{
{ Name = "World", Type = "{{cWorld}}", Notes = "World that is started" },
},
Returns = [[
If the function returns false or no value, the next plugin's callback is called. If the function
returns true, no other callback is called for this event. There is no overridable behavior.
]],
}, -- HOOK_WORLD_STARTED
}

@ -1 +1 @@
Subproject commit ede668bc7c310af49ad7354c00d3f11adbae792a Subproject commit 351aff7efa94ce3c7ba733d5f83013e8a3fdfbfd

View File

@ -1,3 +0,0 @@
[Banned]
;PlayerName=1

View File

@ -1,17 +0,0 @@
[Admins]
Permissions=*
Color=c
[Mods]
Color=5
Inherits=Vips
Permissions=core.time,core.item
[Vips]
Permissions=core.teleport
Color=2
Inherits=Default
[Default]
Permissions=core.build,core.help,core.playerlist,core.pluginlist,core.spawn,transapi.setlang,core.tell,core.me
Color=7

View File

@ -1,23 +0,0 @@
[FakeTruth]
Groups=Admins
[Duralex]
Groups=Admins
[Luthrandel]
Groups=Admins
[cruisecho]
Groups=Admins
[Kwen]
Groups=Admins
[aloe_vera]
Groups=Admins
[xoft]
Groups=Admins
[Player]
Groups=Admins

View File

@ -1,6 +0,0 @@
[WhiteListSettings]
WhiteListOn=0
[WhiteList]
;PlayerName=1

View File

@ -36,6 +36,7 @@ $cfile "../Entities/Pawn.h"
$cfile "../Entities/Player.h" $cfile "../Entities/Player.h"
$cfile "../Entities/Pickup.h" $cfile "../Entities/Pickup.h"
$cfile "../Entities/ProjectileEntity.h" $cfile "../Entities/ProjectileEntity.h"
$cfile "../Entities/TNTEntity.h"
$cfile "../Server.h" $cfile "../Server.h"
$cfile "../World.h" $cfile "../World.h"
$cfile "../Inventory.h" $cfile "../Inventory.h"

View File

@ -1,6 +1,6 @@
/* /*
** Lua binding: AllToLua ** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 12/08/13 18:11:12. ** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:45.
*/ */
#ifndef __cplusplus #ifndef __cplusplus
@ -34,6 +34,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S);
#include "../Entities/Player.h" #include "../Entities/Player.h"
#include "../Entities/Pickup.h" #include "../Entities/Pickup.h"
#include "../Entities/ProjectileEntity.h" #include "../Entities/ProjectileEntity.h"
#include "../Entities/TNTEntity.h"
#include "../Server.h" #include "../Server.h"
#include "../World.h" #include "../World.h"
#include "../Inventory.h" #include "../Inventory.h"
@ -218,7 +219,7 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cItemGrid"); tolua_usertype(tolua_S,"cItemGrid");
tolua_usertype(tolua_S,"cHTTPServer::cCallbacks"); tolua_usertype(tolua_S,"cHTTPServer::cCallbacks");
tolua_usertype(tolua_S,"cLuaWindow"); tolua_usertype(tolua_S,"cLuaWindow");
tolua_usertype(tolua_S,"cServer"); tolua_usertype(tolua_S,"cInventory");
tolua_usertype(tolua_S,"cHopperEntity"); tolua_usertype(tolua_S,"cHopperEntity");
tolua_usertype(tolua_S,"std::vector<AString>"); tolua_usertype(tolua_S,"std::vector<AString>");
tolua_usertype(tolua_S,"cBlockEntityWithItems"); tolua_usertype(tolua_S,"cBlockEntityWithItems");
@ -226,15 +227,16 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cCraftingGrid"); tolua_usertype(tolua_S,"cCraftingGrid");
tolua_usertype(tolua_S,"cBlockArea"); tolua_usertype(tolua_S,"cBlockArea");
tolua_usertype(tolua_S,"cGroup"); tolua_usertype(tolua_S,"cGroup");
tolua_usertype(tolua_S,"cItem");
tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cTracer");
tolua_usertype(tolua_S,"cItem");
tolua_usertype(tolua_S,"cBoundingBox");
tolua_usertype(tolua_S,"cArrowEntity"); tolua_usertype(tolua_S,"cArrowEntity");
tolua_usertype(tolua_S,"cDropSpenserEntity"); tolua_usertype(tolua_S,"cDropSpenserEntity");
tolua_usertype(tolua_S,"cBoundingBox");
tolua_usertype(tolua_S,"cCuboid"); tolua_usertype(tolua_S,"cCuboid");
tolua_usertype(tolua_S,"Vector3i"); tolua_usertype(tolua_S,"Vector3i");
tolua_usertype(tolua_S,"cNoteEntity");
tolua_usertype(tolua_S,"Vector3d"); tolua_usertype(tolua_S,"Vector3d");
tolua_usertype(tolua_S,"cNoteEntity");
tolua_usertype(tolua_S,"cServer");
tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cBlockEntity");
tolua_usertype(tolua_S,"cCriticalSection"); tolua_usertype(tolua_S,"cCriticalSection");
tolua_usertype(tolua_S,"HTTPTemplateRequest"); tolua_usertype(tolua_S,"HTTPTemplateRequest");
@ -254,8 +256,8 @@ static void tolua_reg_types (lua_State* tolua_S)
tolua_usertype(tolua_S,"cDropperEntity"); tolua_usertype(tolua_S,"cDropperEntity");
tolua_usertype(tolua_S,"cProjectileEntity"); tolua_usertype(tolua_S,"cProjectileEntity");
tolua_usertype(tolua_S,"cItemGrid::cListener"); tolua_usertype(tolua_S,"cItemGrid::cListener");
tolua_usertype(tolua_S,"cInventory");
tolua_usertype(tolua_S,"cPlayer"); tolua_usertype(tolua_S,"cPlayer");
tolua_usertype(tolua_S,"cTNTEntity");
} }
/* method: new of class cIniFile */ /* method: new of class cIniFile */
@ -11518,6 +11520,70 @@ static int tolua_AllToLua_cArrowEntity_SetIsCritical00(lua_State* tolua_S)
} }
#endif //#ifndef TOLUA_DISABLE #endif //#ifndef TOLUA_DISABLE
/* method: GetCounterTime of class cTNTEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cTNTEntity_GetCounterTime00
static int tolua_AllToLua_cTNTEntity_GetCounterTime00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cTNTEntity",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cTNTEntity* self = (const cTNTEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetCounterTime'", NULL);
#endif
{
double tolua_ret = (double) self->GetCounterTime();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetCounterTime'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetMaxFuseTime of class cTNTEntity */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cTNTEntity_GetMaxFuseTime00
static int tolua_AllToLua_cTNTEntity_GetMaxFuseTime00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"const cTNTEntity",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
const cTNTEntity* self = (const cTNTEntity*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMaxFuseTime'", NULL);
#endif
{
double tolua_ret = (double) self->GetMaxFuseTime();
tolua_pushnumber(tolua_S,(lua_Number)tolua_ret);
}
}
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'GetMaxFuseTime'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetDescription of class cServer */ /* method: GetDescription of class cServer */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetDescription00 #ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetDescription00
static int tolua_AllToLua_cServer_GetDescription00(lua_State* tolua_S) static int tolua_AllToLua_cServer_GetDescription00(lua_State* tolua_S)
@ -19926,6 +19992,41 @@ static int tolua_AllToLua_cRoot_GetWorld00(lua_State* tolua_S)
} }
#endif //#ifndef TOLUA_DISABLE #endif //#ifndef TOLUA_DISABLE
/* method: CreateAndInitializeWorld of class cRoot */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_CreateAndInitializeWorld00
static int tolua_AllToLua_cRoot_CreateAndInitializeWorld00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cRoot",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cRoot* self = (cRoot*) tolua_tousertype(tolua_S,1,0);
const AString a_WorldName = ((const AString) tolua_tocppstring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CreateAndInitializeWorld'", NULL);
#endif
{
cWorld* tolua_ret = (cWorld*) self->CreateAndInitializeWorld(a_WorldName);
tolua_pushusertype(tolua_S,(void*)tolua_ret,"cWorld");
tolua_pushcppstring(tolua_S,(const char*)a_WorldName);
}
}
return 2;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'CreateAndInitializeWorld'.",&tolua_err);
return 0;
#endif
}
#endif //#ifndef TOLUA_DISABLE
/* method: GetPrimaryServerVersion of class cRoot */ /* method: GetPrimaryServerVersion of class cRoot */
#ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPrimaryServerVersion00 #ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPrimaryServerVersion00
static int tolua_AllToLua_cRoot_GetPrimaryServerVersion00(lua_State* tolua_S) static int tolua_AllToLua_cRoot_GetPrimaryServerVersion00(lua_State* tolua_S)
@ -29797,6 +29898,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"HOOK_UPDATING_SIGN",cPluginManager::HOOK_UPDATING_SIGN); tolua_constant(tolua_S,"HOOK_UPDATING_SIGN",cPluginManager::HOOK_UPDATING_SIGN);
tolua_constant(tolua_S,"HOOK_WEATHER_CHANGED",cPluginManager::HOOK_WEATHER_CHANGED); tolua_constant(tolua_S,"HOOK_WEATHER_CHANGED",cPluginManager::HOOK_WEATHER_CHANGED);
tolua_constant(tolua_S,"HOOK_WEATHER_CHANGING",cPluginManager::HOOK_WEATHER_CHANGING); tolua_constant(tolua_S,"HOOK_WEATHER_CHANGING",cPluginManager::HOOK_WEATHER_CHANGING);
tolua_constant(tolua_S,"HOOK_WORLD_STARTED",cPluginManager::HOOK_WORLD_STARTED);
tolua_constant(tolua_S,"HOOK_WORLD_TICK",cPluginManager::HOOK_WORLD_TICK); tolua_constant(tolua_S,"HOOK_WORLD_TICK",cPluginManager::HOOK_WORLD_TICK);
tolua_constant(tolua_S,"HOOK_NUM_HOOKS",cPluginManager::HOOK_NUM_HOOKS); tolua_constant(tolua_S,"HOOK_NUM_HOOKS",cPluginManager::HOOK_NUM_HOOKS);
tolua_constant(tolua_S,"HOOK_MAX",cPluginManager::HOOK_MAX); tolua_constant(tolua_S,"HOOK_MAX",cPluginManager::HOOK_MAX);
@ -30957,6 +31059,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_cclass(tolua_S,"cFireChargeEntity","cFireChargeEntity","cProjectileEntity",NULL); tolua_cclass(tolua_S,"cFireChargeEntity","cFireChargeEntity","cProjectileEntity",NULL);
tolua_beginmodule(tolua_S,"cFireChargeEntity"); tolua_beginmodule(tolua_S,"cFireChargeEntity");
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cTNTEntity","cTNTEntity","cEntity",NULL);
tolua_beginmodule(tolua_S,"cTNTEntity");
tolua_function(tolua_S,"GetCounterTime",tolua_AllToLua_cTNTEntity_GetCounterTime00);
tolua_function(tolua_S,"GetMaxFuseTime",tolua_AllToLua_cTNTEntity_GetMaxFuseTime00);
tolua_endmodule(tolua_S);
tolua_cclass(tolua_S,"cServer","cServer","",NULL); tolua_cclass(tolua_S,"cServer","cServer","",NULL);
tolua_beginmodule(tolua_S,"cServer"); tolua_beginmodule(tolua_S,"cServer");
tolua_function(tolua_S,"GetDescription",tolua_AllToLua_cServer_GetDescription00); tolua_function(tolua_S,"GetDescription",tolua_AllToLua_cServer_GetDescription00);
@ -31348,6 +31455,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00); tolua_function(tolua_S,"GetServer",tolua_AllToLua_cRoot_GetServer00);
tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); tolua_function(tolua_S,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00);
tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00); tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cRoot_GetWorld00);
tolua_function(tolua_S,"CreateAndInitializeWorld",tolua_AllToLua_cRoot_CreateAndInitializeWorld00);
tolua_function(tolua_S,"GetPrimaryServerVersion",tolua_AllToLua_cRoot_GetPrimaryServerVersion00); tolua_function(tolua_S,"GetPrimaryServerVersion",tolua_AllToLua_cRoot_GetPrimaryServerVersion00);
tolua_function(tolua_S,"SetPrimaryServerVersion",tolua_AllToLua_cRoot_SetPrimaryServerVersion00); tolua_function(tolua_S,"SetPrimaryServerVersion",tolua_AllToLua_cRoot_SetPrimaryServerVersion00);
tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00); tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00);

View File

@ -1,6 +1,6 @@
/* /*
** Lua binding: AllToLua ** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 12/08/13 18:11:13. ** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:46.
*/ */
/* Exported function */ /* Exported function */

View File

@ -93,6 +93,7 @@ public:
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) = 0; virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) = 0;
virtual bool OnWeatherChanged (cWorld & a_World) = 0; virtual bool OnWeatherChanged (cWorld & a_World) = 0;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0; virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0;
virtual bool OnWorldStarted (cWorld & a_World) = 0;
virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) = 0; virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) = 0;
/** Handles the command split into a_Split, issued by player a_Player. /** Handles the command split into a_Split, issued by player a_Player.

View File

@ -1143,6 +1143,21 @@ bool cPluginLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather)
bool cPluginLua::OnWorldStarted(cWorld & a_World)
{
cCSLock Lock(m_CriticalSection);
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WORLD_STARTED];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
m_LuaState.Call((int)(**itr), &a_World);
}
return false;
}
bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) bool cPluginLua::OnWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);

View File

@ -90,6 +90,7 @@ public:
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override; virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnWeatherChanged (cWorld & a_World) override; virtual bool OnWeatherChanged (cWorld & a_World) override;
virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override; virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override;
virtual bool OnWorldStarted (cWorld & a_World) override;
virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override; virtual bool OnWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) override;
virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override; virtual bool HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override;

View File

@ -1209,6 +1209,27 @@ bool cPluginManager::CallHookWeatherChanging(cWorld & a_World, eWeather & a_NewW
bool cPluginManager::CallHookWorldStarted(cWorld & a_World)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_STARTED);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnWorldStarted(a_World))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec) bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastTickDurationMSec)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_TICK); HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_TICK);

View File

@ -106,6 +106,7 @@ public: // tolua_export
HOOK_UPDATING_SIGN, HOOK_UPDATING_SIGN,
HOOK_WEATHER_CHANGED, HOOK_WEATHER_CHANGED,
HOOK_WEATHER_CHANGING, HOOK_WEATHER_CHANGING,
HOOK_WORLD_STARTED,
HOOK_WORLD_TICK, HOOK_WORLD_TICK,
// Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants, // Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants,
@ -191,6 +192,7 @@ public: // tolua_export
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player); bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
bool CallHookWeatherChanged (cWorld & a_World); bool CallHookWeatherChanged (cWorld & a_World);
bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather); bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather);
bool CallHookWorldStarted (cWorld & a_World);
bool CallHookWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec); bool CallHookWorldTick (cWorld & a_World, float a_Dt, int a_LastTickDurationMSec);
bool DisablePlugin(const AString & a_PluginName); // tolua_export bool DisablePlugin(const AString & a_PluginName); // tolua_export

View File

@ -375,7 +375,7 @@ void cBlockHandler::DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX
MicroY = a_BlockY + 0.5; MicroY = a_BlockY + 0.5;
MicroZ = a_BlockZ + 0.5; MicroZ = a_BlockZ + 0.5;
// Add random offset second (this causes pickups to spawn inside blocks most times, it's a little buggy) // Add random offset second
MicroX += r1.rand(1) - 0.5; MicroX += r1.rand(1) - 0.5;
MicroZ += r1.rand(1) - 0.5; MicroZ += r1.rand(1) - 0.5;

View File

@ -773,6 +773,28 @@ void cByteBuffer::ReadAll(AString & a_Data)
bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, int a_NumBytes)
{
if (!a_Dst.CanWriteBytes(a_NumBytes) || !CanReadBytes(a_NumBytes))
{
// There's not enough source bytes or space in the dest BB
return false;
}
char buf[1024];
while (a_NumBytes > 0)
{
int num = (a_NumBytes > sizeof(buf)) ? sizeof(buf) : a_NumBytes;
VERIFY(ReadBuf(buf, num));
VERIFY(a_Dst.Write(buf, num));
a_NumBytes -= num;
}
return true;
}
void cByteBuffer::CommitRead(void) void cByteBuffer::CommitRead(void)
{ {
CHECK_THREAD; CHECK_THREAD;

View File

@ -42,6 +42,9 @@ public:
/// Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already) /// Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already)
int GetReadableSpace(void) const; int GetReadableSpace(void) const;
/// Returns the current data start index. For debugging purposes.
int GetDataStart(void) const { return m_DataStart; }
/// Returns true if the specified amount of bytes are available for reading /// Returns true if the specified amount of bytes are available for reading
bool CanReadBytes(int a_Count) const; bool CanReadBytes(int a_Count) const;
@ -106,6 +109,9 @@ public:
/// Reads all available data into a_Data /// Reads all available data into a_Data
void ReadAll(AString & a_Data); void ReadAll(AString & a_Data);
/// Reads the specified number of bytes and writes it into the destinatio bytebuffer. Returns true on success.
bool ReadToByteBuffer(cByteBuffer & a_Dst, int a_NumBytes);
/// Removes the bytes that have been read from the ringbuffer /// Removes the bytes that have been read from the ringbuffer
void CommitRead(void); void CommitRead(void);

View File

@ -706,8 +706,7 @@ void cChunk::ProcessQueuedSetBlocks(void)
{ {
// Current world age is bigger than/equal to target world age - delay time reached AND // Current world age is bigger than/equal to target world age - delay time reached AND
// Previous block type was the same as current block type (to prevent duplication) // Previous block type was the same as current block type (to prevent duplication)
// Since blocktypes were the same, we just need to set the meta SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); // SetMeta doesn't send to client
SetMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockMeta);
itr = m_SetBlockQueue.erase(itr); itr = m_SetBlockQueue.erase(itr);
LOGD("Successfully set queued block - previous and current types matched"); LOGD("Successfully set queued block - previous and current types matched");
} }
@ -1335,6 +1334,7 @@ void cChunk::WakeUpSimulators(void)
{ {
cSimulator * WaterSimulator = m_World->GetWaterSimulator(); cSimulator * WaterSimulator = m_World->GetWaterSimulator();
cSimulator * LavaSimulator = m_World->GetLavaSimulator(); cSimulator * LavaSimulator = m_World->GetLavaSimulator();
cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator();
int BaseX = m_PosX * cChunkDef::Width; int BaseX = m_PosX * cChunkDef::Width;
int BaseZ = m_PosZ * cChunkDef::Width; int BaseZ = m_PosZ * cChunkDef::Width;
for (int x = 0; x < Width; x++) for (int x = 0; x < Width; x++)
@ -1345,7 +1345,16 @@ void cChunk::WakeUpSimulators(void)
int BlockZ = z + BaseZ; int BlockZ = z + BaseZ;
for (int y = GetHeight(x, z); y >= 0; y--) for (int y = GetHeight(x, z); y >= 0; y--)
{ {
switch (cChunkDef::GetBlock(m_BlockTypes, x, y, z)) BLOCKTYPE Block = cChunkDef::GetBlock(m_BlockTypes, x, y, z);
// The redstone sim takes multiple blocks, use the inbuilt checker
if (RedstoneSimulator->IsAllowedBlock(Block))
{
RedstoneSimulator->AddBlock(BlockX, y, BlockZ, this);
continue;
}
switch (Block)
{ {
case E_BLOCK_WATER: case E_BLOCK_WATER:
{ {
@ -1357,6 +1366,10 @@ void cChunk::WakeUpSimulators(void)
LavaSimulator->AddBlock(BlockX, y, BlockZ, this); LavaSimulator->AddBlock(BlockX, y, BlockZ, this);
break; break;
} }
default:
{
break;
}
} // switch (BlockType) } // switch (BlockType)
} // for y } // for y
} // for z } // for z

View File

@ -2160,12 +2160,12 @@ void cClientHandle::PacketBufferFull(void)
void cClientHandle::PacketUnknown(unsigned char a_PacketType) void cClientHandle::PacketUnknown(UInt32 a_PacketType)
{ {
LOGERROR("Unknown packet type 0x%02x from client \"%s\" @ %s", a_PacketType, m_Username.c_str(), m_IPString.c_str()); LOGERROR("Unknown packet type 0x%x from client \"%s\" @ %s", a_PacketType, m_Username.c_str(), m_IPString.c_str());
AString Reason; AString Reason;
Printf(Reason, "Unknown [C->S] PacketType: 0x%02x", a_PacketType); Printf(Reason, "Unknown [C->S] PacketType: 0x%x", a_PacketType);
SendDisconnect(Reason); SendDisconnect(Reason);
Destroy(); Destroy();
} }

View File

@ -160,7 +160,7 @@ public:
// Calls that cProtocol descendants use to report state: // Calls that cProtocol descendants use to report state:
void PacketBufferFull(void); void PacketBufferFull(void);
void PacketUnknown(unsigned char a_PacketType); void PacketUnknown(UInt32 a_PacketType);
void PacketError(unsigned char a_PacketType); void PacketError(unsigned char a_PacketType);
// Calls that cProtocol descendants use for handling packets: // Calls that cProtocol descendants use for handling packets:

View File

@ -7,6 +7,7 @@
#include "DeadlockDetect.h" #include "DeadlockDetect.h"
#include "Root.h" #include "Root.h"
#include "World.h" #include "World.h"
# include <cstdlib>
@ -137,11 +138,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age)
void cDeadlockDetect::DeadlockDetected(void) void cDeadlockDetect::DeadlockDetected(void)
{ {
ASSERT(!"Deadlock detected"); ASSERT(!"Deadlock detected");
abort();
// TODO: Make a crashdump / coredump
// Crash the server intentionally:
*((volatile int *)0) = 0;
} }

View File

@ -40,21 +40,25 @@ void cExpOrb::SpawnOn(cClientHandle & a_Client)
void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
{ {
cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 4)); cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 5));
if (a_ClosestPlayer) if (a_ClosestPlayer != NULL)
{ {
Vector3f a_PlayerPos(a_ClosestPlayer->GetPosition()); Vector3f a_PlayerPos(a_ClosestPlayer->GetPosition());
a_PlayerPos.y++;
Vector3f a_Distance(a_PlayerPos - GetPosition()); Vector3f a_Distance(a_PlayerPos - GetPosition());
if (a_Distance.Length() < 0.1f) double Distance(a_Distance.Length());
if (Distance < 0.1f)
{ {
LOGD("Player %s picked up an ExpOrb. His reward is %i", a_ClosestPlayer->GetName().c_str(), m_Reward);
a_ClosestPlayer->DeltaExperience(m_Reward); a_ClosestPlayer->DeltaExperience(m_Reward);
a_ClosestPlayer->SendExperience();
Destroy(true); Destroy(true);
} }
a_Distance.y = 0;
a_Distance.Normalize(); a_Distance.Normalize();
a_Distance *= 3; a_Distance *= ((float) (5.5 - Distance));
SetSpeedX( a_Distance.x ); SetSpeedX( a_Distance.x );
SetSpeedY( a_Distance.y );
SetSpeedZ( a_Distance.z ); SetSpeedZ( a_Distance.z );
BroadcastMovementUpdate();
} }
HandlePhysics(a_Dt, a_Chunk);
} }

View File

@ -1393,7 +1393,12 @@ void cPlayer::LoadPermissionsFromDisk()
} }
else else
{ {
LOGWARN("Failed to read the users.ini file. The player will be added only to the Default group."); LOGWARN("Regenerating users.ini, player %s will be added to the \"Default\" group", m_PlayerName.c_str());
IniFile.AddHeaderComment(" This is the file in which the group the player belongs to is stored");
IniFile.AddHeaderComment(" The format is: [PlayerName] | Groups=GroupName");
IniFile.SetValue(m_PlayerName, "Groups", "Default");
IniFile.WriteFile("users.ini");
AddToGroup("Default"); AddToGroup("Default");
} }
ResolvePermissions(); ResolvePermissions();
@ -1410,7 +1415,7 @@ bool cPlayer::LoadFromDisk()
LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); LOGINFO("Player %s has permissions:", m_PlayerName.c_str() );
for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr ) for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr )
{ {
if( itr->second ) LOGINFO("%s", itr->first.c_str() ); if( itr->second ) LOG(" - %s", itr->first.c_str() );
} }
AString SourceFile; AString SourceFile;

View File

@ -6,13 +6,14 @@
// tolua_begin
class cTNTEntity : class cTNTEntity :
public cEntity public cEntity
{ {
typedef cEntity super; typedef cEntity super;
public: public:
// tolua_end
CLASS_PROTODEF(cTNTEntity); CLASS_PROTODEF(cTNTEntity);
cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec); cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec);
@ -22,10 +23,13 @@ public:
virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
double GetCounterTime(void) const { return m_Counter; } // tolua_export
double GetMaxFuseTime(void) const { return m_MaxFuseTime; } // tolua_export
protected: protected:
double m_Counter; ///< How much time has elapsed since the object was created, in seconds double m_Counter; ///< How much time has elapsed since the object was created, in seconds
double m_MaxFuseTime; ///< How long the fuse is, in seconds double m_MaxFuseTime; ///< How long the fuse is, in seconds
}; }; // tolua_export

View File

@ -47,8 +47,25 @@ cGroupManager::cGroupManager()
cIniFile IniFile; cIniFile IniFile;
if (!IniFile.ReadFile("groups.ini")) if (!IniFile.ReadFile("groups.ini"))
{ {
LOGWARNING("groups.ini inaccessible, no groups are defined"); LOGWARNING("Regenerating groups.ini, all groups will be reset");
return; IniFile.AddHeaderComment(" This is the MCServer permissions manager groups file");
IniFile.AddHeaderComment(" It stores all defined groups such as Administrators, Players, or Moderators");
IniFile.SetValue("Owner", "Permissions", "*", true);
IniFile.SetValue("Owner", "Color", "2", true);
IniFile.SetValue("Moderator", "Permissions", "core.time,core.item,core.teleport,core.ban,core.unban,core.save-all,core.toggledownfall");
IniFile.SetValue("Moderator", "Color", "2", true);
IniFile.SetValue("Moderator", "Inherits", "Player", true);
IniFile.SetValue("Player", "Permissions", "core.build", true);
IniFile.SetValue("Player", "Color", "f", true);
IniFile.SetValue("Player", "Inherits", "Default", true);
IniFile.SetValue("Default", "Permissions", "core.help,core.playerlist,core.pluginlist,core.spawn,core.listworlds,core.back,core.motd,core.gotoworld,core.coords,core.viewdistance", true);
IniFile.SetValue("Default", "Color", "f", true);
IniFile.WriteFile("groups.ini");
} }
unsigned int NumKeys = IniFile.GetNumKeys(); unsigned int NumKeys = IniFile.GetNumKeys();

View File

@ -274,6 +274,7 @@ void cMonster::KilledBy(cEntity * a_Killer)
case cMonster::mtWolf: case cMonster::mtWolf:
{ {
Reward = m_World->GetTickRandomNumber(2) + 1; Reward = m_World->GetTickRandomNumber(2) + 1;
break;
} }
// Monsters // Monsters
@ -291,25 +292,30 @@ void cMonster::KilledBy(cEntity * a_Killer)
case cMonster::mtMagmaCube: case cMonster::mtMagmaCube:
{ {
Reward = 6 + (m_World->GetTickRandomNumber(2)); Reward = 6 + (m_World->GetTickRandomNumber(2));
break;
} }
case cMonster::mtBlaze: case cMonster::mtBlaze:
{ {
Reward = 10; Reward = 10;
break;
} }
// Bosses // Bosses
case cMonster::mtEnderDragon: case cMonster::mtEnderDragon:
{ {
Reward = 12000; Reward = 12000;
break;
} }
case cMonster::mtWither: case cMonster::mtWither:
{ {
Reward = 50; Reward = 50;
break;
} }
default: default:
{ {
Reward = 0; Reward = 0;
break;
} }
} }
m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward); m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward);

View File

@ -29,23 +29,23 @@ Implements the 1.7.x protocol classes:
#define HANDLE_READ(Proc, Type, Var) \ #define HANDLE_READ(ByteBuf, Proc, Type, Var) \
Type Var; \ Type Var; \
m_ReceivedData.Proc(Var); ByteBuf.Proc(Var);
#define HANDLE_PACKET_READ(Proc, Type, Var) \ #define HANDLE_PACKET_READ(ByteBuf, Proc, Type, Var) \
Type Var; \ Type Var; \
{ \ { \
if (!m_ReceivedData.Proc(Var)) \ if (!ByteBuf.Proc(Var)) \
{ \ { \
m_ReceivedData.CheckValid(); \ ByteBuf.CheckValid(); \
return false; \ return false; \
} \ } \
m_ReceivedData.CheckValid(); \ ByteBuf.CheckValid(); \
} }
@ -921,6 +921,7 @@ void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property
void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
{ {
LOGD("Received %d bytes of data", a_Size);
if (!m_ReceivedData.Write(a_Data, a_Size)) if (!m_ReceivedData.Write(a_Data, a_Size))
{ {
// Too much data in the incoming queue, report to caller: // Too much data in the incoming queue, report to caller:
@ -932,6 +933,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
while (true) while (true)
{ {
UInt32 PacketLen; UInt32 PacketLen;
int PacketStart = m_ReceivedData.GetDataStart();
if (!m_ReceivedData.ReadVarInt(PacketLen)) if (!m_ReceivedData.ReadVarInt(PacketLen))
{ {
// Not enough data // Not enough data
@ -942,35 +944,38 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size)
// The full packet hasn't been received yet // The full packet hasn't been received yet
return; return;
} }
cByteBuffer bb(PacketLen + 1);
VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen));
m_ReceivedData.CommitRead();
// Write one NUL extra, so that we can detect over-reads
bb.Write("\0", 1);
UInt32 PacketType; UInt32 PacketType;
UInt32 Mark1 = m_ReceivedData.GetReadableSpace(); if (!bb.ReadVarInt(PacketType))
if (!m_ReceivedData.ReadVarInt(PacketType))
{ {
// Not enough data // Not enough data
return; return;
} }
UInt32 NumBytesRead = Mark1 - m_ReceivedData.GetReadableSpace(); // DEBUG:
HandlePacket(PacketType, PacketLen - NumBytesRead); LOGD("Packet 0x%x, len %d (0x%x), start at %d", PacketType, PacketLen, PacketLen, PacketStart);
if (Mark1 - m_ReceivedData.GetReadableSpace() > PacketLen) HandlePacket(bb, PacketType);
if (bb.GetReadableSpace() != 1)
{ {
// Read more than packet length, report as error // Read more or less than packet length, report as error
ASSERT(!"Read wrong number of bytes!");
m_Client->PacketError(PacketType); m_Client->PacketError(PacketType);
} }
// Go to packet end in any case:
m_ReceivedData.ResetRead();
m_ReceivedData.ReadVarInt(PacketType);
m_ReceivedData.SkipRead(PacketLen);
m_ReceivedData.CommitRead();
} // while (true) } // while (true)
} }
void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes) void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{ {
switch (m_State) switch (m_State)
{ {
@ -979,8 +984,8 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Status // Status
switch (a_PacketType) switch (a_PacketType)
{ {
case 0x00: HandlePacketStatusRequest(a_RemainingBytes); return; case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return;
case 0x01: HandlePacketStatusPing (a_RemainingBytes); return; case 0x01: HandlePacketStatusPing (a_ByteBuffer); return;
} }
break; break;
} }
@ -990,8 +995,8 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Login // Login
switch (a_PacketType) switch (a_PacketType)
{ {
case 0x00: HandlePacketLoginStart(a_RemainingBytes); return; case 0x00: HandlePacketLoginStart (a_ByteBuffer); return;
case 0x01: HandlePacketLoginEncryptionResponse(a_RemainingBytes); return; case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return;
} }
break; break;
} }
@ -1001,29 +1006,29 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Game // Game
switch (a_PacketType) switch (a_PacketType)
{ {
case 0x00: HandlePacketKeepAlive (a_RemainingBytes); return; case 0x00: HandlePacketKeepAlive (a_ByteBuffer); return;
case 0x01: HandlePacketChatMessage (a_RemainingBytes); return; case 0x01: HandlePacketChatMessage (a_ByteBuffer); return;
case 0x02: HandlePacketUseEntity (a_RemainingBytes); return; case 0x02: HandlePacketUseEntity (a_ByteBuffer); return;
case 0x03: HandlePacketPlayer (a_RemainingBytes); return; case 0x03: HandlePacketPlayer (a_ByteBuffer); return;
case 0x04: HandlePacketPlayerPos (a_RemainingBytes); return; case 0x04: HandlePacketPlayerPos (a_ByteBuffer); return;
case 0x05: HandlePacketPlayerLook (a_RemainingBytes); return; case 0x05: HandlePacketPlayerLook (a_ByteBuffer); return;
case 0x06: HandlePacketPlayerPosLook (a_RemainingBytes); return; case 0x06: HandlePacketPlayerPosLook (a_ByteBuffer); return;
case 0x07: HandlePacketBlockDig (a_RemainingBytes); return; case 0x07: HandlePacketBlockDig (a_ByteBuffer); return;
case 0x08: HandlePacketBlockPlace (a_RemainingBytes); return; case 0x08: HandlePacketBlockPlace (a_ByteBuffer); return;
case 0x09: HandlePacketSlotSelect (a_RemainingBytes); return; case 0x09: HandlePacketSlotSelect (a_ByteBuffer); return;
case 0x0a: HandlePacketAnimation (a_RemainingBytes); return; case 0x0a: HandlePacketAnimation (a_ByteBuffer); return;
case 0x0b: HandlePacketEntityAction (a_RemainingBytes); return; case 0x0b: HandlePacketEntityAction (a_ByteBuffer); return;
case 0x0c: HandlePacketSteerVehicle (a_RemainingBytes); return; case 0x0c: HandlePacketSteerVehicle (a_ByteBuffer); return;
case 0x0d: HandlePacketWindowClose (a_RemainingBytes); return; case 0x0d: HandlePacketWindowClose (a_ByteBuffer); return;
case 0x0e: HandlePacketWindowClick (a_RemainingBytes); return; case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return;
case 0x0f: // Confirm transaction - not used in MCS case 0x0f: // Confirm transaction - not used in MCS
case 0x10: HandlePacketCreativeInventoryAction(a_RemainingBytes); return; case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return;
case 0x12: HandlePacketUpdateSign (a_RemainingBytes); return; case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return;
case 0x13: HandlePacketPlayerAbilities (a_RemainingBytes); return; case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return;
case 0x14: HandlePacketTabComplete (a_RemainingBytes); return; case 0x14: HandlePacketTabComplete (a_ByteBuffer); return;
case 0x15: HandlePacketClientSettings (a_RemainingBytes); return; case 0x15: HandlePacketClientSettings (a_ByteBuffer); return;
case 0x16: HandlePacketClientStatus (a_RemainingBytes); return; case 0x16: HandlePacketClientStatus (a_ByteBuffer); return;
case 0x17: HandlePacketPluginMessage (a_RemainingBytes); return; case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return;
} }
break; break;
} }
@ -1031,27 +1036,16 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes)
// Unknown packet type, report to the client: // Unknown packet type, report to the client:
m_Client->PacketUnknown(a_PacketType); m_Client->PacketUnknown(a_PacketType);
m_ReceivedData.SkipRead(a_RemainingBytes);
m_ReceivedData.CommitRead();
} }
void cProtocol172::HandlePacketStatusPing(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer)
{ {
ASSERT(a_RemainingBytes == 8);
if (a_RemainingBytes != 8)
{
m_Client->PacketError(0x01);
m_ReceivedData.SkipRead(a_RemainingBytes);
m_ReceivedData.CommitRead();
return;
}
Int64 Timestamp; Int64 Timestamp;
m_ReceivedData.ReadBEInt64(Timestamp); a_ByteBuffer.ReadBEInt64(Timestamp);
m_ReceivedData.CommitRead();
cPacketizer Pkt(*this, 0x01); // Ping packet cPacketizer Pkt(*this, 0x01); // Ping packet
Pkt.WriteInt64(Timestamp); Pkt.WriteInt64(Timestamp);
@ -1061,12 +1055,8 @@ void cProtocol172::HandlePacketStatusPing(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketStatusRequest(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
{ {
// No more bytes in this packet
ASSERT(a_RemainingBytes == 0);
m_ReceivedData.CommitRead();
// Send the response: // Send the response:
AString Response = "{\"version\":{\"name\":\"1.7.2\",\"protocol\":4},\"players\":{"; AString Response = "{\"version\":{\"name\":\"1.7.2\",\"protocol\":4},\"players\":{";
AppendPrintf(Response, "\"max\":%u,\"online\":%u,\"sample\":[]},", AppendPrintf(Response, "\"max\":%u,\"online\":%u,\"sample\":[]},",
@ -1086,7 +1076,7 @@ void cProtocol172::HandlePacketStatusRequest(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer)
{ {
// TODO: Add protocol encryption // TODO: Add protocol encryption
} }
@ -1095,10 +1085,10 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketLoginStart(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
{ {
AString Username; AString Username;
m_ReceivedData.ReadVarUTF8String(Username); a_ByteBuffer.ReadVarUTF8String(Username);
// TODO: Protocol encryption should be set up here if not localhost / auth // TODO: Protocol encryption should be set up here if not localhost / auth
@ -1117,10 +1107,10 @@ void cProtocol172::HandlePacketLoginStart(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketAnimation(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketAnimation(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEInt, int, EntityID); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID);
HANDLE_READ(ReadByte, Byte, Animation); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Animation);
m_Client->HandleAnimation(Animation); m_Client->HandleAnimation(Animation);
} }
@ -1128,13 +1118,13 @@ void cProtocol172::HandlePacketAnimation(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketBlockDig(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadByte, Byte, Status); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status);
HANDLE_READ(ReadBEInt, int, BlockX); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
HANDLE_READ(ReadByte, Byte, BlockY); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, BlockY);
HANDLE_READ(ReadBEInt, int, BlockZ); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
HANDLE_READ(ReadByte, Byte, Face); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face);
m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, Face, Status); m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, Face, Status);
} }
@ -1142,18 +1132,18 @@ void cProtocol172::HandlePacketBlockDig(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketBlockPlace(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEInt, int, BlockX); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
HANDLE_READ(ReadByte, Byte, BlockY); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, BlockY);
HANDLE_READ(ReadBEInt, int, BlockZ); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
HANDLE_READ(ReadByte, Byte, Face); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face);
cItem Item; cItem Item;
ReadItem(Item); ReadItem(a_ByteBuffer, Item);
HANDLE_READ(ReadByte, Byte, CursorX); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX);
HANDLE_READ(ReadByte, Byte, CursorY); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY);
HANDLE_READ(ReadByte, Byte, CursorZ); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorZ);
m_Client->HandleRightClick(BlockX, BlockY, BlockZ, Face, CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem()); m_Client->HandleRightClick(BlockX, BlockY, BlockZ, Face, CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem());
} }
@ -1161,9 +1151,9 @@ void cProtocol172::HandlePacketBlockPlace(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketChatMessage(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketChatMessage(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadVarUTF8String, AString, Message); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Message);
m_Client->HandleChat(Message); m_Client->HandleChat(Message);
} }
@ -1171,14 +1161,14 @@ void cProtocol172::HandlePacketChatMessage(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketClientSettings(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadVarUTF8String, AString, Locale); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale);
HANDLE_READ(ReadByte, Byte, ViewDistance); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance);
HANDLE_READ(ReadByte, Byte, ChatFlags); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags);
HANDLE_READ(ReadByte, Byte, Unused); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatColors);
HANDLE_READ(ReadByte, Byte, Difficulty); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Difficulty);
HANDLE_READ(ReadByte, Byte, ShowCape); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape);
// TODO: handle in m_Client // TODO: handle in m_Client
} }
@ -1186,9 +1176,9 @@ void cProtocol172::HandlePacketClientSettings(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketClientStatus(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadByte, Byte, ActionID); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ActionID);
switch (ActionID) switch (ActionID)
{ {
case 0: case 0:
@ -1216,11 +1206,11 @@ void cProtocol172::HandlePacketClientStatus(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketCreativeInventoryAction(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEShort, short, SlotNum); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum);
cItem Item; cItem Item;
if (!ReadItem(Item)) if (!ReadItem(a_ByteBuffer, Item))
{ {
return; return;
} }
@ -1231,11 +1221,11 @@ void cProtocol172::HandlePacketCreativeInventoryAction(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketEntityAction(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEInt, int, PlayerID); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, PlayerID);
HANDLE_READ(ReadByte, Byte, Action); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Action);
HANDLE_READ(ReadBEInt, int, JumpBoost); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, JumpBoost);
m_Client->HandleEntityAction(PlayerID, Action); m_Client->HandleEntityAction(PlayerID, Action);
} }
@ -1243,9 +1233,9 @@ void cProtocol172::HandlePacketEntityAction(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketKeepAlive(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEInt, int, KeepAliveID); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, KeepAliveID);
m_Client->HandleKeepAlive(KeepAliveID); m_Client->HandleKeepAlive(KeepAliveID);
} }
@ -1253,9 +1243,9 @@ void cProtocol172::HandlePacketKeepAlive(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayer(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketPlayer(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBool, bool, IsOnGround); HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
// TODO: m_Client->HandlePlayerOnGround(IsOnGround); // TODO: m_Client->HandlePlayerOnGround(IsOnGround);
} }
@ -1263,11 +1253,11 @@ void cProtocol172::HandlePacketPlayer(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerAbilities(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadByte, Byte, Flags); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Flags);
HANDLE_READ(ReadBEFloat, float, FlyingSpeed); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed);
HANDLE_READ(ReadBEFloat, float, WalkingSpeed); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed);
// TODO: m_Client->HandlePlayerAbilities(); // TODO: m_Client->HandlePlayerAbilities();
} }
@ -1275,11 +1265,11 @@ void cProtocol172::HandlePacketPlayerAbilities(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerLook(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketPlayerLook(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEFloat, float, Yaw); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
HANDLE_READ(ReadBEFloat, float, Pitch); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
HANDLE_READ(ReadBool, bool, IsOnGround); HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerLook(Yaw, Pitch, IsOnGround); m_Client->HandlePlayerLook(Yaw, Pitch, IsOnGround);
} }
@ -1287,13 +1277,13 @@ void cProtocol172::HandlePacketPlayerLook(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerPos(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEDouble, double, PosX); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX);
HANDLE_READ(ReadBEDouble, double, PosY); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
HANDLE_READ(ReadBEDouble, double, Stance); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, Stance);
HANDLE_READ(ReadBEDouble, double, PosZ); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
HANDLE_READ(ReadBool, bool, IsOnGround); HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerPos(PosX, PosY, PosZ, Stance, IsOnGround); m_Client->HandlePlayerPos(PosX, PosY, PosZ, Stance, IsOnGround);
} }
@ -1301,15 +1291,15 @@ void cProtocol172::HandlePacketPlayerPos(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPlayerPosLook(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEDouble, double, PosX); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX);
HANDLE_READ(ReadBEDouble, double, PosY); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
HANDLE_READ(ReadBEDouble, double, Stance); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, Stance);
HANDLE_READ(ReadBEDouble, double, PosZ); HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
HANDLE_READ(ReadBEFloat, float, Yaw); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
HANDLE_READ(ReadBEFloat, float, Pitch); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
HANDLE_READ(ReadBool, bool, IsOnGround); HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Stance, Yaw, Pitch, IsOnGround); m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Stance, Yaw, Pitch, IsOnGround);
} }
@ -1317,12 +1307,12 @@ void cProtocol172::HandlePacketPlayerPosLook(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketPluginMessage(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadVarUTF8String, AString, Channel); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
HANDLE_READ(ReadBEShort, short, Length); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length);
AString Data; AString Data;
m_ReceivedData.ReadString(Data, Length); a_ByteBuffer.ReadString(Data, Length);
// TODO: m_Client->HandlePluginMessage(Channel, Data); // TODO: m_Client->HandlePluginMessage(Channel, Data);
} }
@ -1330,9 +1320,9 @@ void cProtocol172::HandlePacketPluginMessage(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketSlotSelect(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEShort, short, SlotNum); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum);
m_Client->HandleSlotSelected(SlotNum); m_Client->HandleSlotSelected(SlotNum);
} }
@ -1340,12 +1330,12 @@ void cProtocol172::HandlePacketSlotSelect(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketSteerVehicle(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEFloat, float, Forward); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward);
HANDLE_READ(ReadBEFloat, float, Sideways); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways);
HANDLE_READ(ReadBool, bool, ShouldJump); HANDLE_READ(a_ByteBuffer, ReadBool, bool, ShouldJump);
HANDLE_READ(ReadBool, bool, ShouldUnmount); HANDLE_READ(a_ByteBuffer, ReadBool, bool, ShouldUnmount);
if (ShouldUnmount) if (ShouldUnmount)
{ {
m_Client->HandleUnmount(); m_Client->HandleUnmount();
@ -1360,9 +1350,9 @@ void cProtocol172::HandlePacketSteerVehicle(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketTabComplete(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadVarUTF8String, AString, Text); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Text);
m_Client->HandleTabCompletion(Text); m_Client->HandleTabCompletion(Text);
} }
@ -1370,15 +1360,15 @@ void cProtocol172::HandlePacketTabComplete(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketUpdateSign(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEInt, int, BlockX); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
HANDLE_READ(ReadBEShort, short, BlockY); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, BlockY);
HANDLE_READ(ReadBEInt, int, BlockZ); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
HANDLE_READ(ReadVarUTF8String, AString, Line1); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line1);
HANDLE_READ(ReadVarUTF8String, AString, Line2); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line2);
HANDLE_READ(ReadVarUTF8String, AString, Line3); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line3);
HANDLE_READ(ReadVarUTF8String, AString, Line4); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line4);
m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4); m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
} }
@ -1386,10 +1376,10 @@ void cProtocol172::HandlePacketUpdateSign(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketUseEntity(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadBEInt, int, EntityID); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID);
HANDLE_READ(ReadByte, Byte, MouseButton); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, MouseButton);
m_Client->HandleUseEntity(EntityID, (MouseButton == 1)); m_Client->HandleUseEntity(EntityID, (MouseButton == 1));
} }
@ -1397,15 +1387,15 @@ void cProtocol172::HandlePacketUseEntity(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketWindowClick(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadChar, char, WindowID); HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID);
HANDLE_READ(ReadBEShort, short, SlotNum); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum);
HANDLE_READ(ReadByte, Byte, Button); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Button);
HANDLE_READ(ReadBEShort, short, TransactionID); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, TransactionID);
HANDLE_READ(ReadByte, Byte, Mode); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode);
cItem Item; cItem Item;
ReadItem(Item); ReadItem(a_ByteBuffer, Item);
// Convert Button, Mode, SlotNum and HeldItem into eClickAction: // Convert Button, Mode, SlotNum and HeldItem into eClickAction:
eClickAction Action; eClickAction Action;
@ -1434,6 +1424,12 @@ void cProtocol172::HandlePacketWindowClick(UInt32 a_RemainingBytes)
case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break; case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break;
case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; break; case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; break;
case 0x0600: Action = caDblClick; break; case 0x0600: Action = caDblClick; break;
default:
{
LOGWARNING("Unhandled window click mode / button combination: %d (0x%x)", (Mode << 8) | Button, (Mode << 8) | Button);
Action = caUnknown;
break;
}
} }
m_Client->HandleWindowClick(WindowID, SlotNum, Action, Item); m_Client->HandleWindowClick(WindowID, SlotNum, Action, Item);
@ -1443,9 +1439,9 @@ void cProtocol172::HandlePacketWindowClick(UInt32 a_RemainingBytes)
void cProtocol172::HandlePacketWindowClose(UInt32 a_RemainingBytes) void cProtocol172::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(ReadChar, char, WindowID); HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID);
m_Client->HandleWindowClose(WindowID); m_Client->HandleWindowClose(WindowID);
} }
@ -1492,9 +1488,9 @@ void cProtocol172::SendData(const char * a_Data, int a_Size)
bool cProtocol172::ReadItem(cItem & a_Item) bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item)
{ {
HANDLE_PACKET_READ(ReadBEShort, short, ItemType); HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType);
if (ItemType == -1) if (ItemType == -1)
{ {
// The item is empty, no more data follows // The item is empty, no more data follows
@ -1503,8 +1499,8 @@ bool cProtocol172::ReadItem(cItem & a_Item)
} }
a_Item.m_ItemType = ItemType; a_Item.m_ItemType = ItemType;
HANDLE_PACKET_READ(ReadChar, char, ItemCount); HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, ItemCount);
HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage); HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemDamage);
a_Item.m_ItemCount = ItemCount; a_Item.m_ItemCount = ItemCount;
a_Item.m_ItemDamage = ItemDamage; a_Item.m_ItemDamage = ItemDamage;
if (ItemCount <= 0) if (ItemCount <= 0)
@ -1512,7 +1508,7 @@ bool cProtocol172::ReadItem(cItem & a_Item)
a_Item.Empty(); a_Item.Empty();
} }
HANDLE_PACKET_READ(ReadBEShort, short, MetadataLength); HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, MetadataLength);
if (MetadataLength <= 0) if (MetadataLength <= 0)
{ {
return true; return true;
@ -1520,7 +1516,7 @@ bool cProtocol172::ReadItem(cItem & a_Item)
// Read the metadata // Read the metadata
AString Metadata; AString Metadata;
if (!m_ReceivedData.ReadString(Metadata, MetadataLength)) if (!a_ByteBuffer.ReadString(Metadata, MetadataLength))
{ {
return false; return false;
} }

View File

@ -205,39 +205,39 @@ protected:
void AddReceivedData(const char * a_Data, int a_Size); void AddReceivedData(const char * a_Data, int a_Size);
/// Reads and handles the packet. The packet length and type have already been read. /// Reads and handles the packet. The packet length and type have already been read.
void HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes); void HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType);
// Packet handlers while in the Status state (m_State == 1): // Packet handlers while in the Status state (m_State == 1):
void HandlePacketStatusPing (UInt32 a_RemainingBytes); void HandlePacketStatusPing (cByteBuffer & a_ByteBuffer);
void HandlePacketStatusRequest(UInt32 a_RemainingBytes); void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer);
// Packet handlers while in the Login state (m_State == 2): // Packet handlers while in the Login state (m_State == 2):
void HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes); void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer);
void HandlePacketLoginStart (UInt32 a_RemainingBytes); void HandlePacketLoginStart (cByteBuffer & a_ByteBuffer);
// Packet handlers while in the Game state (m_State == 3): // Packet handlers while in the Game state (m_State == 3):
void HandlePacketAnimation (UInt32 a_RemainingBytes); void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
void HandlePacketBlockDig (UInt32 a_RemainingBytes); void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer);
void HandlePacketBlockPlace (UInt32 a_RemainingBytes); void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
void HandlePacketChatMessage (UInt32 a_RemainingBytes); void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketClientSettings (UInt32 a_RemainingBytes); void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer);
void HandlePacketClientStatus (UInt32 a_RemainingBytes); void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer);
void HandlePacketCreativeInventoryAction(UInt32 a_RemainingBytes); void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer);
void HandlePacketEntityAction (UInt32 a_RemainingBytes); void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer);
void HandlePacketKeepAlive (UInt32 a_RemainingBytes); void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayer (UInt32 a_RemainingBytes); void HandlePacketPlayer (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerAbilities (UInt32 a_RemainingBytes); void HandlePacketPlayerAbilities (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerLook (UInt32 a_RemainingBytes); void HandlePacketPlayerLook (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerPos (UInt32 a_RemainingBytes); void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerPosLook (UInt32 a_RemainingBytes); void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer);
void HandlePacketPluginMessage (UInt32 a_RemainingBytes); void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketSlotSelect (UInt32 a_RemainingBytes); void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer);
void HandlePacketSteerVehicle (UInt32 a_RemainingBytes); void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer);
void HandlePacketTabComplete (UInt32 a_RemainingBytes); void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer);
void HandlePacketUpdateSign (UInt32 a_RemainingBytes); void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer);
void HandlePacketUseEntity (UInt32 a_RemainingBytes); void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClick (UInt32 a_RemainingBytes); void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (UInt32 a_RemainingBytes); void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
/// Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. /// Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here.
@ -249,7 +249,7 @@ protected:
void SendCompass(const cWorld & a_World); void SendCompass(const cWorld & a_World);
/// Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data /// Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data
bool ReadItem(cItem & a_Item); bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item);
/// Parses item metadata as read by ReadItem(), into the item enchantments. /// Parses item metadata as read by ReadItem(), into the item enchantments.
void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);

View File

@ -299,12 +299,31 @@ void cRoot::LoadWorlds(cIniFile & IniFile)
cWorld * cRoot::CreateAndInitializeWorld(const AString & a_WorldName)
{
if (m_WorldsByName[a_WorldName] != NULL)
{
return NULL;
}
cWorld* NewWorld = new cWorld(a_WorldName.c_str());
m_WorldsByName[a_WorldName] = NewWorld;
NewWorld->Start();
NewWorld->InitializeSpawn();
m_PluginManager->CallHookWorldStarted(*NewWorld);
return NewWorld;
}
void cRoot::StartWorlds(void) void cRoot::StartWorlds(void)
{ {
for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr)
{ {
itr->second->Start(); itr->second->Start();
itr->second->InitializeSpawn(); itr->second->InitializeSpawn();
m_PluginManager->CallHookWorldStarted(*itr->second);
} }
} }

View File

@ -42,6 +42,7 @@ public:
cServer * GetServer(void) { return m_Server; } // tolua_export cServer * GetServer(void) { return m_Server; } // tolua_export
cWorld * GetDefaultWorld(void); // tolua_export cWorld * GetDefaultWorld(void); // tolua_export
cWorld * GetWorld(const AString & a_WorldName); // tolua_export cWorld * GetWorld(const AString & a_WorldName); // tolua_export
cWorld * CreateAndInitializeWorld(const AString & a_WorldName); // tolua_export
/// Calls the callback for each world; returns true if the callback didn't abort (return true) /// Calls the callback for each world; returns true if the callback didn't abort (return true)
bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings << bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings <<

View File

@ -50,7 +50,7 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu
// Check for duplicates: // Check for duplicates:
cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData(); cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData();
for (cRedstoneSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr) for (cRedstoneSimulatorChunkData::const_iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr)
{ {
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
{ {
@ -79,22 +79,20 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
// Check to see if PoweredBlocks have invalid items (source is air or unpowered) // Check to see if PoweredBlocks have invalid items (source is air or unpowered)
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();)
{ {
sPoweredBlocks & Change = *itr; int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
BLOCKTYPE SourceBlockType; BLOCKTYPE SourceBlockType;
NIBBLETYPE SourceBlockMeta; NIBBLETYPE SourceBlockMeta;
if (!a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta)) if (!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta))
{ {
continue; continue;
} }
if (SourceBlockType != Change.a_SourceBlock) if (SourceBlockType != itr->a_SourceBlock)
{ {
itr = m_PoweredBlocks.erase(itr); itr = m_PoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock).c_str()); LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
} }
else if ( else if (
// Changeable sources // Changeable sources
@ -105,7 +103,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
) )
{ {
itr = m_PoweredBlocks.erase(itr); itr = m_PoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock).c_str()); LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
} }
else else
{ {
@ -116,33 +114,31 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
// Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed // Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();) for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();)
{ {
sLinkedPoweredBlocks & Change = *itr; int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width;
int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; int MidRelX = itr->a_MiddlePos.x - a_ChunkX * cChunkDef::Width;
int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; int MidRelZ = itr->a_MiddlePos.z - a_ChunkZ * cChunkDef::Width;
int MidRelX = Change.a_MiddlePos.x - a_ChunkX * cChunkDef::Width;
int MidRelZ = Change.a_MiddlePos.z - a_ChunkZ * cChunkDef::Width;
BLOCKTYPE SourceBlockType; BLOCKTYPE SourceBlockType;
NIBBLETYPE SourceBlockMeta; NIBBLETYPE SourceBlockMeta;
BLOCKTYPE MiddleBlockType; BLOCKTYPE MiddleBlockType;
if ( if (
!a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || !a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) ||
!a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType) !a_Chunk->UnboundedRelGetBlockType(MidRelX, itr->a_MiddlePos.y, MidRelZ, MiddleBlockType)
) )
{ {
continue; continue;
} }
if (SourceBlockType != Change.a_SourceBlock) if (SourceBlockType != itr->a_SourceBlock)
{ {
itr = m_LinkedPoweredBlocks.erase(itr); itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock).c_str()); LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
} }
else if (MiddleBlockType != Change.a_MiddleBlock) else if (MiddleBlockType != itr->a_MiddleBlock)
{ {
itr = m_LinkedPoweredBlocks.erase(itr); itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(Change.a_SourceBlock).c_str()); LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
} }
else if ( else if (
// Things that can send power through a block but which depends on meta // Things that can send power through a block but which depends on meta
@ -152,7 +148,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
) )
{ {
itr = m_LinkedPoweredBlocks.erase(itr); itr = m_LinkedPoweredBlocks.erase(itr);
LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock).c_str()); LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str());
} }
else else
{ {
@ -162,19 +158,17 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end();) for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end();)
{ {
sSimulatedPlayerToggleableList & Change = *itr; int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width;
int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
int RelX = Change.a_BlockPos.x - a_ChunkX * cChunkDef::Width;
int RelZ = Change.a_BlockPos.z - a_ChunkZ * cChunkDef::Width;
BLOCKTYPE SourceBlockType; BLOCKTYPE SourceBlockType;
if (!a_Chunk->UnboundedRelGetBlockType(RelX, Change.a_BlockPos.y, RelZ, SourceBlockType)) if (!a_Chunk->UnboundedRelGetBlockType(RelX, itr->a_BlockPos.y, RelZ, SourceBlockType))
{ {
continue; continue;
} }
else if (!IsAllowedBlock(SourceBlockType)) else if (!IsAllowedBlock(SourceBlockType))
{ {
LOGD("cRedstoneSimulator: Erased block %s from toggleable simulated list due to power state change", ItemToFullString(SourceBlockType).c_str()); LOGD("cRedstoneSimulator: Erased block %s from toggleable simulated list as block is no longer redstone", ItemToFullString(SourceBlockType).c_str());
itr = m_SimulatedPlayerToggleableBlocks.erase(itr); itr = m_SimulatedPlayerToggleableBlocks.erase(itr);
} }
else else
@ -282,7 +276,7 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B
int X = a_BlockX; int Y = a_BlockY; int Z = a_BlockZ; int X = a_BlockX; int Y = a_BlockY; int Z = a_BlockZ;
AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on
if (AreCoordsPowered(X, Y, Z)) if (AreCoordsDirectlyPowered(X, Y, Z))
{ {
// There was a match, torch goes off // There was a match, torch goes off
m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ));
@ -329,7 +323,7 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B
AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on
// See if off state torch can be turned on again // See if off state torch can be turned on again
if (AreCoordsPowered(X, Y, Z)) if (AreCoordsDirectlyPowered(X, Y, Z))
{ {
return; // Something matches, torch still powered return; // Something matches, torch still powered
} }
@ -416,7 +410,6 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
{ {
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); // Power block beneath
} }
else else
{ {
@ -464,10 +457,12 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl
{ {
m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MetaToSet); m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, MetaToSet);
} }
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); // Power block beneath
} }
// Wire still powered, power blocks beneath
SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE);
SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE);
if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire
{ {
switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ)) switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ))
@ -630,7 +625,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int
// Self not in list, add self to list // Self not in list, add self to list
sRepeatersDelayList RC; sRepeatersDelayList RC;
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2); // Repeaters power off slower than they power on, so no +1. Why? No idea.
RC.a_ElapsedTicks = 0; RC.a_ElapsedTicks = 0;
m_RepeatersDelayList.push_back(RC); m_RepeatersDelayList.push_back(RC);
return; return;
@ -826,23 +821,27 @@ void cRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ
bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) bool cRedstoneSimulator::AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
{ {
sPoweredBlocks & Change = *itr; if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{ {
return true; return true;
} }
} }
return false;
}
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
bool cRedstoneSimulator::AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
sLinkedPoweredBlocks & Change = *itr; for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
{
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{ {
return true; return true;
} }
@ -858,64 +857,60 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo
{ {
// Repeaters cannot be powered by any face except their back; verify that this is true for a source // Repeaters cannot be powered by any face except their back; verify that this is true for a source
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
{ {
sPoweredBlocks & Change = *itr; if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
switch (a_Meta) switch (a_Meta)
{ {
case 0x0: case 0x0:
{ {
// Flip the coords to check the back of the repeater // Flip the coords to check the back of the repeater
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; } if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
break; break;
} }
case 0x1: case 0x1:
{ {
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; } if (itr->a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
break; break;
} }
case 0x2: case 0x2:
{ {
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; } if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
break; break;
} }
case 0x3: case 0x3:
{ {
if (Change.a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; } if (itr->a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
break; break;
} }
} }
} }
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
{ {
sLinkedPoweredBlocks & Change = *itr; if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
switch (a_Meta) switch (a_Meta)
{ {
case 0x0: case 0x0:
{ {
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; } if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
break; break;
} }
case 0x1: case 0x1:
{ {
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; } if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
break; break;
} }
case 0x2: case 0x2:
{ {
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; } if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
break; break;
} }
case 0x3: case 0x3:
{ {
if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; } if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
break; break;
} }
} }
@ -932,15 +927,13 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block
int OldX = a_BlockX, OldY = a_BlockY, OldZ = a_BlockZ; int OldX = a_BlockX, OldY = a_BlockY, OldZ = a_BlockZ;
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
{ {
sPoweredBlocks & Change = *itr; if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta); // Piston meta is based on what direction they face, so we can do this AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta); // Piston meta is based on what direction they face, so we can do this
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{ {
return true; return true;
} }
@ -950,15 +943,13 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block
a_BlockZ = OldZ; a_BlockZ = OldZ;
} }
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
{ {
sLinkedPoweredBlocks & Change = *itr; if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_Meta);
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) if (!itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{ {
return true; return true;
} }
@ -976,13 +967,11 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block
bool cRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered) bool cRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered)
{ {
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr) for (SimulatedPlayerToggleableList::const_iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr)
{ {
sSimulatedPlayerToggleableList & Change = *itr; if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{ {
if (Change.WasLastStatePowered != IsCurrentStatePowered) // Was the last power state different to the current? if (itr->WasLastStatePowered != IsCurrentStatePowered) // Was the last power state different to the current?
{ {
return false; // It was, coordinates are no longer simulated return false; // It was, coordinates are no longer simulated
} }
@ -1007,222 +996,72 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i
{ {
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ); BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE) // Wires can't power another wire through a block
{
if (m_World.GetBlock(a_BlockX - 2, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break; break;
} }
case BLOCK_FACE_XP: case BLOCK_FACE_XP:
{ {
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ); BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX + 2, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break; break;
} }
case BLOCK_FACE_YM: case BLOCK_FACE_YM:
{ {
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break; break;
} }
case BLOCK_FACE_YP: case BLOCK_FACE_YP:
{ {
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY + 2, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break; break;
} }
case BLOCK_FACE_ZM: case BLOCK_FACE_ZM:
{ {
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1); BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 2) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break; break;
} }
case BLOCK_FACE_ZP: case BLOCK_FACE_ZP:
{ {
BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1); BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1);
if (a_SourceType == E_BLOCK_REDSTONE_WIRE)
{
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 2) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE)
{
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
}
else
{
SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock);
}
break; break;
} }
default: default:
@ -1270,13 +1109,11 @@ void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_Block
return; return;
} }
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list
{ {
sPoweredBlocks & Change = *itr;
if ( if (
Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) && itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
Change.a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
) )
{ {
// Check for duplicates // Check for duplicates
@ -1302,24 +1139,28 @@ void cRedstoneSimulator::SetBlockLinkedPowered(
BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddleBlock BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddleBlock
) )
{ {
if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) BLOCKTYPE DestBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ);
if (DestBlock == E_BLOCK_AIR)
{ {
// Don't set air, fixes some bugs (wires powering themselves) // Don't set air, fixes some bugs (wires powering themselves)
return; return;
} }
if (!IsViableMiddleBlock(m_World.GetBlock(a_MiddleX, a_MiddleY, a_MiddleZ))) if (!IsViableMiddleBlock(a_MiddleBlock))
{ {
return; return;
} }
if ((a_SourceBlock == E_BLOCK_REDSTONE_WIRE) && (DestBlock == E_BLOCK_REDSTONE_WIRE))
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
{ {
sLinkedPoweredBlocks & Change = *itr; // Wires cannot power another wire through a block
return;
}
for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list
{
if ( if (
Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) && itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) &&
Change.a_MiddlePos.Equals(Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ)) && itr->a_MiddlePos.Equals(Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ)) &&
Change.a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ))
) )
{ {
// Check for duplicates // Check for duplicates
@ -1344,15 +1185,16 @@ void cRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a
{ {
for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr) for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr)
{ {
sSimulatedPlayerToggleableList & Change = *itr; if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)))
{
continue;
}
if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) if (itr->WasLastStatePowered != WasLastStatePowered)
{ {
if (Change.WasLastStatePowered != WasLastStatePowered) // If power states different, update listing
{ itr->WasLastStatePowered = WasLastStatePowered;
// If power states different, erase the old listing in preparation to add new one return;
m_SimulatedPlayerToggleableBlocks.erase(itr);
break;
} }
else else
{ {
@ -1360,8 +1202,8 @@ void cRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a
return; return;
} }
} }
}
// We have arrive here; no block must be in list - add one
sSimulatedPlayerToggleableList RC; sSimulatedPlayerToggleableList RC;
RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ);
RC.WasLastStatePowered = WasLastStatePowered; RC.WasLastStatePowered = WasLastStatePowered;

View File

@ -127,7 +127,11 @@ private:
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock); void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock);
/// <summary>Returns if a coordinate is powered or linked powered</summary> /// <summary>Returns if a coordinate is powered or linked powered</summary>
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); 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); }
/// <summary>Returns if a coordinate is in the directly powered blocks list</summary>
bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
/// <summary>Returns if a coordinate is in the indirectly powered blocks list</summary>
bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
/// <summary>Returns if a coordinate was marked as simulated (for blocks toggleable by players)</summary> /// <summary>Returns if a coordinate was marked as simulated (for blocks toggleable by players)</summary>
bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered); bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
/// <summary>Returns if a repeater is powered</summary> /// <summary>Returns if a repeater is powered</summary>
@ -150,6 +154,9 @@ private:
switch (Block) switch (Block)
{ {
// Add SOLID but not viable middle blocks here // Add SOLID but not viable middle blocks here
case E_BLOCK_PISTON:
case E_BLOCK_PISTON_EXTENSION:
case E_BLOCK_STICKY_PISTON:
case E_BLOCK_REDSTONE_REPEATER_ON: case E_BLOCK_REDSTONE_REPEATER_ON:
case E_BLOCK_REDSTONE_REPEATER_OFF: case E_BLOCK_REDSTONE_REPEATER_OFF:
{ {

View File

@ -392,6 +392,7 @@ public:
inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; } inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; }
inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; } inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; }
inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; }
/// Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true /// Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true
bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp