From ed7816419d2b1d2ddd3a371efb4276ca67dfb4d8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 29 Jan 2014 19:19:14 +0000 Subject: [PATCH 01/30] Fixed redstone simulator crash found in #570 --- src/ChunkDef.h | 16 +++++++++++----- src/Simulator/RedstoneSimulator.cpp | 25 +++++++++++++------------ src/Simulator/RedstoneSimulator.h | 2 +- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index d1288994c..13933e6f1 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -499,13 +499,14 @@ public: /// Generic template that can store any kind of data together with a triplet of 3 coords: -template class cCoordWithData +template class cCoordWithData { public: int x; int y; int z; X Data; + Y SecondData; cCoordWithData(int a_X, int a_Y, int a_Z) : x(a_X), y(a_Y), z(a_Z) @@ -516,14 +517,19 @@ public: x(a_X), y(a_Y), z(a_Z), Data(a_Data) { } + + cCoordWithData(int a_X, int a_Y, int a_Z, const X & a_Data, const Y & a_SecondData) : + x(a_X), y(a_Y), z(a_Z), Data(a_Data), SecondData(a_SecondData) + { + } } ; -// Illegal in C++03: typedef std::list< cCoordWithData > cCoordWithDataList; -typedef cCoordWithData cCoordWithInt; -typedef cCoordWithData cCoordWithBlock; +typedef cCoordWithData cCoordWithInt; +typedef cCoordWithData cCoordWithBlockAndBool; + typedef std::list cCoordWithIntList; typedef std::vector cCoordWithIntVector; -typedef std::vector cCoordWithBlockVector; +typedef std::vector cCoordWithBlockAndBoolVector; diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index e361cbf49..357643ecc 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -9,7 +9,6 @@ #include "../Blocks/BlockTorch.h" #include "../Blocks/BlockDoor.h" #include "../Piston.h" -#include "../Tracer.h" @@ -170,7 +169,7 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu { if (!IsAllowedBlock(Block)) { - ChunkData.erase(itr); // The new blocktype is not redstone; it must be removed from this list + itr->SecondData = true; // The new blocktype is not redstone; it must be queued to be removed from this list } else { @@ -185,7 +184,7 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu return; } - ChunkData.push_back(cCoordWithBlock(RelX, a_BlockY, RelZ, Block)); + ChunkData.push_back(cCoordWithBlockAndBool(RelX, a_BlockY, RelZ, Block, false)); } @@ -208,8 +207,14 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c int BaseX = a_Chunk->GetPosX() * cChunkDef::Width; int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width; - for (cRedstoneSimulatorChunkData::const_iterator dataitr = ChunkData.begin(); dataitr != ChunkData.end(); ++dataitr) + for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(); dataitr != ChunkData.end();) { + if (dataitr->SecondData) + { + dataitr = ChunkData.erase(dataitr); + continue; + } + int a_X = BaseX + dataitr->x; int a_Z = BaseZ + dataitr->z; switch (dataitr->Data) @@ -279,6 +284,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c break; } } + ++dataitr; } } @@ -917,7 +923,7 @@ void cRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_BlockY, int a_B case E_BLOCK_STONE_PRESSURE_PLATE: { // MCS feature - stone pressure plates can only be triggered by players :D - cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(a_BlockX + 0.5f, (float)a_BlockY, a_BlockZ + 0.5f), 0.5f); + cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(a_BlockX + 0.5f, (float)a_BlockY, a_BlockZ + 0.5f), 0.5f, false); if (a_Player != NULL) { @@ -948,19 +954,14 @@ void cRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_BlockY, int a_B virtual bool Item(cEntity * a_Entity) override { - cTracer LineOfSight(m_World); - Vector3f EntityPos = a_Entity->GetPosition(); Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); float Distance = (EntityPos - BlockPos).Length(); if (Distance < 0.5) { - if (!LineOfSight.Trace(BlockPos, (EntityPos - BlockPos), (int)(EntityPos - BlockPos).Length())) - { - m_Entity = a_Entity; - return true; // Break out, we only need to know for wooden plates that at least one entity is on top - } + m_Entity = a_Entity; + return true; // Break out, we only need to know for wooden plates that at least one entity is on top } return false; } diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index bb2efeb8a..c505b2a0f 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -4,7 +4,7 @@ #include "Simulator.h" /// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used -typedef cCoordWithBlockVector cRedstoneSimulatorChunkData; +typedef cCoordWithBlockAndBoolVector cRedstoneSimulatorChunkData; From 7d03876a3e11aedff0201a8330bfdb2b5523fc5e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 29 Jan 2014 19:22:03 +0000 Subject: [PATCH 02/30] Added LOGREPLACELINE for line replacement --- src/Log.cpp | 31 ++++++++++++++++++++++++-- src/Log.h | 4 ++-- src/MCLogger.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++----- src/MCLogger.h | 7 +++++- src/World.cpp | 10 ++++----- 5 files changed, 94 insertions(+), 16 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index 2d6be0f59..a23a79ccc 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -99,7 +99,7 @@ void cLog::ClearLog() -void cLog::Log(const char * a_Format, va_list argList) +void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine) { AString Message; AppendVPrintf(Message, a_Format, argList); @@ -134,7 +134,34 @@ void cLog::Log(const char * a_Format, va_list argList) __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else - printf("%s", Line.c_str()); + if (a_ReplaceCurrentLine) + { +#ifdef _WIN32 + if (m_LastStringSize == 0) + { + m_LastStringSize = Line.length(); + } + else if (Line.length() < m_LastStringSize) // If last printed line was longer than current, clear this line + { + for (size_t X = 0; X != m_LastStringSize; ++X) + { + fputs(" ", stdout); + } + } +#else // _WIN32 + fputs("\033[K", stdout); // Clear current line +#endif + + printf("\r%s", Line.c_str()); + +#ifdef __linux + fputs("\033[1B", stdout); // Move down one line +#endif // __linux + } + else + { + printf("%s", Line.c_str()); + } #endif #if defined (_WIN32) && defined(_DEBUG) diff --git a/src/Log.h b/src/Log.h index cba248dae..c8c26913b 100644 --- a/src/Log.h +++ b/src/Log.h @@ -10,11 +10,11 @@ class cLog private: FILE * m_File; static cLog * s_Log; - + size_t m_LastStringSize = 0; public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList); + void Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine = false); void Log(const char * a_Format, ...); // tolua_begin void SimpleLog(const char * a_String); diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 4f3e5dc0f..632ea2efe 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -119,13 +119,51 @@ void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) -void cMCLogger::Log(const char * a_Format, va_list a_ArgList) +void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldReplaceLine) { cCSLock Lock(m_CriticalSection); - SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); + + if (!m_BeginLineUpdate && a_ShouldReplaceLine) + { + a_ShouldReplaceLine = false; // Print a normal line first if this is the initial replace line + m_BeginLineUpdate = true; + } + else if (m_BeginLineUpdate && !a_ShouldReplaceLine) + { + m_BeginLineUpdate = false; + } + + if (a_ShouldReplaceLine) + { +#ifdef _WIN32 + HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(Output, &csbi); + + COORD Position = { 0, csbi.dwCursorPosition.Y - 1 }; // Move cursor up one line + SetConsoleCursorPosition(Output, Position); + + SetColor(csRegular); + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + ResetColor(); + + Position = { 0, csbi.dwCursorPosition.Y }; // Set cursor to original position + SetConsoleCursorPosition(Output, Position); +#else // _WIN32 + fputs("\033[1A", stdout); // Move cursor up one line + SetColor(csRegular); + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + ResetColor(); +#endif + } + else + { + SetColor(csRegular); + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + ResetColor(); + puts(""); + } } @@ -188,7 +226,7 @@ void cMCLogger::SetColor(eColorScheme a_Scheme) default: ASSERT(!"Unhandled color scheme"); } SetConsoleTextAttribute(g_Console, Attrib); - #elif defined(__linux) && !defined(ANDROID_NDK) + #elif (defined(__linux) || defined(__apple)) && !defined(ANDROID_NDK) switch (a_Scheme) { case csRegular: printf("\x1b[0m"); break; // Whatever the console default is @@ -224,6 +262,14 @@ void cMCLogger::ResetColor(void) ////////////////////////////////////////////////////////////////////////// // Global functions +void LOGREPLACELINE(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Log(a_Format, argList, true); + va_end(argList); +} + void LOG(const char* a_Format, ...) { va_list argList; diff --git a/src/MCLogger.h b/src/MCLogger.h index c949a4cdf..7bcc195dd 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -21,7 +21,7 @@ public: // tolua_export ~cMCLogger(); // tolua_export - void Log(const char* a_Format, va_list a_ArgList); + void Log(const char* a_Format, va_list a_ArgList, bool a_ShouldReplaceLine = false); void Info(const char* a_Format, va_list a_ArgList); void Warn(const char* a_Format, va_list a_ArgList); void Error(const char* a_Format, va_list a_ArgList); @@ -51,12 +51,17 @@ private: /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this void InitLog(const AString & a_FileName); + + /** Flag to show whether a 'replace line' log command has been issued + Used to decide when to put a newline */ + bool m_BeginLineUpdate = false; }; // tolua_export +extern void LOGREPLACELINE(const char* a_Format, ...); extern void LOG(const char* a_Format, ...); extern void LOGINFO(const char* a_Format, ...); extern void LOGWARN(const char* a_Format, ...); diff --git a/src/World.cpp b/src/World.cpp index 88bbf5f8a..bac529d4a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -100,13 +100,13 @@ protected: { for (;;) { - LOG("%d chunks to load, %d chunks to generate", + LOGREPLACELINE("%d chunks to load, %d chunks to generate", m_World->GetStorage().GetLoadQueueLength(), m_World->GetGenerator().GetQueueLength() ); - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) + // Wait for 0.5 sec, but be "reasonably wakeable" when the thread is to finish + for (int i = 0; i < 5; i++) { cSleep::MilliSleep(100); if (m_ShouldTerminate) @@ -152,10 +152,10 @@ protected: { for (;;) { - LOG("%d chunks remaining to light", m_Lighting->GetQueueLength() + LOGREPLACELINE("%d chunks remaining to light", m_Lighting->GetQueueLength() ); - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish + // Wait for 0.5 sec, but be "reasonably wakeable" when the thread is to finish for (int i = 0; i < 20; i++) { cSleep::MilliSleep(100); From d8aa0b0ec7a2ebea2fc157c623ae8cd7d0b6ba1c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 31 Jan 2014 00:04:57 +0000 Subject: [PATCH 03/30] Improved code * Fixed some issues * Fixed standard violation --- src/Log.cpp | 14 +++++++++----- src/MCLogger.cpp | 12 ++++++++---- src/MCLogger.h | 4 ---- src/World.cpp | 2 ++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index a23a79ccc..37f1376db 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -134,14 +134,15 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else + size_t LineLength = Line.length(); + + if (m_LastStringSize == 0) + m_LastStringSize = LineLength; + if (a_ReplaceCurrentLine) { #ifdef _WIN32 - if (m_LastStringSize == 0) - { - m_LastStringSize = Line.length(); - } - else if (Line.length() < m_LastStringSize) // If last printed line was longer than current, clear this line + if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line { for (size_t X = 0; X != m_LastStringSize; ++X) { @@ -162,6 +163,9 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine { printf("%s", Line.c_str()); } + + m_LastStringSize = LineLength; + #endif #if defined (_WIN32) && defined(_DEBUG) diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 632ea2efe..aebe3e1c9 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -11,6 +11,10 @@ cMCLogger * cMCLogger::s_MCLogger = NULL; bool g_ShouldColorOutput = false; +/** Flag to show whether a 'replace line' log command has been issued +Used to decide when to put a newline */ +bool g_BeginLineUpdate = false; + #ifdef _WIN32 #include // Needed for _isatty(), not available on Linux @@ -123,14 +127,14 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla { cCSLock Lock(m_CriticalSection); - if (!m_BeginLineUpdate && a_ShouldReplaceLine) + if (!g_BeginLineUpdate && a_ShouldReplaceLine) { a_ShouldReplaceLine = false; // Print a normal line first if this is the initial replace line - m_BeginLineUpdate = true; + g_BeginLineUpdate = true; } - else if (m_BeginLineUpdate && !a_ShouldReplaceLine) + else if (g_BeginLineUpdate && !a_ShouldReplaceLine) { - m_BeginLineUpdate = false; + g_BeginLineUpdate = false; } if (a_ShouldReplaceLine) diff --git a/src/MCLogger.h b/src/MCLogger.h index 7bcc195dd..c105ab6e2 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -51,10 +51,6 @@ private: /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this void InitLog(const AString & a_FileName); - - /** Flag to show whether a 'replace line' log command has been issued - Used to decide when to put a newline */ - bool m_BeginLineUpdate = false; }; // tolua_export diff --git a/src/World.cpp b/src/World.cpp index bac529d4a..f2981bf84 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -111,6 +111,7 @@ protected: cSleep::MilliSleep(100); if (m_ShouldTerminate) { + LOGREPLACELINE("World successfully loaded!"); return; } } @@ -161,6 +162,7 @@ protected: cSleep::MilliSleep(100); if (m_ShouldTerminate) { + LOGREPLACELINE("Lighting successful!"); return; } } From 7ae5631d89426df6f05b6c8ba656ba02b9d15f93 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 31 Jan 2014 00:05:23 +0000 Subject: [PATCH 04/30] Added a comment --- src/Log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Log.cpp b/src/Log.cpp index 37f1376db..cbb83097c 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -137,7 +137,7 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine size_t LineLength = Line.length(); if (m_LastStringSize == 0) - m_LastStringSize = LineLength; + m_LastStringSize = LineLength; // Initialise m_LastStringSize if (a_ReplaceCurrentLine) { From 02e752789399ad1b65a0443534ea6a8721efd78c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 31 Jan 2014 20:50:29 +0000 Subject: [PATCH 05/30] Properly initialised variables --- src/Log.cpp | 3 ++- src/Log.h | 2 +- src/MCLogger.cpp | 14 ++++++-------- src/MCLogger.h | 4 ++++ 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index cbb83097c..3938f2c24 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -18,7 +18,8 @@ cLog* cLog::s_Log = NULL; cLog::cLog(const AString & a_FileName ) - : m_File(NULL) + : m_File(NULL), + m_LastStringSize(0) { s_Log = this; diff --git a/src/Log.h b/src/Log.h index c8c26913b..8a0ee9fc7 100644 --- a/src/Log.h +++ b/src/Log.h @@ -10,7 +10,7 @@ class cLog private: FILE * m_File; static cLog * s_Log; - size_t m_LastStringSize = 0; + size_t m_LastStringSize; public: cLog(const AString & a_FileName); ~cLog(); diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index aebe3e1c9..b7b826374 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -11,10 +11,6 @@ cMCLogger * cMCLogger::s_MCLogger = NULL; bool g_ShouldColorOutput = false; -/** Flag to show whether a 'replace line' log command has been issued -Used to decide when to put a newline */ -bool g_BeginLineUpdate = false; - #ifdef _WIN32 #include // Needed for _isatty(), not available on Linux @@ -38,6 +34,7 @@ cMCLogger * cMCLogger::GetInstance(void) cMCLogger::cMCLogger(void) + : m_BeginLineUpdate(false) { AString FileName; Printf(FileName, "LOG_%d.txt", (int)time(NULL)); @@ -49,6 +46,7 @@ cMCLogger::cMCLogger(void) cMCLogger::cMCLogger(const AString & a_FileName) + : m_BeginLineUpdate(false) { InitLog(a_FileName); } @@ -127,14 +125,14 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla { cCSLock Lock(m_CriticalSection); - if (!g_BeginLineUpdate && a_ShouldReplaceLine) + if (!m_BeginLineUpdate && a_ShouldReplaceLine) { a_ShouldReplaceLine = false; // Print a normal line first if this is the initial replace line - g_BeginLineUpdate = true; + m_BeginLineUpdate = true; } - else if (g_BeginLineUpdate && !a_ShouldReplaceLine) + else if (m_BeginLineUpdate && !a_ShouldReplaceLine) { - g_BeginLineUpdate = false; + m_BeginLineUpdate = false; } if (a_ShouldReplaceLine) diff --git a/src/MCLogger.h b/src/MCLogger.h index c105ab6e2..4550cc55d 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -51,6 +51,10 @@ private: /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this void InitLog(const AString & a_FileName); + + /** Flag to show whether a 'replace line' log command has been issued + Used to decide when to put a newline */ + bool m_BeginLineUpdate; }; // tolua_export From 6b18add09b5e9d6d6c2a61e90bdd7011f56f4c82 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 31 Jan 2014 23:02:26 +0000 Subject: [PATCH 06/30] Fixed issues with insufficient console space --- src/Log.cpp | 140 +++++++++++++++++++++++++++++++++++------------ src/Log.h | 11 +++- src/MCLogger.cpp | 14 ++++- 3 files changed, 125 insertions(+), 40 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index 3938f2c24..e7d3e0629 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -100,7 +100,105 @@ void cLog::ClearLog() -void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine) +bool cLog::LogReplaceLine(const char * a_Format, va_list argList) +{ + AString Message; + AppendVPrintf(Message, a_Format, argList); + + time_t rawtime; + time(&rawtime); + + struct tm* timeinfo; +#ifdef _MSC_VER + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime); +#else + timeinfo = localtime(&rawtime); +#endif + + AString Line; +#ifdef _DEBUG + Printf(Line, "[%04x|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); +#else + Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); +#endif + if (m_File) + { + fprintf(m_File, "%s\n", Line.c_str()); + fflush(m_File); + } + + // Print to console: +#if defined(ANDROID_NDK) + //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); + __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); + //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); +#else + size_t LineLength = Line.length(); + + if (m_LastStringSize == 0) + m_LastStringSize = LineLength; // Initialise m_LastStringSize + + HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(Output, &csbi); + + if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) + { + printf("\r%s", Line.c_str()); + return false; + } +#ifdef _WIN32 + if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line + { + for (size_t X = 0; X != m_LastStringSize + 1; ++X) + { + fputs(" ", stdout); + } + } +#else // _WIN32 + struct ttysize ts; +#ifdef TIOCGSIZE + ioctl(STDIN_FILENO, TIOCGSIZE, &ts); + if (ts.ts_cols < LineLength) + { + return false; + } +#elif defined(TIOCGWINSZ) + ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); + if (ts.ts_cols < LineLength) + { + return false; + } +#else /* TIOCGSIZE */ + return false; +#endif + fputs("\033[K", stdout); // Clear current line +#endif + printf("\r%s", Line.c_str()); +#ifdef __linux + fputs("\033[1B", stdout); // Move down one line +#endif // __linux + + m_LastStringSize = LineLength; + +#endif // ANDROID_NDK + +#if defined (_WIN32) && defined(_DEBUG) + // In a Windows Debug build, output the log to debug console as well: + OutputDebugStringA((Line + "\n").c_str()); +#endif // _WIN32 + + return true; +} + + + + + +void cLog::Log(const char * a_Format, va_list argList) { AString Message; AppendVPrintf(Message, a_Format, argList); @@ -123,6 +221,7 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine #else Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #endif + if (m_File) { fprintf(m_File, "%s\n", Line.c_str()); @@ -130,44 +229,13 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine } // Print to console: -#if defined(ANDROID_NDK) + #if defined(ANDROID_NDK) //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); -#else - size_t LineLength = Line.length(); - - if (m_LastStringSize == 0) - m_LastStringSize = LineLength; // Initialise m_LastStringSize - - if (a_ReplaceCurrentLine) - { -#ifdef _WIN32 - if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line - { - for (size_t X = 0; X != m_LastStringSize; ++X) - { - fputs(" ", stdout); - } - } -#else // _WIN32 - fputs("\033[K", stdout); // Clear current line -#endif - - printf("\r%s", Line.c_str()); - -#ifdef __linux - fputs("\033[1B", stdout); // Move down one line -#endif // __linux - } - else - { - printf("%s", Line.c_str()); - } - - m_LastStringSize = LineLength; - -#endif + #else + printf("%s", Line.c_str()); + #endif #if defined (_WIN32) && defined(_DEBUG) // In a Windows Debug build, output the log to debug console as well: diff --git a/src/Log.h b/src/Log.h index 8a0ee9fc7..c9ca17864 100644 --- a/src/Log.h +++ b/src/Log.h @@ -8,20 +8,29 @@ class cLog { // tolua_export private: + FILE * m_File; static cLog * s_Log; size_t m_LastStringSize; + public: + cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine = false); + + /** Replaces current line of console with given text. + Returns true if successful, false if not (screen too narrow etc.) */ + bool LogReplaceLine(const char * a_Format, va_list argList); + void Log(const char * a_Format, va_list argList); void Log(const char * a_Format, ...); + // tolua_begin void SimpleLog(const char * a_String); void OpenLog(const char * a_FileName); void CloseLog(); void ClearLog(); static cLog* GetInstance(); + }; // tolua_end diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index b7b826374..0828b7fe4 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -147,7 +147,11 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla SetConsoleCursorPosition(Output, Position); SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) + { + m_BeginLineUpdate = false; + puts(""); + } ResetColor(); Position = { 0, csbi.dwCursorPosition.Y }; // Set cursor to original position @@ -155,14 +159,18 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla #else // _WIN32 fputs("\033[1A", stdout); // Move cursor up one line SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) + { + m_BeginLineUpdate = false; + puts(""); + } ResetColor(); #endif } else { SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + m_Log->Log(a_Format, a_ArgList); ResetColor(); puts(""); } From 397208145ebe5c95ebf32f2985f6800634932230 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 31 Jan 2014 23:25:15 +0000 Subject: [PATCH 07/30] A newline issue is resolved --- src/Log.cpp | 2 +- src/MCLogger.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index e7d3e0629..b246e8196 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -147,7 +147,7 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) { - printf("\r%s", Line.c_str()); + printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, add a new line return false; } #ifdef _WIN32 diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 0828b7fe4..11fd451a7 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -150,7 +150,6 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) { m_BeginLineUpdate = false; - puts(""); } ResetColor(); @@ -162,7 +161,6 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) { m_BeginLineUpdate = false; - puts(""); } ResetColor(); #endif From 5becfe850a2b4827a21e8ede989545334efbbead Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Feb 2014 01:47:21 +0000 Subject: [PATCH 08/30] Fixed Linux compile --- src/Log.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Log.cpp b/src/Log.cpp index b246e8196..44dab33c9 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -135,6 +135,7 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else +#ifdef _WIN32 size_t LineLength = Line.length(); if (m_LastStringSize == 0) @@ -150,7 +151,7 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, add a new line return false; } -#ifdef _WIN32 + if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line { for (size_t X = 0; X != m_LastStringSize + 1; ++X) From 6f660b379ecbc091b9bd92093e0dad01a4f6bf38 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Feb 2014 01:54:26 +0000 Subject: [PATCH 09/30] Another Linux fix --- src/Log.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Log.cpp b/src/Log.cpp index 44dab33c9..aa9f22f84 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -7,6 +7,12 @@ #include #include "OSSupport/IsThread.h" +#ifdef __linux +#include +#include +#endif // __linux + + #if defined(ANDROID_NDK) #include #include "ToJava.h" From b0784d1931b4a6771321a0c3b33af537200bf084 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Feb 2014 21:40:02 +0000 Subject: [PATCH 10/30] Split cCoord template into one and two data types --- src/ChunkDef.h | 42 ++++++++++++++++++++++------- src/Simulator/RedstoneSimulator.cpp | 4 +-- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 13933e6f1..2c50755cf 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -498,15 +498,14 @@ public: -/// Generic template that can store any kind of data together with a triplet of 3 coords: -template class cCoordWithData +/** Generic template that can store any kind of data together with a triplet of 3 coords*/ +template class cCoordWithData { public: int x; int y; int z; X Data; - Y SecondData; cCoordWithData(int a_X, int a_Y, int a_Z) : x(a_X), y(a_Y), z(a_Z) @@ -517,18 +516,41 @@ public: x(a_X), y(a_Y), z(a_Z), Data(a_Data) { } - - cCoordWithData(int a_X, int a_Y, int a_Z, const X & a_Data, const Y & a_SecondData) : - x(a_X), y(a_Y), z(a_Z), Data(a_Data), SecondData(a_SecondData) - { - } } ; -typedef cCoordWithData cCoordWithInt; -typedef cCoordWithData cCoordWithBlockAndBool; +typedef cCoordWithData cCoordWithInt; +typedef cCoordWithData cCoordWithBlock; typedef std::list cCoordWithIntList; typedef std::vector cCoordWithIntVector; + + + + + +/** Generic template that can store two types of any kind of data together with a triplet of 3 coords */ +template class cCoordWithDoubleData +{ +public: + int x; + int y; + int z; + X Data; + Z DataTwo; + + cCoordWithDoubleData(int a_X, int a_Y, int a_Z) : + x(a_X), y(a_Y), z(a_Z) + { + } + + cCoordWithDoubleData(int a_X, int a_Y, int a_Z, const X & a_Data, const Z & a_DataTwo) : + x(a_X), y(a_Y), z(a_Z), Data(a_Data), DataTwo(a_DataTwo) + { + } +}; + +typedef cCoordWithDoubleData cCoordWithBlockAndBool; + typedef std::vector cCoordWithBlockAndBoolVector; diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index 357643ecc..131380daa 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -169,7 +169,7 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu { if (!IsAllowedBlock(Block)) { - itr->SecondData = true; // The new blocktype is not redstone; it must be queued to be removed from this list + itr->DataTwo = true; // The new blocktype is not redstone; it must be queued to be removed from this list } else { @@ -209,7 +209,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(); dataitr != ChunkData.end();) { - if (dataitr->SecondData) + if (dataitr->DataTwo) { dataitr = ChunkData.erase(dataitr); continue; From e26dc5cc0aaeb81ee7c6419ea91f8eef7d072ef3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Feb 2014 21:40:50 +0000 Subject: [PATCH 11/30] Added checks for ice into IsBlockWater() * This fixes players spawning in vast oceans of ice, as opposed to the previous water --- src/Defines.h | 11 +++++++++-- src/World.cpp | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Defines.h b/src/Defines.h index 3a26f4be6..b3dbcc93e 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -254,9 +254,16 @@ inline bool IsValidItem(int a_ItemType) -inline bool IsBlockWater(BLOCKTYPE a_BlockType) +inline bool IsBlockWater(BLOCKTYPE a_BlockType, bool a_IncludeFrozenWater = false) { - return ((a_BlockType == E_BLOCK_WATER) || (a_BlockType == E_BLOCK_STATIONARY_WATER)); + if (a_IncludeFrozenWater) + { + return ((a_BlockType == E_BLOCK_WATER) || (a_BlockType == E_BLOCK_STATIONARY_WATER) || (a_BlockType == E_BLOCK_ICE)); + } + else + { + return ((a_BlockType == E_BLOCK_WATER) || (a_BlockType == E_BLOCK_STATIONARY_WATER)); + } } diff --git a/src/World.cpp b/src/World.cpp index f2981bf84..2571a6782 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -635,7 +635,7 @@ void cWorld::GenerateRandomSpawn(void) { LOGD("Generating random spawnpoint..."); - while (IsBlockWater(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ))) + while (IsBlockWater(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ), true)) { if ((GetTickRandomNumber(4) % 2) == 0) // Randomise whether to increment X or Z coords { From dd325d742db9db54a25460fcacd093e7cc6f44f0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Feb 2014 21:44:23 +0000 Subject: [PATCH 12/30] Again improved LogReplaceLine * Fixed issues on Linux with cursor positioning * Made preprocessor blocks more readable * Improved reliability of line clearing on Windows - Removed an *unneeded* variable --- src/Log.cpp | 142 +++++++++++++++++++++++++++------------------------- src/Log.h | 1 - 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index aa9f22f84..a1b4c784f 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -9,7 +9,7 @@ #ifdef __linux #include -#include +#include #endif // __linux @@ -24,8 +24,7 @@ cLog* cLog::s_Log = NULL; cLog::cLog(const AString & a_FileName ) - : m_File(NULL), - m_LastStringSize(0) + : m_File(NULL) { s_Log = this; @@ -115,20 +114,22 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) time(&rawtime); struct tm* timeinfo; -#ifdef _MSC_VER - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime); -#else - timeinfo = localtime(&rawtime); -#endif + + #ifdef _MSC_VER + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime); + #else + timeinfo = localtime(&rawtime); + #endif AString Line; -#ifdef _DEBUG - Printf(Line, "[%04x|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); -#else - Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); -#endif + #ifdef _DEBUG + Printf(Line, "[%04x|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + #else + Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + #endif + if (m_File) { fprintf(m_File, "%s\n", Line.c_str()); @@ -136,67 +137,68 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) } // Print to console: -#if defined(ANDROID_NDK) - //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); - __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); - //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); -#else -#ifdef _WIN32 - size_t LineLength = Line.length(); + #if defined(ANDROID_NDK) + //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); + __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); + //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); + #else + + size_t LineLength = Line.length(); + #ifdef _WIN32 + HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); - if (m_LastStringSize == 0) - m_LastStringSize = LineLength; // Initialise m_LastStringSize + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(Output, &csbi); // Obtain console window information - HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); + if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) // Will text overrun width? If so, do not do a replace operation + { + printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, print normally with a newline + return false; + } - CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(Output, &csbi); + for (size_t X = 0; X != (size_t)(csbi.srWindow.Right - csbi.srWindow.Left); ++X) + { + fputs(" ", stdout); // Clear current line in preparation for new text + } + #else // _WIN32 + // Try to get console width; if text overruns, print normally with a newline + #ifdef TIOCGSIZE + struct ttysize ts; + ioctl(STDIN_FILENO, TIOCGSIZE, &ts); - if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) - { - printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, add a new line - return false; - } + if (ts.ts_cols < LineLength) + { + printf("\n%s", Line.c_str()); + return false; + } + #elif defined(TIOCGWINSZ) + struct winsize ts; + ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); - if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line - { - for (size_t X = 0; X != m_LastStringSize + 1; ++X) - { - fputs(" ", stdout); - } - } -#else // _WIN32 - struct ttysize ts; -#ifdef TIOCGSIZE - ioctl(STDIN_FILENO, TIOCGSIZE, &ts); - if (ts.ts_cols < LineLength) - { - return false; - } -#elif defined(TIOCGWINSZ) - ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); - if (ts.ts_cols < LineLength) - { - return false; - } -#else /* TIOCGSIZE */ - return false; -#endif - fputs("\033[K", stdout); // Clear current line -#endif - printf("\r%s", Line.c_str()); -#ifdef __linux - fputs("\033[1B", stdout); // Move down one line -#endif // __linux + if (ts.ws_col < LineLength) + { + printf("\n%s", Line.c_str()); + return false; + } + #else + printf("\n%s", Line.c_str()); + return false; + #endif - m_LastStringSize = LineLength; + fputs("\033[K", stdout); // Clear current line + #endif // Not _WIN32 -#endif // ANDROID_NDK + printf("\r%s", Line.c_str()); -#if defined (_WIN32) && defined(_DEBUG) - // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA((Line + "\n").c_str()); -#endif // _WIN32 + #ifdef __linux + fputs("\033[1B", stdout); // Move down one line + #endif // __linux + #endif // ANDROID_NDK + + #if defined (_WIN32) && defined(_DEBUG) + // In a Windows Debug build, output the log to debug console as well: + OutputDebugStringA((Line + "\n").c_str()); + #endif // _WIN32 return true; } @@ -241,7 +243,9 @@ void cLog::Log(const char * a_Format, va_list argList) __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else - printf("%s", Line.c_str()); + // If something requests the current line to be rewritten (LogReplaceLine), on Linux it clears the current line, but that moves the cursor to the end of that line, so we reset it here (\r) + // Doesn't affect anything normally - cursor should already be at beginning of line + printf("\r%s", Line.c_str()); #endif #if defined (_WIN32) && defined(_DEBUG) diff --git a/src/Log.h b/src/Log.h index c9ca17864..6944edd88 100644 --- a/src/Log.h +++ b/src/Log.h @@ -11,7 +11,6 @@ private: FILE * m_File; static cLog * s_Log; - size_t m_LastStringSize; public: From b89419f603126b9c8e01c607912b2976ba66ffda Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 12:47:17 +0000 Subject: [PATCH 13/30] Creative players take Plugin damage --- src/Entities/Entity.cpp | 3 ++- src/Entities/Player.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index e22f689d9..08780ca8b 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -397,6 +397,7 @@ int cEntity::GetArmorCoverAgainst(const cEntity * a_Attacker, eDamageType a_Dama case dtPotionOfHarming: case dtFalling: case dtLightning: + case dtPlugin: { return 0; } @@ -473,7 +474,7 @@ void cEntity::KilledBy(cEntity * a_Killer) return; } - // Drop loot: + // Drop loot: cItems Drops; GetDrops(Drops, a_Killer); m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ()); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 82e31ae65..ca0f0e770 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -784,11 +784,11 @@ void cPlayer::SetFlying(bool a_IsFlying) void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { - if (a_TDI.DamageType != dtInVoid) + if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtPlugin)) { if (IsGameModeCreative()) { - // No damage / health in creative mode if not void damage + // No damage / health in creative mode if not void or plugin damage return; } } From 55cfb232db9d7bf15dfa0d2e0816b4651331e2fd Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 19:10:22 +0000 Subject: [PATCH 14/30] Possibly fixed #618 --- src/World.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index 2571a6782..acfcf8e48 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1639,7 +1639,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_FlyAwaySpeed /= 100; // Pre-divide, so that we don't have to divide each time inside the loop for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) { - if (!IsValidItem(itr->m_ItemType)) + if (!IsValidItem(itr->m_ItemType) || itr->m_ItemType == E_BLOCK_AIR) { // Don't spawn pickup if item isn't even valid; should prevent client crashing too continue; @@ -1665,7 +1665,7 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double { for (cItems::const_iterator itr = a_Pickups.begin(); itr != a_Pickups.end(); ++itr) { - if (!IsValidItem(itr->m_ItemType)) + if (!IsValidItem(itr->m_ItemType) || itr->m_ItemType == E_BLOCK_AIR) { continue; } From e56d41175b7db000a87346bd1bb14f17ecc5a66a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 19:16:38 +0000 Subject: [PATCH 15/30] TNT improvements + Added entity damage + Added entity propulsion * Fixed #67 and fixed #230 --- src/BlockID.h | 1 + src/ChunkMap.cpp | 152 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 116 insertions(+), 37 deletions(-) diff --git a/src/BlockID.h b/src/BlockID.h index b31c589b9..f53440ec8 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -801,6 +801,7 @@ enum eDamageType dtPotionOfHarming, dtEnderPearl, // Thrown an ender pearl, teleported by it dtAdmin, // Damage applied by an admin command + dtExplosion, // Damage applied by an explosion // Some common synonyms: dtPawnAttack = dtAttack, diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 5797eb453..e23a29a11 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -15,6 +15,9 @@ #include "Blocks/BlockHandler.h" #include "MobCensus.h" #include "MobSpawner.h" +#include "BoundingBox.h" + +#include "Entities/Pickup.h" #ifndef _WIN32 #include // abs @@ -1624,49 +1627,52 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ { return; } - + + bool ShouldDestroyBlocks = true; + // Don't explode if the explosion center is inside a liquid block: - switch (m_World->GetBlock((int)floor(a_BlockX), (int)floor(a_BlockY), (int)floor(a_BlockZ))) + if (IsBlockLiquid(m_World->GetBlock((int)floor(a_BlockX), (int)floor(a_BlockY), (int)floor(a_BlockZ)))) { - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_LAVA: - case E_BLOCK_STATIONARY_LAVA: - { - return; - } + ShouldDestroyBlocks = false; } - - cBlockArea area; + + int ExplosionSizeInt = (int)ceil(a_ExplosionSize); + int ExplosionSizeSq = ExplosionSizeInt * ExplosionSizeInt; + int bx = (int)floor(a_BlockX); int by = (int)floor(a_BlockY); int bz = (int)floor(a_BlockZ); - int ExplosionSizeInt = (int) ceil(a_ExplosionSize); - int ExplosionSizeSq = ExplosionSizeInt * ExplosionSizeInt; - a_BlocksAffected.reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt); + int MinY = std::max((int)floor(a_BlockY - ExplosionSizeInt), 0); int MaxY = std::min((int)ceil(a_BlockY + ExplosionSizeInt), cChunkDef::Height - 1); - area.Read(m_World, bx - ExplosionSizeInt, (int)ceil(a_BlockX + ExplosionSizeInt), MinY, MaxY, bz - ExplosionSizeInt, (int)ceil(a_BlockZ + ExplosionSizeInt)); - for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++) + + if (ShouldDestroyBlocks) { - for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++) + cBlockArea area; + + a_BlocksAffected.reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt); + + area.Read(m_World, bx - ExplosionSizeInt, (int)ceil(a_BlockX + ExplosionSizeInt), MinY, MaxY, bz - ExplosionSizeInt, (int)ceil(a_BlockZ + ExplosionSizeInt)); + for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++) { - if ((by + y >= cChunkDef::Height) || (by + y < 0)) + for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++) { - // Outside of the world - continue; - } - for (int z = -ExplosionSizeInt; z < ExplosionSizeInt; z++) - { - if ((x * x + y * y + z * z) > ExplosionSizeSq) + if ((by + y >= cChunkDef::Height) || (by + y < 0)) { - // Too far away + // Outside of the world continue; } - - BLOCKTYPE Block = area.GetBlockType(bx + x, by + y, bz + z); - switch (Block) + for (int z = -ExplosionSizeInt; z < ExplosionSizeInt; z++) { + if ((x * x + y * y + z * z) > ExplosionSizeSq) + { + // Too far away + continue; + } + + BLOCKTYPE Block = area.GetBlockType(bx + x, by + y, bz + z); + switch (Block) + { case E_BLOCK_TNT: { // Activate the TNT, with a random fuse between 10 to 30 game ticks @@ -1691,20 +1697,20 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_WATER); break; } - + case E_BLOCK_STATIONARY_LAVA: { // Turn into simulated lava: area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_LAVA); break; } - + case E_BLOCK_AIR: { // No pickups for air break; } - + default: { if (m_World->GetTickRandomNumber(100) <= 25) // 25% chance of pickups @@ -1713,16 +1719,88 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ cBlockHandler * Handler = BlockHandler(Block); Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. - m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + //m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); } - } // switch (BlockType) - } // for z - } // for y - } // for x - area.Write(m_World, bx - ExplosionSizeInt, MinY, bz - ExplosionSizeInt); + } // switch (BlockType) + } // for z + } // for y + } // for x + area.Write(m_World, bx - ExplosionSizeInt, MinY, bz - ExplosionSizeInt); + } + + class cTNTDamageCallback : + public cEntityCallback + { + public: + cTNTDamageCallback(cBoundingBox & a_bbTNT, Vector3d a_ExplosionPos, int a_ExplosionSize, int a_ExplosionSizeSq) : + m_bbTNT(a_bbTNT), + m_ExplosionPos(a_ExplosionPos), + m_ExplosionSize(a_ExplosionSize), + m_ExplosionSizeSq(a_ExplosionSizeSq) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + if (a_Entity->IsPickup()) + { + if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible + { + return false; + } + } + + Vector3d EntityPos = a_Entity->GetPosition(); + cBoundingBox bbEntity(EntityPos, a_Entity->GetWidth() / 2, a_Entity->GetHeight()); + + if (m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround + { + Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); + Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); + + AbsoluteEntityPos -= m_ExplosionPos; + AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; + + double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; + FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + if (FinalDamage > a_Entity->GetMaxHealth()) + FinalDamage = a_Entity->GetMaxHealth(); + else if (FinalDamage < 0) + return false; + + if (!a_Entity->IsTNT()) + { + a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); + } + + Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; + if (distance_explosion.SqrLength() < 4096.0) + { + distance_explosion.Normalize(); + distance_explosion *= m_ExplosionSizeSq; + + a_Entity->AddSpeed(distance_explosion); + } + } + return false; + } + + protected: + cBoundingBox & m_bbTNT; + Vector3d m_ExplosionPos; + int m_ExplosionSize; + int m_ExplosionSizeSq; + }; + + cBoundingBox bbTNT(Vector3d(a_BlockX, a_BlockY, a_BlockZ), 0.5, 1); + bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); + + + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSize, ExplosionSizeSq); + ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): WakeUpSimulatorsInArea( From 5bf060f06c7ee2d7ffa6a86b2e15acc4d472a9da Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:09:15 +0000 Subject: [PATCH 16/30] Revert "Again improved LogReplaceLine" This reverts commit dd325d742db9db54a25460fcacd093e7cc6f44f0. --- src/Log.cpp | 142 +++++++++++++++++++++++++--------------------------- src/Log.h | 1 + 2 files changed, 70 insertions(+), 73 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index a1b4c784f..aa9f22f84 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -9,7 +9,7 @@ #ifdef __linux #include -#include +#include #endif // __linux @@ -24,7 +24,8 @@ cLog* cLog::s_Log = NULL; cLog::cLog(const AString & a_FileName ) - : m_File(NULL) + : m_File(NULL), + m_LastStringSize(0) { s_Log = this; @@ -114,22 +115,20 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) time(&rawtime); struct tm* timeinfo; - - #ifdef _MSC_VER - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime); - #else - timeinfo = localtime(&rawtime); - #endif +#ifdef _MSC_VER + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime); +#else + timeinfo = localtime(&rawtime); +#endif AString Line; - #ifdef _DEBUG - Printf(Line, "[%04x|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #else - Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #endif - +#ifdef _DEBUG + Printf(Line, "[%04x|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); +#else + Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); +#endif if (m_File) { fprintf(m_File, "%s\n", Line.c_str()); @@ -137,68 +136,67 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) } // Print to console: - #if defined(ANDROID_NDK) - //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); - __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); - //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); - #else - - size_t LineLength = Line.length(); - #ifdef _WIN32 - HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); +#if defined(ANDROID_NDK) + //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); + __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); + //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); +#else +#ifdef _WIN32 + size_t LineLength = Line.length(); - CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(Output, &csbi); // Obtain console window information + if (m_LastStringSize == 0) + m_LastStringSize = LineLength; // Initialise m_LastStringSize - if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) // Will text overrun width? If so, do not do a replace operation - { - printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, print normally with a newline - return false; - } + HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); - for (size_t X = 0; X != (size_t)(csbi.srWindow.Right - csbi.srWindow.Left); ++X) - { - fputs(" ", stdout); // Clear current line in preparation for new text - } - #else // _WIN32 - // Try to get console width; if text overruns, print normally with a newline - #ifdef TIOCGSIZE - struct ttysize ts; - ioctl(STDIN_FILENO, TIOCGSIZE, &ts); + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(Output, &csbi); - if (ts.ts_cols < LineLength) - { - printf("\n%s", Line.c_str()); - return false; - } - #elif defined(TIOCGWINSZ) - struct winsize ts; - ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); + if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) + { + printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, add a new line + return false; + } - if (ts.ws_col < LineLength) - { - printf("\n%s", Line.c_str()); - return false; - } - #else - printf("\n%s", Line.c_str()); - return false; - #endif + if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line + { + for (size_t X = 0; X != m_LastStringSize + 1; ++X) + { + fputs(" ", stdout); + } + } +#else // _WIN32 + struct ttysize ts; +#ifdef TIOCGSIZE + ioctl(STDIN_FILENO, TIOCGSIZE, &ts); + if (ts.ts_cols < LineLength) + { + return false; + } +#elif defined(TIOCGWINSZ) + ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); + if (ts.ts_cols < LineLength) + { + return false; + } +#else /* TIOCGSIZE */ + return false; +#endif + fputs("\033[K", stdout); // Clear current line +#endif + printf("\r%s", Line.c_str()); +#ifdef __linux + fputs("\033[1B", stdout); // Move down one line +#endif // __linux - fputs("\033[K", stdout); // Clear current line - #endif // Not _WIN32 + m_LastStringSize = LineLength; - printf("\r%s", Line.c_str()); +#endif // ANDROID_NDK - #ifdef __linux - fputs("\033[1B", stdout); // Move down one line - #endif // __linux - #endif // ANDROID_NDK - - #if defined (_WIN32) && defined(_DEBUG) - // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA((Line + "\n").c_str()); - #endif // _WIN32 +#if defined (_WIN32) && defined(_DEBUG) + // In a Windows Debug build, output the log to debug console as well: + OutputDebugStringA((Line + "\n").c_str()); +#endif // _WIN32 return true; } @@ -243,9 +241,7 @@ void cLog::Log(const char * a_Format, va_list argList) __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else - // If something requests the current line to be rewritten (LogReplaceLine), on Linux it clears the current line, but that moves the cursor to the end of that line, so we reset it here (\r) - // Doesn't affect anything normally - cursor should already be at beginning of line - printf("\r%s", Line.c_str()); + printf("%s", Line.c_str()); #endif #if defined (_WIN32) && defined(_DEBUG) diff --git a/src/Log.h b/src/Log.h index 6944edd88..c9ca17864 100644 --- a/src/Log.h +++ b/src/Log.h @@ -11,6 +11,7 @@ private: FILE * m_File; static cLog * s_Log; + size_t m_LastStringSize; public: From a0242afec23ed0f3328410e6d2d6336ec61a5d51 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:09:35 +0000 Subject: [PATCH 17/30] Revert "Another Linux fix" This reverts commit 6f660b379ecbc091b9bd92093e0dad01a4f6bf38. --- src/Log.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index aa9f22f84..44dab33c9 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -7,12 +7,6 @@ #include #include "OSSupport/IsThread.h" -#ifdef __linux -#include -#include -#endif // __linux - - #if defined(ANDROID_NDK) #include #include "ToJava.h" From 070962fb8a09e86a26fe6f1d517ff94787675489 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:09:40 +0000 Subject: [PATCH 18/30] Revert "Fixed Linux compile" This reverts commit 5becfe850a2b4827a21e8ede989545334efbbead. --- src/Log.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index 44dab33c9..b246e8196 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -135,7 +135,6 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else -#ifdef _WIN32 size_t LineLength = Line.length(); if (m_LastStringSize == 0) @@ -151,7 +150,7 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, add a new line return false; } - +#ifdef _WIN32 if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line { for (size_t X = 0; X != m_LastStringSize + 1; ++X) From e4b666989d67b9ec824fe0ac9f7c4f880486d72b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:09:47 +0000 Subject: [PATCH 19/30] Revert "A newline issue is resolved" This reverts commit 397208145ebe5c95ebf32f2985f6800634932230. --- src/Log.cpp | 2 +- src/MCLogger.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Log.cpp b/src/Log.cpp index b246e8196..e7d3e0629 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -147,7 +147,7 @@ bool cLog::LogReplaceLine(const char * a_Format, va_list argList) if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) { - printf("\n%s", Line.c_str()); // We are at line to be replaced, but since we can't, add a new line + printf("\r%s", Line.c_str()); return false; } #ifdef _WIN32 diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 11fd451a7..0828b7fe4 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -150,6 +150,7 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) { m_BeginLineUpdate = false; + puts(""); } ResetColor(); @@ -161,6 +162,7 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) { m_BeginLineUpdate = false; + puts(""); } ResetColor(); #endif From dd3cc733ae882d029eaab093113783fb1c91113a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:09:56 +0000 Subject: [PATCH 20/30] Revert "Fixed issues with insufficient console space" This reverts commit 6b18add09b5e9d6d6c2a61e90bdd7011f56f4c82. --- src/Log.cpp | 140 ++++++++++++----------------------------------- src/Log.h | 11 +--- src/MCLogger.cpp | 14 +---- 3 files changed, 40 insertions(+), 125 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index e7d3e0629..3938f2c24 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -100,105 +100,7 @@ void cLog::ClearLog() -bool cLog::LogReplaceLine(const char * a_Format, va_list argList) -{ - AString Message; - AppendVPrintf(Message, a_Format, argList); - - time_t rawtime; - time(&rawtime); - - struct tm* timeinfo; -#ifdef _MSC_VER - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime); -#else - timeinfo = localtime(&rawtime); -#endif - - AString Line; -#ifdef _DEBUG - Printf(Line, "[%04x|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); -#else - Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); -#endif - if (m_File) - { - fprintf(m_File, "%s\n", Line.c_str()); - fflush(m_File); - } - - // Print to console: -#if defined(ANDROID_NDK) - //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); - __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); - //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); -#else - size_t LineLength = Line.length(); - - if (m_LastStringSize == 0) - m_LastStringSize = LineLength; // Initialise m_LastStringSize - - HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(Output, &csbi); - - if ((size_t)((csbi.srWindow.Right - csbi.srWindow.Left) + 1) < LineLength) - { - printf("\r%s", Line.c_str()); - return false; - } -#ifdef _WIN32 - if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line - { - for (size_t X = 0; X != m_LastStringSize + 1; ++X) - { - fputs(" ", stdout); - } - } -#else // _WIN32 - struct ttysize ts; -#ifdef TIOCGSIZE - ioctl(STDIN_FILENO, TIOCGSIZE, &ts); - if (ts.ts_cols < LineLength) - { - return false; - } -#elif defined(TIOCGWINSZ) - ioctl(STDIN_FILENO, TIOCGWINSZ, &ts); - if (ts.ts_cols < LineLength) - { - return false; - } -#else /* TIOCGSIZE */ - return false; -#endif - fputs("\033[K", stdout); // Clear current line -#endif - printf("\r%s", Line.c_str()); -#ifdef __linux - fputs("\033[1B", stdout); // Move down one line -#endif // __linux - - m_LastStringSize = LineLength; - -#endif // ANDROID_NDK - -#if defined (_WIN32) && defined(_DEBUG) - // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA((Line + "\n").c_str()); -#endif // _WIN32 - - return true; -} - - - - - -void cLog::Log(const char * a_Format, va_list argList) +void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine) { AString Message; AppendVPrintf(Message, a_Format, argList); @@ -221,7 +123,6 @@ void cLog::Log(const char * a_Format, va_list argList) #else Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #endif - if (m_File) { fprintf(m_File, "%s\n", Line.c_str()); @@ -229,13 +130,44 @@ void cLog::Log(const char * a_Format, va_list argList) } // Print to console: - #if defined(ANDROID_NDK) +#if defined(ANDROID_NDK) //__android_log_vprint(ANDROID_LOG_ERROR,"MCServer", a_Format, argList); __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); - #else - printf("%s", Line.c_str()); - #endif +#else + size_t LineLength = Line.length(); + + if (m_LastStringSize == 0) + m_LastStringSize = LineLength; // Initialise m_LastStringSize + + if (a_ReplaceCurrentLine) + { +#ifdef _WIN32 + if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line + { + for (size_t X = 0; X != m_LastStringSize; ++X) + { + fputs(" ", stdout); + } + } +#else // _WIN32 + fputs("\033[K", stdout); // Clear current line +#endif + + printf("\r%s", Line.c_str()); + +#ifdef __linux + fputs("\033[1B", stdout); // Move down one line +#endif // __linux + } + else + { + printf("%s", Line.c_str()); + } + + m_LastStringSize = LineLength; + +#endif #if defined (_WIN32) && defined(_DEBUG) // In a Windows Debug build, output the log to debug console as well: diff --git a/src/Log.h b/src/Log.h index c9ca17864..8a0ee9fc7 100644 --- a/src/Log.h +++ b/src/Log.h @@ -8,29 +8,20 @@ class cLog { // tolua_export private: - FILE * m_File; static cLog * s_Log; size_t m_LastStringSize; - public: - cLog(const AString & a_FileName); ~cLog(); - - /** Replaces current line of console with given text. - Returns true if successful, false if not (screen too narrow etc.) */ - bool LogReplaceLine(const char * a_Format, va_list argList); - void Log(const char * a_Format, va_list argList); + void Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine = false); void Log(const char * a_Format, ...); - // tolua_begin void SimpleLog(const char * a_String); void OpenLog(const char * a_FileName); void CloseLog(); void ClearLog(); static cLog* GetInstance(); - }; // tolua_end diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 0828b7fe4..b7b826374 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -147,11 +147,7 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla SetConsoleCursorPosition(Output, Position); SetColor(csRegular); - if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) - { - m_BeginLineUpdate = false; - puts(""); - } + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); ResetColor(); Position = { 0, csbi.dwCursorPosition.Y }; // Set cursor to original position @@ -159,18 +155,14 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla #else // _WIN32 fputs("\033[1A", stdout); // Move cursor up one line SetColor(csRegular); - if (!m_Log->LogReplaceLine(a_Format, a_ArgList)) - { - m_BeginLineUpdate = false; - puts(""); - } + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); ResetColor(); #endif } else { SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList); + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); ResetColor(); puts(""); } From ecbb9134a5e4c631fc10cb9251d0d18de80d6b36 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:10:02 +0000 Subject: [PATCH 21/30] Revert "Properly initialised variables" This reverts commit 02e752789399ad1b65a0443534ea6a8721efd78c. --- src/Log.cpp | 3 +-- src/Log.h | 2 +- src/MCLogger.cpp | 14 ++++++++------ src/MCLogger.h | 4 ---- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index 3938f2c24..cbb83097c 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -18,8 +18,7 @@ cLog* cLog::s_Log = NULL; cLog::cLog(const AString & a_FileName ) - : m_File(NULL), - m_LastStringSize(0) + : m_File(NULL) { s_Log = this; diff --git a/src/Log.h b/src/Log.h index 8a0ee9fc7..c8c26913b 100644 --- a/src/Log.h +++ b/src/Log.h @@ -10,7 +10,7 @@ class cLog private: FILE * m_File; static cLog * s_Log; - size_t m_LastStringSize; + size_t m_LastStringSize = 0; public: cLog(const AString & a_FileName); ~cLog(); diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index b7b826374..aebe3e1c9 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -11,6 +11,10 @@ cMCLogger * cMCLogger::s_MCLogger = NULL; bool g_ShouldColorOutput = false; +/** Flag to show whether a 'replace line' log command has been issued +Used to decide when to put a newline */ +bool g_BeginLineUpdate = false; + #ifdef _WIN32 #include // Needed for _isatty(), not available on Linux @@ -34,7 +38,6 @@ cMCLogger * cMCLogger::GetInstance(void) cMCLogger::cMCLogger(void) - : m_BeginLineUpdate(false) { AString FileName; Printf(FileName, "LOG_%d.txt", (int)time(NULL)); @@ -46,7 +49,6 @@ cMCLogger::cMCLogger(void) cMCLogger::cMCLogger(const AString & a_FileName) - : m_BeginLineUpdate(false) { InitLog(a_FileName); } @@ -125,14 +127,14 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla { cCSLock Lock(m_CriticalSection); - if (!m_BeginLineUpdate && a_ShouldReplaceLine) + if (!g_BeginLineUpdate && a_ShouldReplaceLine) { a_ShouldReplaceLine = false; // Print a normal line first if this is the initial replace line - m_BeginLineUpdate = true; + g_BeginLineUpdate = true; } - else if (m_BeginLineUpdate && !a_ShouldReplaceLine) + else if (g_BeginLineUpdate && !a_ShouldReplaceLine) { - m_BeginLineUpdate = false; + g_BeginLineUpdate = false; } if (a_ShouldReplaceLine) diff --git a/src/MCLogger.h b/src/MCLogger.h index 4550cc55d..c105ab6e2 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -51,10 +51,6 @@ private: /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this void InitLog(const AString & a_FileName); - - /** Flag to show whether a 'replace line' log command has been issued - Used to decide when to put a newline */ - bool m_BeginLineUpdate; }; // tolua_export From f4c25ac445c95502ae95a0023fc67f3aa394d594 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:10:13 +0000 Subject: [PATCH 22/30] Revert "Added a comment" This reverts commit 7ae5631d89426df6f05b6c8ba656ba02b9d15f93. --- src/Log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Log.cpp b/src/Log.cpp index cbb83097c..37f1376db 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -137,7 +137,7 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine size_t LineLength = Line.length(); if (m_LastStringSize == 0) - m_LastStringSize = LineLength; // Initialise m_LastStringSize + m_LastStringSize = LineLength; if (a_ReplaceCurrentLine) { From 6ef5c057aa2a36dbd54f56780e5700e753b37bcf Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:10:23 +0000 Subject: [PATCH 23/30] Revert "Improved code" This reverts commit d8aa0b0ec7a2ebea2fc157c623ae8cd7d0b6ba1c. --- src/Log.cpp | 14 +++++--------- src/MCLogger.cpp | 12 ++++-------- src/MCLogger.h | 4 ++++ src/World.cpp | 2 -- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index 37f1376db..a23a79ccc 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -134,15 +134,14 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else - size_t LineLength = Line.length(); - - if (m_LastStringSize == 0) - m_LastStringSize = LineLength; - if (a_ReplaceCurrentLine) { #ifdef _WIN32 - if (LineLength < m_LastStringSize) // If last printed line was longer than current, clear this line + if (m_LastStringSize == 0) + { + m_LastStringSize = Line.length(); + } + else if (Line.length() < m_LastStringSize) // If last printed line was longer than current, clear this line { for (size_t X = 0; X != m_LastStringSize; ++X) { @@ -163,9 +162,6 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine { printf("%s", Line.c_str()); } - - m_LastStringSize = LineLength; - #endif #if defined (_WIN32) && defined(_DEBUG) diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index aebe3e1c9..632ea2efe 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -11,10 +11,6 @@ cMCLogger * cMCLogger::s_MCLogger = NULL; bool g_ShouldColorOutput = false; -/** Flag to show whether a 'replace line' log command has been issued -Used to decide when to put a newline */ -bool g_BeginLineUpdate = false; - #ifdef _WIN32 #include // Needed for _isatty(), not available on Linux @@ -127,14 +123,14 @@ void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldRepla { cCSLock Lock(m_CriticalSection); - if (!g_BeginLineUpdate && a_ShouldReplaceLine) + if (!m_BeginLineUpdate && a_ShouldReplaceLine) { a_ShouldReplaceLine = false; // Print a normal line first if this is the initial replace line - g_BeginLineUpdate = true; + m_BeginLineUpdate = true; } - else if (g_BeginLineUpdate && !a_ShouldReplaceLine) + else if (m_BeginLineUpdate && !a_ShouldReplaceLine) { - g_BeginLineUpdate = false; + m_BeginLineUpdate = false; } if (a_ShouldReplaceLine) diff --git a/src/MCLogger.h b/src/MCLogger.h index c105ab6e2..7bcc195dd 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -51,6 +51,10 @@ private: /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this void InitLog(const AString & a_FileName); + + /** Flag to show whether a 'replace line' log command has been issued + Used to decide when to put a newline */ + bool m_BeginLineUpdate = false; }; // tolua_export diff --git a/src/World.cpp b/src/World.cpp index acfcf8e48..5cd3e1478 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -111,7 +111,6 @@ protected: cSleep::MilliSleep(100); if (m_ShouldTerminate) { - LOGREPLACELINE("World successfully loaded!"); return; } } @@ -162,7 +161,6 @@ protected: cSleep::MilliSleep(100); if (m_ShouldTerminate) { - LOGREPLACELINE("Lighting successful!"); return; } } From d9a9052de733d88e49a2df9f455632c64f2c5b5d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 20:10:31 +0000 Subject: [PATCH 24/30] Revert "Added LOGREPLACELINE for line replacement" This reverts commit 7d03876a3e11aedff0201a8330bfdb2b5523fc5e. --- src/Log.cpp | 31 ++------------------------ src/Log.h | 4 ++-- src/MCLogger.cpp | 58 +++++------------------------------------------- src/MCLogger.h | 7 +----- src/World.cpp | 10 ++++----- 5 files changed, 16 insertions(+), 94 deletions(-) diff --git a/src/Log.cpp b/src/Log.cpp index a23a79ccc..2d6be0f59 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -99,7 +99,7 @@ void cLog::ClearLog() -void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine) +void cLog::Log(const char * a_Format, va_list argList) { AString Message; AppendVPrintf(Message, a_Format, argList); @@ -134,34 +134,7 @@ void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else - if (a_ReplaceCurrentLine) - { -#ifdef _WIN32 - if (m_LastStringSize == 0) - { - m_LastStringSize = Line.length(); - } - else if (Line.length() < m_LastStringSize) // If last printed line was longer than current, clear this line - { - for (size_t X = 0; X != m_LastStringSize; ++X) - { - fputs(" ", stdout); - } - } -#else // _WIN32 - fputs("\033[K", stdout); // Clear current line -#endif - - printf("\r%s", Line.c_str()); - -#ifdef __linux - fputs("\033[1B", stdout); // Move down one line -#endif // __linux - } - else - { - printf("%s", Line.c_str()); - } + printf("%s", Line.c_str()); #endif #if defined (_WIN32) && defined(_DEBUG) diff --git a/src/Log.h b/src/Log.h index c8c26913b..cba248dae 100644 --- a/src/Log.h +++ b/src/Log.h @@ -10,11 +10,11 @@ class cLog private: FILE * m_File; static cLog * s_Log; - size_t m_LastStringSize = 0; + public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine = false); + 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/MCLogger.cpp b/src/MCLogger.cpp index 632ea2efe..4f3e5dc0f 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -119,51 +119,13 @@ void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) -void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldReplaceLine) +void cMCLogger::Log(const char * a_Format, va_list a_ArgList) { cCSLock Lock(m_CriticalSection); - - if (!m_BeginLineUpdate && a_ShouldReplaceLine) - { - a_ShouldReplaceLine = false; // Print a normal line first if this is the initial replace line - m_BeginLineUpdate = true; - } - else if (m_BeginLineUpdate && !a_ShouldReplaceLine) - { - m_BeginLineUpdate = false; - } - - if (a_ShouldReplaceLine) - { -#ifdef _WIN32 - HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(Output, &csbi); - - COORD Position = { 0, csbi.dwCursorPosition.Y - 1 }; // Move cursor up one line - SetConsoleCursorPosition(Output, Position); - - SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); - ResetColor(); - - Position = { 0, csbi.dwCursorPosition.Y }; // Set cursor to original position - SetConsoleCursorPosition(Output, Position); -#else // _WIN32 - fputs("\033[1A", stdout); // Move cursor up one line - SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); - ResetColor(); -#endif - } - else - { - SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); - ResetColor(); - puts(""); - } + SetColor(csRegular); + m_Log->Log(a_Format, a_ArgList); + ResetColor(); + puts(""); } @@ -226,7 +188,7 @@ void cMCLogger::SetColor(eColorScheme a_Scheme) default: ASSERT(!"Unhandled color scheme"); } SetConsoleTextAttribute(g_Console, Attrib); - #elif (defined(__linux) || defined(__apple)) && !defined(ANDROID_NDK) + #elif defined(__linux) && !defined(ANDROID_NDK) switch (a_Scheme) { case csRegular: printf("\x1b[0m"); break; // Whatever the console default is @@ -262,14 +224,6 @@ void cMCLogger::ResetColor(void) ////////////////////////////////////////////////////////////////////////// // Global functions -void LOGREPLACELINE(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Log(a_Format, argList, true); - va_end(argList); -} - void LOG(const char* a_Format, ...) { va_list argList; diff --git a/src/MCLogger.h b/src/MCLogger.h index 7bcc195dd..c949a4cdf 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -21,7 +21,7 @@ public: // tolua_export ~cMCLogger(); // tolua_export - void Log(const char* a_Format, va_list a_ArgList, bool a_ShouldReplaceLine = false); + void Log(const char* a_Format, va_list a_ArgList); void Info(const char* a_Format, va_list a_ArgList); void Warn(const char* a_Format, va_list a_ArgList); void Error(const char* a_Format, va_list a_ArgList); @@ -51,17 +51,12 @@ private: /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this void InitLog(const AString & a_FileName); - - /** Flag to show whether a 'replace line' log command has been issued - Used to decide when to put a newline */ - bool m_BeginLineUpdate = false; }; // tolua_export -extern void LOGREPLACELINE(const char* a_Format, ...); extern void LOG(const char* a_Format, ...); extern void LOGINFO(const char* a_Format, ...); extern void LOGWARN(const char* a_Format, ...); diff --git a/src/World.cpp b/src/World.cpp index 5cd3e1478..f598874ea 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -100,13 +100,13 @@ protected: { for (;;) { - LOGREPLACELINE("%d chunks to load, %d chunks to generate", + LOG("%d chunks to load, %d chunks to generate", m_World->GetStorage().GetLoadQueueLength(), m_World->GetGenerator().GetQueueLength() ); - // Wait for 0.5 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 5; i++) + // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish + for (int i = 0; i < 20; i++) { cSleep::MilliSleep(100); if (m_ShouldTerminate) @@ -152,10 +152,10 @@ protected: { for (;;) { - LOGREPLACELINE("%d chunks remaining to light", m_Lighting->GetQueueLength() + LOG("%d chunks remaining to light", m_Lighting->GetQueueLength() ); - // Wait for 0.5 sec, but be "reasonably wakeable" when the thread is to finish + // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish for (int i = 0; i < 20; i++) { cSleep::MilliSleep(100); From ba398c06d78f6e11e7ac322e5ef46df4a91b5776 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 21:24:06 +0000 Subject: [PATCH 25/30] Uncommented pickup spawner code --- src/ChunkMap.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index e23a29a11..53e5b956b 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1719,7 +1719,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ cBlockHandler * Handler = BlockHandler(Block); Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. - //m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); @@ -1747,7 +1747,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ { if (a_Entity->IsPickup()) { - if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible + if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned) { return false; } @@ -1761,21 +1761,25 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); + // Work out how far we are from the edge of the TNT's explosive effect AbsoluteEntityPos -= m_ExplosionPos; AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + + // Clip damage values if (FinalDamage > a_Entity->GetMaxHealth()) FinalDamage = a_Entity->GetMaxHealth(); else if (FinalDamage < 0) return false; - if (!a_Entity->IsTNT()) + if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible { a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); } + // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; if (distance_explosion.SqrLength() < 4096.0) { From 0f67f80c6e60b2696bf94ee91330cdc0cefde3fa Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 21:48:21 +0000 Subject: [PATCH 26/30] Added IsBlockWaterOrIce() --- src/Defines.h | 20 +++++++++++--------- src/World.cpp | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Defines.h b/src/Defines.h index b3dbcc93e..5b868b2e5 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -254,16 +254,18 @@ inline bool IsValidItem(int a_ItemType) -inline bool IsBlockWater(BLOCKTYPE a_BlockType, bool a_IncludeFrozenWater = false) +inline bool IsBlockWater(BLOCKTYPE a_BlockType) { - if (a_IncludeFrozenWater) - { - return ((a_BlockType == E_BLOCK_WATER) || (a_BlockType == E_BLOCK_STATIONARY_WATER) || (a_BlockType == E_BLOCK_ICE)); - } - else - { - return ((a_BlockType == E_BLOCK_WATER) || (a_BlockType == E_BLOCK_STATIONARY_WATER)); - } + return ((a_BlockType == E_BLOCK_WATER) || (a_BlockType == E_BLOCK_STATIONARY_WATER)); +} + + + + + +inline bool IsBlockWaterOrIce(BLOCKTYPE a_BlockType) +{ + return (IsBlockWater(a_BlockType) || (a_BlockType == E_BLOCK_ICE)); } diff --git a/src/World.cpp b/src/World.cpp index f598874ea..d8850e78a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -633,7 +633,7 @@ void cWorld::GenerateRandomSpawn(void) { LOGD("Generating random spawnpoint..."); - while (IsBlockWater(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ), true)) + while (IsBlockWaterOrIce(GetBlock((int)m_SpawnX, GetHeight((int)m_SpawnX, (int)m_SpawnZ), (int)m_SpawnZ))) { if ((GetTickRandomNumber(4) % 2) == 0) // Randomise whether to increment X or Z coords { From c2c1639af8f9db9bdd0f720c0e748c98d2835b5c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 2 Feb 2014 22:43:39 +0100 Subject: [PATCH 27/30] Groups.ini can contain spaces around commas in values. This includes Permissions, Inherits and Commands. Also fixed an unlikely but possible crash with group colors. --- src/GroupManager.cpp | 48 ++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index 497f98c93..d5567d91e 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -69,47 +69,51 @@ cGroupManager::cGroupManager() } unsigned int NumKeys = IniFile.GetNumKeys(); - for( unsigned int i = 0; i < NumKeys; i++ ) + for (size_t i = 0; i < NumKeys; i++) { std::string KeyName = IniFile.GetKeyName( i ); cGroup* Group = GetGroup( KeyName.c_str() ); LOGD("Loading group: %s", KeyName.c_str() ); - Group->SetName( KeyName ); - char Color = IniFile.GetValue( KeyName, "Color", "-" )[0]; - if( Color != '-' ) - Group->SetColor( cChatColor::Color + Color ); + Group->SetName(KeyName); + AString Color = IniFile.GetValue(KeyName, "Color", "-"); + if ((Color != "-") && (Color.length() >= 1)) + { + Group->SetColor(cChatColor::Color + Color[0]); + } else - Group->SetColor( cChatColor::White ); - - AString Commands = IniFile.GetValue( KeyName, "Commands", "" ); - if( Commands.size() > 0 ) { - AStringVector Split = StringSplit( Commands, "," ); - for( unsigned int i = 0; i < Split.size(); i++) + Group->SetColor(cChatColor::White); + } + + AString Commands = IniFile.GetValue(KeyName, "Commands", ""); + if (!Commands.empty()) + { + AStringVector Split = StringSplitAndTrim(Commands, ","); + for (size_t i = 0; i < Split.size(); i++) { - Group->AddCommand( Split[i] ); + Group->AddCommand(Split[i]); } } - AString Permissions = IniFile.GetValue( KeyName, "Permissions", "" ); - if( Permissions.size() > 0 ) + AString Permissions = IniFile.GetValue(KeyName, "Permissions", ""); + if (!Permissions.empty()) { - AStringVector Split = StringSplit( Permissions, "," ); - for( unsigned int i = 0; i < Split.size(); i++) + AStringVector Split = StringSplitAndTrim(Permissions, ","); + for (size_t i = 0; i < Split.size(); i++) { - Group->AddPermission( Split[i] ); + Group->AddPermission(Split[i]); } } - std::string Groups = IniFile.GetValue( KeyName, "Inherits", "" ); - if( Groups.size() > 0 ) + std::string Groups = IniFile.GetValue(KeyName, "Inherits", ""); + if (!Groups.empty()) { - AStringVector Split = StringSplit( Groups, "," ); - for( unsigned int i = 0; i < Split.size(); i++) + AStringVector Split = StringSplitAndTrim(Groups, ","); + for (size_t i = 0; i < Split.size(); i++) { - Group->InheritFrom( GetGroup( Split[i].c_str() ) ); + Group->InheritFrom(GetGroup(Split[i].c_str())); } } } From 0b384198e535470ac4aaa7d8f38b3da62b12ea34 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 3 Feb 2014 10:38:25 +0100 Subject: [PATCH 28/30] SocketThreads: Fixed sending to closed socket. --- src/OSSupport/SocketThreads.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index 3e2631733..269f1d452 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -557,6 +557,11 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) } } // if (outgoing data is empty) + if (m_Slots[i].m_State == sSlot::ssRemoteClosed) + { + continue; + } + if (!SendDataThroughSocket(m_Slots[i].m_Socket, m_Slots[i].m_Outgoing)) { int Err = cSocket::GetLastError(); @@ -566,7 +571,7 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) { m_Slots[i].m_Client->SocketClosed(); } - return; + continue; } if (m_Slots[i].m_Outgoing.empty() && (m_Slots[i].m_State == sSlot::ssWritingRestOut)) From e3b9cdebc9c07a548c4aa219d53cf53c2c111b48 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 14:01:47 +0000 Subject: [PATCH 29/30] Inversed condition --- src/ChunkMap.cpp | 65 +++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 53e5b956b..4511391ff 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1756,39 +1756,42 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Vector3d EntityPos = a_Entity->GetPosition(); cBoundingBox bbEntity(EntityPos, a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - if (m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround + if (!m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround { - Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); - Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); - - // Work out how far we are from the edge of the TNT's explosive effect - AbsoluteEntityPos -= m_ExplosionPos; - AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; - - double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; - FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); - - // Clip damage values - if (FinalDamage > a_Entity->GetMaxHealth()) - FinalDamage = a_Entity->GetMaxHealth(); - else if (FinalDamage < 0) - return false; - - if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible - { - a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); - } - - // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() - Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; - if (distance_explosion.SqrLength() < 4096.0) - { - distance_explosion.Normalize(); - distance_explosion *= m_ExplosionSizeSq; - - a_Entity->AddSpeed(distance_explosion); - } + return false; } + + Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); + Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); + + // Work out how far we are from the edge of the TNT's explosive effect + AbsoluteEntityPos -= m_ExplosionPos; + AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; + + double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; + FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + + // Clip damage values + if (FinalDamage > a_Entity->GetMaxHealth()) + FinalDamage = a_Entity->GetMaxHealth(); + else if (FinalDamage < 0) + return false; + + if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible + { + a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); + } + + // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() + Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; + if (distance_explosion.SqrLength() < 4096.0) + { + distance_explosion.Normalize(); + distance_explosion *= m_ExplosionSizeSq; + + a_Entity->AddSpeed(distance_explosion); + } + return false; } From c9916cd8c2332b6d6992ab38c0339ced6c91bc92 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 3 Feb 2014 17:07:46 +0100 Subject: [PATCH 30/30] Fixed socket leaking. --- src/OSSupport/SocketThreads.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index 269f1d452..a02661d2c 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -209,6 +209,10 @@ bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client) if (m_Slots[i].m_State == sSlot::ssRemoteClosed) { // The remote has already closed the socket, remove the slot altogether: + if (m_Slots[i].m_Socket.IsValid()) + { + m_Slots[i].m_Socket.CloseSocket(); + } m_Slots[i] = m_Slots[--m_NumSlots]; } else @@ -489,6 +493,7 @@ void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) // Notify the callback that the remote has closed the socket; keep the slot m_Slots[i].m_Client->SocketClosed(); m_Slots[i].m_State = sSlot::ssRemoteClosed; + m_Slots[i].m_Socket.CloseSocket(); break; } case sSlot::ssWritingRestOut: