From ba49a32c3a5b10bfe1ae90edd08f06acad0389fd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 16 Jan 2014 08:34:10 +0100 Subject: [PATCH 1/6] Another VarArgs fix. This time using va_copy() on platforms that have it and simple assignment on platforms that don't. --- lib/inifile/iniFile.cpp | 6 ++---- src/CommandOutput.cpp | 6 ++---- src/Log.cpp | 10 ++++------ src/Log.h | 2 +- src/OSSupport/File.cpp | 6 ++---- src/StringUtils.cpp | 44 ++++++++++++++++++++++++----------------- src/StringUtils.h | 8 ++------ 7 files changed, 39 insertions(+), 43 deletions(-) diff --git a/lib/inifile/iniFile.cpp b/lib/inifile/iniFile.cpp index c118eeca..afa1c110 100644 --- a/lib/inifile/iniFile.cpp +++ b/lib/inifile/iniFile.cpp @@ -446,12 +446,10 @@ bool cIniFile::SetValueF(const AString & a_KeyName, const AString & a_ValueName, bool cIniFile::SetValueV(const AString & a_KeyName, const AString & a_ValueName, const char * a_Format, ...) { - va_list args, argsCopy; + va_list args; va_start(args, a_Format); - va_start(argsCopy, a_Format); AString Data; - AppendVPrintf(Data, a_Format, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(Data, a_Format, args); va_end(args); return SetValue(a_KeyName, a_ValueName, Data); } diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index 48a69596..c221682a 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -16,11 +16,9 @@ void cCommandOutputCallback::Out(const char * a_Fmt, ...) { AString Output; - va_list args, argsCopy; + va_list args; va_start(args, a_Fmt); - va_start(argsCopy, a_Fmt); - AppendVPrintf(Output, a_Fmt, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(Output, a_Fmt, args); va_end(args); Output.append("\n"); Out(Output); diff --git a/src/Log.cpp b/src/Log.cpp index 8f811f14..2d6be0f5 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -99,10 +99,10 @@ void cLog::ClearLog() -void cLog::Log(const char * a_Format, va_list argList, va_list argListCopy) +void cLog::Log(const char * a_Format, va_list argList) { AString Message; - AppendVPrintf(Message, a_Format, argList, argListCopy); + AppendVPrintf(Message, a_Format, argList); time_t rawtime; time ( &rawtime ); @@ -149,11 +149,9 @@ void cLog::Log(const char * a_Format, va_list argList, va_list argListCopy) void cLog::Log(const char * a_Format, ...) { - va_list argList, argListCopy; + va_list argList; va_start(argList, a_Format); - va_start(argListCopy, a_Format); - Log(a_Format, argList, argListCopy); - va_end(argListCopy); + Log(a_Format, argList); va_end(argList); } diff --git a/src/Log.h b/src/Log.h index d33fc287..cba248da 100644 --- a/src/Log.h +++ b/src/Log.h @@ -14,7 +14,7 @@ private: public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList, va_list argListCopy); + void Log(const char * a_Format, va_list argList); void Log(const char * a_Format, ...); // tolua_begin void SimpleLog(const char * a_String); diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index a55346c4..9f7c0d43 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -440,11 +440,9 @@ AString cFile::ReadWholeFile(const AString & a_FileName) int cFile::Printf(const char * a_Fmt, ...) { AString buf; - va_list args, argsCopy; + va_list args; va_start(args, a_Fmt); - va_start(argsCopy, a_Fmt); - AppendVPrintf(buf, a_Fmt, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(buf, a_Fmt, args); va_end(args); return Write(buf.c_str(), buf.length()); } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 16937c8a..58101779 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -14,39 +14,52 @@ #pragma comment(lib, "ws2_32.lib") #endif +// For platforms that don't have va_copy, define out own, simplistic one: +#ifndef va_copy + #define va_copy(dst, src) dst = src +#endif va_copy -AString & AppendVPrintf(AString & str, const char *format, va_list args, va_list argsCopy) + +AString & AppendVPrintf(AString & str, const char *format, va_list args) { ASSERT(format != NULL); char buffer[2048]; size_t len; + va_list argsCopy; + va_copy(argsCopy, args); #ifdef _MSC_VER // MS CRT provides secure printf that doesn't behave like in the C99 standard - if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, args)) != -1) + if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, argsCopy)) != -1) #else // _MSC_VER - if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, args)) < ARRAYCOUNT(buffer)) + if ((len = vsnprintf(buffer, ARRAYCOUNT(buffer), format, argsCopy)) < ARRAYCOUNT(buffer)) #endif // else _MSC_VER { // The result did fit into the static buffer + va_end(argsCopy); str.append(buffer, len); return str; } + va_end(argsCopy); - // The result did not fit into the static buffer + // The result did not fit into the static buffer, use a dynamic buffer: #ifdef _MSC_VER // for MS CRT, we need to calculate the result length - len = _vscprintf(format, args); + va_copy(argsCopy, args); + len = _vscprintf(format, argsCopy); if (len == -1) { + va_end(argsCopy); return str; } + va_end(argsCopy); #endif // _MSC_VER // Allocate a buffer and printf into it: + va_copy(argsCopy, args); std::vector Buffer(len + 1); #ifdef _MSC_VER vsprintf_s((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); @@ -54,6 +67,7 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args, va_list vsnprintf((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); #endif // else _MSC_VER str.append(&(Buffer.front()), Buffer.size() - 1); + va_end(argsCopy); return str; } @@ -64,11 +78,9 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args, va_list AString & Printf(AString & str, const char * format, ...) { str.clear(); - va_list args, argsCopy; + va_list args; va_start(args, format); - va_start(argsCopy, format); - std::string &retval = AppendVPrintf(str, format, args, argsCopy); - va_end(argsCopy); + std::string &retval = AppendVPrintf(str, format, args); va_end(args); return retval; } @@ -80,11 +92,9 @@ AString & Printf(AString & str, const char * format, ...) AString Printf(const char * format, ...) { AString res; - va_list args, argsCopy; + va_list args; va_start(args, format); - va_start(argsCopy, format); - AppendVPrintf(res, format, args, argsCopy); - va_end(argsCopy); + AppendVPrintf(res, format, args); va_end(args); return res; } @@ -93,13 +103,11 @@ AString Printf(const char * format, ...) -AString & AppendPrintf(AString &str, const char *format, ...) +AString & AppendPrintf(AString &str, const char * format, ...) { - va_list args, argsCopy; + va_list args; va_start(args, format); - va_start(argsCopy, format); - std::string &retval = AppendVPrintf(str, format, args, argsCopy); - va_end(argsCopy); + std::string &retval = AppendVPrintf(str, format, args); va_end(args); return retval; } diff --git a/src/StringUtils.h b/src/StringUtils.h index 35faeb01..dfbfc2a7 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -21,12 +21,8 @@ typedef std::list AStringList; -/** Add the formated string to the existing data in the string -It is silly to need to specify the arguments twice, but it is required for x64 / GCC: -Ref.: issue #541, http://www.bailopan.net/blog/?p=30 -va_copy is not available until C++11, so we need to make do with passing a duplicate. -*/ -extern AString & AppendVPrintf(AString & str, const char * format, va_list args, va_list argsCopy); +/** Add the formated string to the existing data in the string */ +extern AString & AppendVPrintf(AString & str, const char * format, va_list args); /// Output the formatted text into the string extern AString & Printf (AString & str, const char * format, ...); From 6f739359e33a3d1c1c7ffc1fc2e5116f8c02fcc7 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 16 Jan 2014 09:01:12 +0100 Subject: [PATCH 2/6] Yet another attempt at VarArgs. --- src/StringUtils.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 58101779..0dbd41c1 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -14,23 +14,22 @@ #pragma comment(lib, "ws2_32.lib") #endif -// For platforms that don't have va_copy, define out own, simplistic one: -#ifndef va_copy - #define va_copy(dst, src) dst = src -#endif va_copy - -AString & AppendVPrintf(AString & str, const char *format, va_list args) +AString & AppendVPrintf(AString & str, const char * format, va_list args) { ASSERT(format != NULL); char buffer[2048]; size_t len; + #ifdef va_copy va_list argsCopy; va_copy(argsCopy, args); + #else + #define argsCopy args + #endif #ifdef _MSC_VER // MS CRT provides secure printf that doesn't behave like in the C99 standard if ((len = _vsnprintf_s(buffer, ARRAYCOUNT(buffer), _TRUNCATE, format, argsCopy)) != -1) @@ -39,27 +38,31 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args) #endif // else _MSC_VER { // The result did fit into the static buffer + #ifdef va_copy va_end(argsCopy); + #endif str.append(buffer, len); return str; } + #ifdef va_copy va_end(argsCopy); + #endif // The result did not fit into the static buffer, use a dynamic buffer: #ifdef _MSC_VER // for MS CRT, we need to calculate the result length - va_copy(argsCopy, args); - len = _vscprintf(format, argsCopy); + // MS doesn't have va_copy() and does nod need it at all + len = _vscprintf(format, args); if (len == -1) { - va_end(argsCopy); return str; } - va_end(argsCopy); #endif // _MSC_VER // Allocate a buffer and printf into it: + #ifdef va_copy va_copy(argsCopy, args); + #endif std::vector Buffer(len + 1); #ifdef _MSC_VER vsprintf_s((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); @@ -67,7 +70,9 @@ AString & AppendVPrintf(AString & str, const char *format, va_list args) vsnprintf((char *)&(Buffer.front()), Buffer.size(), format, argsCopy); #endif // else _MSC_VER str.append(&(Buffer.front()), Buffer.size() - 1); + #ifdef va_copy va_end(argsCopy); + #endif return str; } From e29749b35edcadc4724997ad6ab90eb44d77e906 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 16 Jan 2014 15:26:58 +0100 Subject: [PATCH 3/6] Added packet diagnostics to 1.7 protocol. When the packet is mis-interpreted, a log message is output about the packet type and lengths. --- src/Protocol/Protocol17x.cpp | 64 ++++++++++++++++++++---------------- src/Protocol/Protocol17x.h | 6 ++-- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 68992155..162194bc 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1037,11 +1037,18 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) return; } - HandlePacket(bb, PacketType); + if (!HandlePacket(bb, PacketType)) + { + // Unknown packet, already been reported, just bail out + return; + } if (bb.GetReadableSpace() != 1) { // Read more or less than packet length, report as error + LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x. Read %u bytes, packet contained %u bytes", + PacketType, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen + ); ASSERT(!"Read wrong number of bytes!"); m_Client->PacketError(PacketType); } @@ -1051,7 +1058,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) -void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) +bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) { switch (m_State) { @@ -1060,8 +1067,8 @@ void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) // Status switch (a_PacketType) { - case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return; - case 0x01: HandlePacketStatusPing (a_ByteBuffer); return; + case 0x00: HandlePacketStatusRequest(a_ByteBuffer); return true; + case 0x01: HandlePacketStatusPing (a_ByteBuffer); return true; } break; } @@ -1071,8 +1078,8 @@ void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) // Login switch (a_PacketType) { - case 0x00: HandlePacketLoginStart (a_ByteBuffer); return; - case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return; + case 0x00: HandlePacketLoginStart (a_ByteBuffer); return true; + case 0x01: HandlePacketLoginEncryptionResponse(a_ByteBuffer); return true; } break; } @@ -1082,29 +1089,29 @@ void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) // Game switch (a_PacketType) { - 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 0x00: HandlePacketKeepAlive (a_ByteBuffer); return true; + case 0x01: HandlePacketChatMessage (a_ByteBuffer); return true; + case 0x02: HandlePacketUseEntity (a_ByteBuffer); return true; + case 0x03: HandlePacketPlayer (a_ByteBuffer); return true; + case 0x04: HandlePacketPlayerPos (a_ByteBuffer); return true; + case 0x05: HandlePacketPlayerLook (a_ByteBuffer); return true; + case 0x06: HandlePacketPlayerPosLook (a_ByteBuffer); return true; + case 0x07: HandlePacketBlockDig (a_ByteBuffer); return true; + case 0x08: HandlePacketBlockPlace (a_ByteBuffer); return true; + case 0x09: HandlePacketSlotSelect (a_ByteBuffer); return true; + case 0x0a: HandlePacketAnimation (a_ByteBuffer); return true; + case 0x0b: HandlePacketEntityAction (a_ByteBuffer); return true; + case 0x0c: HandlePacketSteerVehicle (a_ByteBuffer); return true; + case 0x0d: HandlePacketWindowClose (a_ByteBuffer); return true; + case 0x0e: HandlePacketWindowClick (a_ByteBuffer); return true; case 0x0f: // Confirm transaction - not used in MCS - 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; + case 0x10: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true; + case 0x12: HandlePacketUpdateSign (a_ByteBuffer); return true; + case 0x13: HandlePacketPlayerAbilities (a_ByteBuffer); return true; + case 0x14: HandlePacketTabComplete (a_ByteBuffer); return true; + case 0x15: HandlePacketClientSettings (a_ByteBuffer); return true; + case 0x16: HandlePacketClientStatus (a_ByteBuffer); return true; + case 0x17: HandlePacketPluginMessage (a_ByteBuffer); return true; } break; } @@ -1112,6 +1119,7 @@ void cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) // Unknown packet type, report to the client: m_Client->PacketUnknown(a_PacketType); + return false; } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index fd6b1fc0..07dba834 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -222,8 +222,10 @@ protected: /// Adds the received (unencrypted) data to m_ReceivedData, parses complete packets 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(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType); + /** Reads and handles the packet. The packet length and type have already been read. + Returns true if the packet was understood, false if it was an unknown packet + */ + bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType); // Packet handlers while in the Status state (m_State == 1): void HandlePacketStatusPing (cByteBuffer & a_ByteBuffer); From dab37db5627fce29b260a09483e3c2d7f29b2456 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 16 Jan 2014 18:33:28 +0100 Subject: [PATCH 4/6] CMake: Fixed output paths for all MSVC versions. --- lib/lua/CMakeLists.txt | 14 ++++++++++---- src/CMakeLists.txt | 16 +++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/lua/CMakeLists.txt b/lib/lua/CMakeLists.txt index 9052da19..02c20388 100644 --- a/lib/lua/CMakeLists.txt +++ b/lib/lua/CMakeLists.txt @@ -22,11 +22,17 @@ endif() if (WIN32) add_library(lua SHARED ${SOURCE}) set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) - if (MSVC) - # MSVC generator adds a "Debug" or "Release" postfixes to the LIBRARY_OUTPUT_PATH, we need to cancel them: - SET_TARGET_PROPERTIES(lua PROPERTIES PREFIX "../") - SET_TARGET_PROPERTIES(lua PROPERTIES IMPORT_PREFIX "../") + # Output the executable into the $/MCServer folder, so that MCServer can find it: + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) + SET_TARGET_PROPERTIES(${EXECUTABLE} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer + RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer + RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer + ) + + if (MSVC) # Remove SCL warnings, we expect this library to have been tested safe SET_TARGET_PROPERTIES( lua PROPERTIES COMPILE_FLAGS "-D_CRT_SECURE_NO_WARNINGS" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1c031173..b3af6aed 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required (VERSION 2.8.2) project (MCServer) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") @@ -88,13 +88,15 @@ set(EXECUTABLE MCServer) add_executable(${EXECUTABLE} ${SOURCE}) -set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) -if (MSVC) - # MSVC generator adds a "Debug" or "Release" postfixes to the EXECUTABLE_OUTPUT_PATH, we need to cancel them: - SET_TARGET_PROPERTIES(${EXECUTABLE} PROPERTIES PREFIX "../") - SET_TARGET_PROPERTIES(${EXECUTABLE} PROPERTIES IMPORT_PREFIX "../") -endif() +# Output the executable into the $/MCServer folder, so that it has access to external resources: +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) +SET_TARGET_PROPERTIES(${EXECUTABLE} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer + RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer + RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer + RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer +) # Make the debug executable have a "_debug" suffix From 9a8975420e6b33abb7271534f1e8f5bfc50b21f3 Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 16 Jan 2014 09:51:01 -0800 Subject: [PATCH 5/6] documented CROSSCOMPILING flag --- COMPILING.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/COMPILING.md b/COMPILING.md index e10acee9..0989440a 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -25,3 +25,12 @@ This is useful if you want to compile MCServer to use on another 32-bit machine. -DFORCE_32=1 to your cmake command and 32 bit will be forced. + +Compiling for another computer +------------------------------ + +When compiling for another computer it is important to set cross compiling mode. This tells the compiler not to optimise for your machine. It can be used with debug or release mode. To enable simply add: + + -DCROSSCOMPILE=1 + +to your cmake command. From daf94e5f48af321c6cd56ecd39f56e04b3c2b6b4 Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 16 Jan 2014 09:53:46 -0800 Subject: [PATCH 6/6] Documented the SchedualeTask function --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 0dc059cb..4f01c375 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2087,6 +2087,7 @@ end QueueSetBlock = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta, TickDelay", Return = "", Notes = "Queues the block to be set to the specified blocktype and meta after the specified amount of game ticks. Uses SetBlock() for the actual setting, so simulators are woken up and block entities are handled correctly." }, QueueTask = { Params = "TaskFunction", Return = "", Notes = "Queues the specified function to be executed in the tick thread. This is the primary means of interaction with a cWorld from the WebAdmin page handlers (see {{WebWorldThreads}}). The function signature is
function()
All return values from the function are ignored. Note that this function is actually called *after* the QueueTask() function returns." }, RegenerateChunk = { Params = "ChunkX, ChunkZ", Return = "", Notes = "Queues the specified chunk to be re-generated, overwriting the current data. To queue a chunk for generating only if it doesn't exist, use the GenerateChunk() instead." }, + ScheduleTask = { Params = "TaskFunction, Ticks", Return = "", Notes = "Queues the specified function to be executed in the tick thread after a number of ticks. This enables operations to be queued for execution in the future. The function signature is
function()
All return values from the function are ignored." }, SendBlockTo = { Params = "BlockX, BlockY, BlockZ, {{cPlayer|Player}}", Return = "", Notes = "Sends the block at the specified coords to the specified player's client, as an UpdateBlock packet." }, SetBlock = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "", Notes = "Sets the block at the specified coords, replaces the block entities for the previous block type, creates a new block entity for the new block, if appropriate, and wakes up the simulators. This is the preferred way to set blocks, as opposed to FastSetBlock(), which is only to be used under special circumstances." }, SetBlockMeta =