diff --git a/GNUmakefile b/GNUmakefile index c8cdd35e1..d729268e7 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -88,7 +88,7 @@ CXX_OPTIONS += -Wall ################################################### # 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 CXX_OPTIONS += -DCRYPTOPP_DISABLE_ASM endif diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 75d5c011f..b7dddec05 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1862,6 +1862,17 @@ end }, }, -- 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 = { Desc = [[ diff --git a/MCServer/Plugins/APIDump/Hooks/OnWorldStarted.lua b/MCServer/Plugins/APIDump/Hooks/OnWorldStarted.lua new file mode 100644 index 000000000..61e3de86e --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnWorldStarted.lua @@ -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 +} + + + + + diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index ede668bc7..351aff7ef 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit ede668bc7c310af49ad7354c00d3f11adbae792a +Subproject commit 351aff7efa94ce3c7ba733d5f83013e8a3fdfbfd diff --git a/MCServer/banned.example.ini b/MCServer/banned.example.ini deleted file mode 100644 index ceb71fe0b..000000000 --- a/MCServer/banned.example.ini +++ /dev/null @@ -1,3 +0,0 @@ -[Banned] -;PlayerName=1 - diff --git a/MCServer/groups.example.ini b/MCServer/groups.example.ini deleted file mode 100644 index 2e4b5ebee..000000000 --- a/MCServer/groups.example.ini +++ /dev/null @@ -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 diff --git a/MCServer/users.example.ini b/MCServer/users.example.ini deleted file mode 100644 index 6726c0bf8..000000000 --- a/MCServer/users.example.ini +++ /dev/null @@ -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 \ No newline at end of file diff --git a/MCServer/whitelist.example.ini b/MCServer/whitelist.example.ini deleted file mode 100644 index a89c148c9..000000000 --- a/MCServer/whitelist.example.ini +++ /dev/null @@ -1,6 +0,0 @@ -[WhiteListSettings] -WhiteListOn=0 - -[WhiteList] -;PlayerName=1 - diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 2a70efedf..6db7b2b0e 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -36,6 +36,7 @@ $cfile "../Entities/Pawn.h" $cfile "../Entities/Player.h" $cfile "../Entities/Pickup.h" $cfile "../Entities/ProjectileEntity.h" +$cfile "../Entities/TNTEntity.h" $cfile "../Server.h" $cfile "../World.h" $cfile "../Inventory.h" diff --git a/src/Bindings/Bindings.cpp b/src/Bindings/Bindings.cpp index c3607af5d..090d8047a 100644 --- a/src/Bindings/Bindings.cpp +++ b/src/Bindings/Bindings.cpp @@ -1,6 +1,6 @@ /* ** 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 @@ -34,6 +34,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "../Entities/Player.h" #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" +#include "../Entities/TNTEntity.h" #include "../Server.h" #include "../World.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,"cHTTPServer::cCallbacks"); tolua_usertype(tolua_S,"cLuaWindow"); - tolua_usertype(tolua_S,"cServer"); + tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cHopperEntity"); tolua_usertype(tolua_S,"std::vector"); 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,"cBlockArea"); tolua_usertype(tolua_S,"cGroup"); - tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"cTracer"); + tolua_usertype(tolua_S,"cItem"); + tolua_usertype(tolua_S,"cBoundingBox"); tolua_usertype(tolua_S,"cArrowEntity"); tolua_usertype(tolua_S,"cDropSpenserEntity"); - tolua_usertype(tolua_S,"cBoundingBox"); tolua_usertype(tolua_S,"cCuboid"); tolua_usertype(tolua_S,"Vector3i"); - tolua_usertype(tolua_S,"cNoteEntity"); tolua_usertype(tolua_S,"Vector3d"); + tolua_usertype(tolua_S,"cNoteEntity"); + tolua_usertype(tolua_S,"cServer"); tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cCriticalSection"); 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,"cProjectileEntity"); tolua_usertype(tolua_S,"cItemGrid::cListener"); - tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cPlayer"); + tolua_usertype(tolua_S,"cTNTEntity"); } /* method: new of class cIniFile */ @@ -11518,6 +11520,70 @@ static int tolua_AllToLua_cArrowEntity_SetIsCritical00(lua_State* tolua_S) } #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 */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cServer_GetDescription00 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 +/* 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 */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cRoot_GetPrimaryServerVersion00 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_WEATHER_CHANGED",cPluginManager::HOOK_WEATHER_CHANGED); 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_NUM_HOOKS",cPluginManager::HOOK_NUM_HOOKS); 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_beginmodule(tolua_S,"cFireChargeEntity"); 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_beginmodule(tolua_S,"cServer"); 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,"GetDefaultWorld",tolua_AllToLua_cRoot_GetDefaultWorld00); 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,"SetPrimaryServerVersion",tolua_AllToLua_cRoot_SetPrimaryServerVersion00); tolua_function(tolua_S,"GetGroupManager",tolua_AllToLua_cRoot_GetGroupManager00); diff --git a/src/Bindings/Bindings.h b/src/Bindings/Bindings.h index 88367e71f..73cf3c7d8 100644 --- a/src/Bindings/Bindings.h +++ b/src/Bindings/Bindings.h @@ -1,6 +1,6 @@ /* ** 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 */ diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 50a89018d..5cb35ac5a 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -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 OnWeatherChanged (cWorld & a_World) = 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; /** Handles the command split into a_Split, issued by player a_Player. diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index d714f2112..f27cee76e 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -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) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 95e7e789f..188d202e0 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -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 OnWeatherChanged (cWorld & a_World) 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 HandleCommand(const AStringVector & a_Split, cPlayer * a_Player) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 29ea26577..12263605f 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -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) { HookMap::iterator Plugins = m_Hooks.find(HOOK_WORLD_TICK); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 8282b061c..09f230475 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -106,6 +106,7 @@ public: // tolua_export HOOK_UPDATING_SIGN, HOOK_WEATHER_CHANGED, HOOK_WEATHER_CHANGING, + HOOK_WORLD_STARTED, HOOK_WORLD_TICK, // 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 CallHookWeatherChanged (cWorld & a_World); 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 DisablePlugin(const AString & a_PluginName); // tolua_export diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index fde6bd803..d377823f7 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -375,7 +375,7 @@ void cBlockHandler::DropBlock(cWorld * a_World, cEntity * a_Digger, int a_BlockX MicroY = a_BlockY + 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; MicroZ += r1.rand(1) - 0.5; diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 29f3afbfc..64c03d0d3 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -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) { CHECK_THREAD; diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index 95c690203..06c846fa9 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -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) 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 bool CanReadBytes(int a_Count) const; @@ -106,6 +109,9 @@ public: /// Reads all available data into 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 void CommitRead(void); diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 9c195fdf8..42969bf6d 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -706,8 +706,7 @@ void cChunk::ProcessQueuedSetBlocks(void) { // 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) - // Since blocktypes were the same, we just need to set the meta - SetMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockMeta); + SetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); // SetMeta doesn't send to client itr = m_SetBlockQueue.erase(itr); LOGD("Successfully set queued block - previous and current types matched"); } @@ -1335,6 +1334,7 @@ void cChunk::WakeUpSimulators(void) { cSimulator * WaterSimulator = m_World->GetWaterSimulator(); cSimulator * LavaSimulator = m_World->GetLavaSimulator(); + cSimulator * RedstoneSimulator = m_World->GetRedstoneSimulator(); int BaseX = m_PosX * cChunkDef::Width; int BaseZ = m_PosZ * cChunkDef::Width; for (int x = 0; x < Width; x++) @@ -1345,7 +1345,16 @@ void cChunk::WakeUpSimulators(void) int BlockZ = z + BaseZ; 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: { @@ -1357,6 +1366,10 @@ void cChunk::WakeUpSimulators(void) LavaSimulator->AddBlock(BlockX, y, BlockZ, this); break; } + default: + { + break; + } } // switch (BlockType) } // for y } // for z diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index aa223f5df..f7e18974f 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -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; - Printf(Reason, "Unknown [C->S] PacketType: 0x%02x", a_PacketType); + Printf(Reason, "Unknown [C->S] PacketType: 0x%x", a_PacketType); SendDisconnect(Reason); Destroy(); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 4498c15c2..2ff75b28a 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -160,7 +160,7 @@ public: // Calls that cProtocol descendants use to report state: void PacketBufferFull(void); - void PacketUnknown(unsigned char a_PacketType); + void PacketUnknown(UInt32 a_PacketType); void PacketError(unsigned char a_PacketType); // Calls that cProtocol descendants use for handling packets: diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index e699e0c84..c42d09b89 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -7,6 +7,7 @@ #include "DeadlockDetect.h" #include "Root.h" #include "World.h" +# include @@ -137,11 +138,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age) void cDeadlockDetect::DeadlockDetected(void) { ASSERT(!"Deadlock detected"); - - // TODO: Make a crashdump / coredump - - // Crash the server intentionally: - *((volatile int *)0) = 0; + abort(); } diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp index 1e5ee00ce..248fb7278 100644 --- a/src/Entities/ExpOrb.cpp +++ b/src/Entities/ExpOrb.cpp @@ -40,21 +40,25 @@ void cExpOrb::SpawnOn(cClientHandle & a_Client) void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) { - cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 4)); - if (a_ClosestPlayer) + cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 5)); + if (a_ClosestPlayer != NULL) { Vector3f a_PlayerPos(a_ClosestPlayer->GetPosition()); + a_PlayerPos.y++; 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->SendExperience(); Destroy(true); } - a_Distance.y = 0; a_Distance.Normalize(); - a_Distance *= 3; + a_Distance *= ((float) (5.5 - Distance)); SetSpeedX( a_Distance.x ); + SetSpeedY( a_Distance.y ); SetSpeedZ( a_Distance.z ); + BroadcastMovementUpdate(); } + HandlePhysics(a_Dt, a_Chunk); } \ No newline at end of file diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 7a5ff5696..85833f31d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1393,7 +1393,12 @@ void cPlayer::LoadPermissionsFromDisk() } 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"); } ResolvePermissions(); @@ -1410,7 +1415,7 @@ bool cPlayer::LoadFromDisk() LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); 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; diff --git a/src/Entities/TNTEntity.h b/src/Entities/TNTEntity.h index eb5040e8a..d1fcae766 100644 --- a/src/Entities/TNTEntity.h +++ b/src/Entities/TNTEntity.h @@ -6,13 +6,14 @@ - +// tolua_begin class cTNTEntity : public cEntity { typedef cEntity super; public: + // tolua_end CLASS_PROTODEF(cTNTEntity); cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec); @@ -21,11 +22,14 @@ public: // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) 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: 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 -}; +}; // tolua_export diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index df609f05b..1ffe3812f 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -47,8 +47,25 @@ cGroupManager::cGroupManager() cIniFile IniFile; if (!IniFile.ReadFile("groups.ini")) { - LOGWARNING("groups.ini inaccessible, no groups are defined"); - return; + LOGWARNING("Regenerating groups.ini, all groups will be reset"); + 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(); diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 091623c8a..0e2da942d 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -274,6 +274,7 @@ void cMonster::KilledBy(cEntity * a_Killer) case cMonster::mtWolf: { Reward = m_World->GetTickRandomNumber(2) + 1; + break; } // Monsters @@ -291,25 +292,30 @@ void cMonster::KilledBy(cEntity * a_Killer) case cMonster::mtMagmaCube: { Reward = 6 + (m_World->GetTickRandomNumber(2)); + break; } case cMonster::mtBlaze: { Reward = 10; + break; } // Bosses case cMonster::mtEnderDragon: { Reward = 12000; + break; } case cMonster::mtWither: { Reward = 50; + break; } default: { Reward = 0; + break; } } m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 75983e9a3..bfb38904c 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -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; \ - m_ReceivedData.Proc(Var); + ByteBuf.Proc(Var); -#define HANDLE_PACKET_READ(Proc, Type, Var) \ +#define HANDLE_PACKET_READ(ByteBuf, Proc, Type, Var) \ Type Var; \ { \ - if (!m_ReceivedData.Proc(Var)) \ + if (!ByteBuf.Proc(Var)) \ { \ - m_ReceivedData.CheckValid(); \ + ByteBuf.CheckValid(); \ 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) { + LOGD("Received %d bytes of data", a_Size); if (!m_ReceivedData.Write(a_Data, a_Size)) { // 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) { UInt32 PacketLen; + int PacketStart = m_ReceivedData.GetDataStart(); if (!m_ReceivedData.ReadVarInt(PacketLen)) { // 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 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 Mark1 = m_ReceivedData.GetReadableSpace(); - if (!m_ReceivedData.ReadVarInt(PacketType)) + if (!bb.ReadVarInt(PacketType)) { // Not enough data return; } - UInt32 NumBytesRead = Mark1 - m_ReceivedData.GetReadableSpace(); - HandlePacket(PacketType, PacketLen - NumBytesRead); + // DEBUG: + 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); } - - // Go to packet end in any case: - m_ReceivedData.ResetRead(); - m_ReceivedData.ReadVarInt(PacketType); - m_ReceivedData.SkipRead(PacketLen); - m_ReceivedData.CommitRead(); } // while (true) } -void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes) +void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) { switch (m_State) { @@ -979,8 +984,8 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes) // Status switch (a_PacketType) { - case 0x00: HandlePacketStatusRequest(a_RemainingBytes); return; - case 0x01: HandlePacketStatusPing (a_RemainingBytes); return; + case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return; + case 0x01: HandlePacketStatusPing (a_ByteBuffer); return; } break; } @@ -990,8 +995,8 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes) // Login switch (a_PacketType) { - case 0x00: HandlePacketLoginStart(a_RemainingBytes); return; - case 0x01: HandlePacketLoginEncryptionResponse(a_RemainingBytes); return; + case 0x00: HandlePacketLoginStart (a_ByteBuffer); return; + case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return; } break; } @@ -1001,29 +1006,29 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes) // Game switch (a_PacketType) { - case 0x00: HandlePacketKeepAlive (a_RemainingBytes); return; - case 0x01: HandlePacketChatMessage (a_RemainingBytes); return; - case 0x02: HandlePacketUseEntity (a_RemainingBytes); return; - case 0x03: HandlePacketPlayer (a_RemainingBytes); return; - case 0x04: HandlePacketPlayerPos (a_RemainingBytes); return; - case 0x05: HandlePacketPlayerLook (a_RemainingBytes); return; - case 0x06: HandlePacketPlayerPosLook (a_RemainingBytes); return; - case 0x07: HandlePacketBlockDig (a_RemainingBytes); return; - case 0x08: HandlePacketBlockPlace (a_RemainingBytes); return; - case 0x09: HandlePacketSlotSelect (a_RemainingBytes); return; - case 0x0a: HandlePacketAnimation (a_RemainingBytes); return; - case 0x0b: HandlePacketEntityAction (a_RemainingBytes); return; - case 0x0c: HandlePacketSteerVehicle (a_RemainingBytes); return; - case 0x0d: HandlePacketWindowClose (a_RemainingBytes); return; - case 0x0e: HandlePacketWindowClick (a_RemainingBytes); return; + case 0x00: HandlePacketKeepAlive (a_ByteBuffer); return; + case 0x01: HandlePacketChatMessage (a_ByteBuffer); return; + case 0x02: HandlePacketUseEntity (a_ByteBuffer); return; + case 0x03: HandlePacketPlayer (a_ByteBuffer); return; + case 0x04: HandlePacketPlayerPos (a_ByteBuffer); return; + case 0x05: HandlePacketPlayerLook (a_ByteBuffer); return; + case 0x06: HandlePacketPlayerPosLook (a_ByteBuffer); return; + case 0x07: HandlePacketBlockDig (a_ByteBuffer); return; + case 0x08: HandlePacketBlockPlace (a_ByteBuffer); return; + case 0x09: HandlePacketSlotSelect (a_ByteBuffer); return; + case 0x0a: HandlePacketAnimation (a_ByteBuffer); return; + case 0x0b: HandlePacketEntityAction (a_ByteBuffer); return; + case 0x0c: HandlePacketSteerVehicle (a_ByteBuffer); return; + case 0x0d: HandlePacketWindowClose (a_ByteBuffer); return; + case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return; case 0x0f: // Confirm transaction - not used in MCS - case 0x10: HandlePacketCreativeInventoryAction(a_RemainingBytes); return; - case 0x12: HandlePacketUpdateSign (a_RemainingBytes); return; - case 0x13: HandlePacketPlayerAbilities (a_RemainingBytes); return; - case 0x14: HandlePacketTabComplete (a_RemainingBytes); return; - case 0x15: HandlePacketClientSettings (a_RemainingBytes); return; - case 0x16: HandlePacketClientStatus (a_RemainingBytes); return; - case 0x17: HandlePacketPluginMessage (a_RemainingBytes); return; + case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return; + case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return; + case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return; + case 0x14: HandlePacketTabComplete (a_ByteBuffer); return; + case 0x15: HandlePacketClientSettings (a_ByteBuffer); return; + case 0x16: HandlePacketClientStatus (a_ByteBuffer); return; + case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return; } break; } @@ -1031,27 +1036,16 @@ void cProtocol172::HandlePacket(UInt32 a_PacketType, UInt32 a_RemainingBytes) // Unknown packet type, report to the client: 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; - m_ReceivedData.ReadBEInt64(Timestamp); - m_ReceivedData.CommitRead(); + a_ByteBuffer.ReadBEInt64(Timestamp); cPacketizer Pkt(*this, 0x01); // Ping packet 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: AString Response = "{\"version\":{\"name\":\"1.7.2\",\"protocol\":4},\"players\":{"; 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 } @@ -1095,10 +1085,10 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes) -void cProtocol172::HandlePacketLoginStart(UInt32 a_RemainingBytes) +void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) { AString Username; - m_ReceivedData.ReadVarUTF8String(Username); + a_ByteBuffer.ReadVarUTF8String(Username); // 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(ReadByte, Byte, Animation); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, 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(ReadBEInt, int, BlockX); - HANDLE_READ(ReadByte, Byte, BlockY); - HANDLE_READ(ReadBEInt, int, BlockZ); - HANDLE_READ(ReadByte, Byte, Face); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, BlockY); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); 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(ReadByte, Byte, BlockY); - HANDLE_READ(ReadBEInt, int, BlockZ); - HANDLE_READ(ReadByte, Byte, Face); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, BlockY); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face); cItem Item; - ReadItem(Item); + ReadItem(a_ByteBuffer, Item); - HANDLE_READ(ReadByte, Byte, CursorX); - HANDLE_READ(ReadByte, Byte, CursorY); - HANDLE_READ(ReadByte, Byte, CursorZ); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorZ); 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); } @@ -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(ReadByte, Byte, ViewDistance); - HANDLE_READ(ReadByte, Byte, ChatFlags); - HANDLE_READ(ReadByte, Byte, Unused); - HANDLE_READ(ReadByte, Byte, Difficulty); - HANDLE_READ(ReadByte, Byte, ShowCape); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatColors); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Difficulty); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape); // 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) { 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; - if (!ReadItem(Item)) + if (!ReadItem(a_ByteBuffer, Item)) { 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(ReadByte, Byte, Action); - HANDLE_READ(ReadBEInt, int, JumpBoost); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, PlayerID); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Action); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, JumpBoost); 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); } @@ -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); } @@ -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(ReadBEFloat, float, FlyingSpeed); - HANDLE_READ(ReadBEFloat, float, WalkingSpeed); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Flags); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed); // 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(ReadBEFloat, float, Pitch); - HANDLE_READ(ReadBool, bool, IsOnGround); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, 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(ReadBEDouble, double, PosY); - HANDLE_READ(ReadBEDouble, double, Stance); - HANDLE_READ(ReadBEDouble, double, PosZ); - HANDLE_READ(ReadBool, bool, IsOnGround); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, Stance); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, 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(ReadBEDouble, double, PosY); - HANDLE_READ(ReadBEDouble, double, Stance); - HANDLE_READ(ReadBEDouble, double, PosZ); - HANDLE_READ(ReadBEFloat, float, Yaw); - HANDLE_READ(ReadBEFloat, float, Pitch); - HANDLE_READ(ReadBool, bool, IsOnGround); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, Stance); + HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, 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(ReadBEShort, short, Length); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length); AString Data; - m_ReceivedData.ReadString(Data, Length); + a_ByteBuffer.ReadString(Data, Length); // 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); } @@ -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(ReadBEFloat, float, Sideways); - HANDLE_READ(ReadBool, bool, ShouldJump); - HANDLE_READ(ReadBool, bool, ShouldUnmount); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward); + HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, ShouldJump); + HANDLE_READ(a_ByteBuffer, ReadBool, bool, ShouldUnmount); if (ShouldUnmount) { 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); } @@ -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(ReadBEShort, short, BlockY); - HANDLE_READ(ReadBEInt, int, BlockZ); - HANDLE_READ(ReadVarUTF8String, AString, Line1); - HANDLE_READ(ReadVarUTF8String, AString, Line2); - HANDLE_READ(ReadVarUTF8String, AString, Line3); - HANDLE_READ(ReadVarUTF8String, AString, Line4); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX); + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, BlockY); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line1); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line2); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line3); + HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, 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(ReadByte, Byte, MouseButton); + HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, MouseButton); 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(ReadBEShort, short, SlotNum); - HANDLE_READ(ReadByte, Byte, Button); - HANDLE_READ(ReadBEShort, short, TransactionID); - HANDLE_READ(ReadByte, Byte, Mode); + HANDLE_READ(a_ByteBuffer, ReadChar, char, WindowID); + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Button); + HANDLE_READ(a_ByteBuffer, ReadBEShort, short, TransactionID); + HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode); cItem Item; - ReadItem(Item); + ReadItem(a_ByteBuffer, Item); // Convert Button, Mode, SlotNum and HeldItem into eClickAction: eClickAction Action; @@ -1434,6 +1424,12 @@ void cProtocol172::HandlePacketWindowClick(UInt32 a_RemainingBytes) case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break; case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; 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); @@ -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); } @@ -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) { // The item is empty, no more data follows @@ -1503,8 +1499,8 @@ bool cProtocol172::ReadItem(cItem & a_Item) } a_Item.m_ItemType = ItemType; - HANDLE_PACKET_READ(ReadChar, char, ItemCount); - HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage); + HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, ItemCount); + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemDamage); a_Item.m_ItemCount = ItemCount; a_Item.m_ItemDamage = ItemDamage; if (ItemCount <= 0) @@ -1512,7 +1508,7 @@ bool cProtocol172::ReadItem(cItem & a_Item) a_Item.Empty(); } - HANDLE_PACKET_READ(ReadBEShort, short, MetadataLength); + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, MetadataLength); if (MetadataLength <= 0) { return true; @@ -1520,7 +1516,7 @@ bool cProtocol172::ReadItem(cItem & a_Item) // Read the metadata AString Metadata; - if (!m_ReceivedData.ReadString(Metadata, MetadataLength)) + if (!a_ByteBuffer.ReadString(Metadata, MetadataLength)) { return false; } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 9a189ab24..b8c91fbeb 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -205,39 +205,39 @@ protected: void AddReceivedData(const char * a_Data, int a_Size); /// 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): - void HandlePacketStatusPing (UInt32 a_RemainingBytes); - void HandlePacketStatusRequest(UInt32 a_RemainingBytes); + void HandlePacketStatusPing (cByteBuffer & a_ByteBuffer); + void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer); // Packet handlers while in the Login state (m_State == 2): - void HandlePacketLoginEncryptionResponse(UInt32 a_RemainingBytes); - void HandlePacketLoginStart (UInt32 a_RemainingBytes); + void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); + void HandlePacketLoginStart (cByteBuffer & a_ByteBuffer); // Packet handlers while in the Game state (m_State == 3): - void HandlePacketAnimation (UInt32 a_RemainingBytes); - void HandlePacketBlockDig (UInt32 a_RemainingBytes); - void HandlePacketBlockPlace (UInt32 a_RemainingBytes); - void HandlePacketChatMessage (UInt32 a_RemainingBytes); - void HandlePacketClientSettings (UInt32 a_RemainingBytes); - void HandlePacketClientStatus (UInt32 a_RemainingBytes); - void HandlePacketCreativeInventoryAction(UInt32 a_RemainingBytes); - void HandlePacketEntityAction (UInt32 a_RemainingBytes); - void HandlePacketKeepAlive (UInt32 a_RemainingBytes); - void HandlePacketPlayer (UInt32 a_RemainingBytes); - void HandlePacketPlayerAbilities (UInt32 a_RemainingBytes); - void HandlePacketPlayerLook (UInt32 a_RemainingBytes); - void HandlePacketPlayerPos (UInt32 a_RemainingBytes); - void HandlePacketPlayerPosLook (UInt32 a_RemainingBytes); - void HandlePacketPluginMessage (UInt32 a_RemainingBytes); - void HandlePacketSlotSelect (UInt32 a_RemainingBytes); - void HandlePacketSteerVehicle (UInt32 a_RemainingBytes); - void HandlePacketTabComplete (UInt32 a_RemainingBytes); - void HandlePacketUpdateSign (UInt32 a_RemainingBytes); - void HandlePacketUseEntity (UInt32 a_RemainingBytes); - void HandlePacketWindowClick (UInt32 a_RemainingBytes); - void HandlePacketWindowClose (UInt32 a_RemainingBytes); + void HandlePacketAnimation (cByteBuffer & a_ByteBuffer); + void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); + void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer); + void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer); + void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer); + void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer); + void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer); + void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer); + void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayer (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerAbilities (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerLook (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer); + void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer); + void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer); + void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer); + void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer); + void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer); + void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer); + void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer); + void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); + 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. @@ -249,7 +249,7 @@ protected: 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 - bool ReadItem(cItem & a_Item); + bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item); /// Parses item metadata as read by ReadItem(), into the item enchantments. void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); diff --git a/src/Root.cpp b/src/Root.cpp index c99bf76b7..fb1e96426 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -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) { for (WorldMap::iterator itr = m_WorldsByName.begin(); itr != m_WorldsByName.end(); ++itr) { itr->second->Start(); itr->second->InitializeSpawn(); + m_PluginManager->CallHookWorldStarted(*itr->second); } } diff --git a/src/Root.h b/src/Root.h index 4e38dd17f..c59afc810 100644 --- a/src/Root.h +++ b/src/Root.h @@ -42,6 +42,7 @@ public: cServer * GetServer(void) { return m_Server; } // tolua_export cWorld * GetDefaultWorld(void); // 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) bool ForEachWorld(cWorldListCallback & a_Callback); // >> Exported in ManualBindings << diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index 9328b9fcb..f61e1c63b 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -50,7 +50,7 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu // Check for duplicates: 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)) { @@ -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) for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) { - sPoweredBlocks & Change = *itr; - - int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; - int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width; + int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width; BLOCKTYPE SourceBlockType; 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; } - if (SourceBlockType != Change.a_SourceBlock) + if (SourceBlockType != itr->a_SourceBlock) { 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 ( // Changeable sources @@ -105,7 +103,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c ) { 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 { @@ -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 for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();) { - sLinkedPoweredBlocks & Change = *itr; - - int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; - int RelZ = Change.a_SourcePos.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; + int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width; + int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + int MidRelX = itr->a_MiddlePos.x - a_ChunkX * cChunkDef::Width; + int MidRelZ = itr->a_MiddlePos.z - a_ChunkZ * cChunkDef::Width; BLOCKTYPE SourceBlockType; NIBBLETYPE SourceBlockMeta; BLOCKTYPE MiddleBlockType; if ( - !a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || - !a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType) + !a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || + !a_Chunk->UnboundedRelGetBlockType(MidRelX, itr->a_MiddlePos.y, MidRelZ, MiddleBlockType) ) { continue; } - if (SourceBlockType != Change.a_SourceBlock) + if (SourceBlockType != itr->a_SourceBlock) { 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); - 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 ( // 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); - 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 { @@ -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();) { - sSimulatedPlayerToggleableList & Change = *itr; - - int RelX = Change.a_BlockPos.x - a_ChunkX * cChunkDef::Width; - int RelZ = Change.a_BlockPos.z - a_ChunkZ * cChunkDef::Width; + int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width; + int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width; 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; } 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); } 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; 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 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 // 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 } @@ -416,7 +410,6 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { 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 { @@ -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); } - - 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 { 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 sRepeatersDelayList RC; 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; m_RepeatersDelayList.push_back(RC); 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 (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 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) +{ + for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list { - sLinkedPoweredBlocks & Change = *itr; - - 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; } @@ -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 - 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 (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } switch (a_Meta) { case 0x0: { // 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; } 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; } 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; } 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; } } } - 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 (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } switch (a_Meta) { 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; } 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; } 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; } 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; } } @@ -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; - 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 (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + if (!itr->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 - 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; } @@ -950,15 +943,13 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block 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 (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } 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; } @@ -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) { - 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 (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + if (itr->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 } @@ -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); - 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 - 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 - 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, 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; } case BLOCK_FACE_XP: { 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 + 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 + 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, 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; } case BLOCK_FACE_YM: { 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 + 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 - 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, 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; } case BLOCK_FACE_YP: { 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 + 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 + 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, 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; } case BLOCK_FACE_ZM: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1); + + 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, 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); - 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 + 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); - } break; } case BLOCK_FACE_ZP: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1); + + 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, 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); - 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 + 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); - } break; } default: @@ -1270,13 +1109,11 @@ void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_Block 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 ( - Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) && - Change.a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) + itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) && + itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) ) { // Check for duplicates @@ -1302,24 +1139,28 @@ void cRedstoneSimulator::SetBlockLinkedPowered( 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) return; } - if (!IsViableMiddleBlock(m_World.GetBlock(a_MiddleX, a_MiddleY, a_MiddleZ))) + if (!IsViableMiddleBlock(a_MiddleBlock)) { return; } - - for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list + if ((a_SourceBlock == E_BLOCK_REDSTONE_WIRE) && (DestBlock == E_BLOCK_REDSTONE_WIRE)) { - 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 ( - Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) && - Change.a_MiddlePos.Equals(Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ)) && - Change.a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) + itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ)) && + itr->a_MiddlePos.Equals(Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ)) && + itr->a_SourcePos.Equals(Vector3i(a_SourceX, a_SourceY, a_SourceZ)) ) { // Check for duplicates @@ -1344,24 +1185,25 @@ void cRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a { for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr) { - sSimulatedPlayerToggleableList & Change = *itr; - - if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { - if (Change.WasLastStatePowered != WasLastStatePowered) - { - // If power states different, erase the old listing in preparation to add new one - m_SimulatedPlayerToggleableBlocks.erase(itr); - break; - } - else - { - // If states the same, just ignore - return; - } + continue; + } + + if (itr->WasLastStatePowered != WasLastStatePowered) + { + // If power states different, update listing + itr->WasLastStatePowered = WasLastStatePowered; + return; + } + else + { + // If states the same, just ignore + return; } } + // We have arrive here; no block must be in list - add one sSimulatedPlayerToggleableList RC; RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); RC.WasLastStatePowered = WasLastStatePowered; diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index 1d85c0634..23ac510fc 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -127,7 +127,11 @@ private: void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock); /// Returns if a coordinate is powered or linked powered - 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); } + /// Returns if a coordinate is in the directly powered blocks list + bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ); + /// Returns if a coordinate is in the indirectly powered blocks list + bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ); /// Returns if a coordinate was marked as simulated (for blocks toggleable by players) bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered); /// Returns if a repeater is powered @@ -150,6 +154,9 @@ private: switch (Block) { // 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_OFF: { diff --git a/src/World.h b/src/World.h index b6ab321fb..fc821a68a 100644 --- a/src/World.h +++ b/src/World.h @@ -392,6 +392,7 @@ public: inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; } 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 bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp