summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt194
-rw-r--r--COMPILING.md4
-rw-r--r--MCServer/.gitignore1
-rw-r--r--MCServer/Plugins/Debuggers/Debuggers.lua23
-rw-r--r--SetFlags.cmake189
-rw-r--r--Tools/MCADefrag/CMakeLists.txt81
-rw-r--r--Tools/ProtoProxy/CMakeLists.txt80
-rw-r--r--lib/polarssl.cmake5
-rw-r--r--lib/tolua++/CMakeLists.txt2
-rw-r--r--lib/zlib/CMakeLists.txt14
-rw-r--r--src/Bindings/AllToLua.pkg1
-rw-r--r--src/ClientHandle.cpp13
-rw-r--r--src/ClientHandle.h11
-rw-r--r--src/CompositeChat.cpp206
-rw-r--r--src/CompositeChat.h172
-rw-r--r--src/Defines.h9
-rw-r--r--src/Entities/ExpOrb.cpp7
-rw-r--r--src/Entities/Player.cpp14
-rw-r--r--src/Entities/Player.h1
-rw-r--r--src/Entities/ProjectileEntity.cpp1
-rw-r--r--src/Protocol/Protocol.h2
-rw-r--r--src/Protocol/Protocol125.cpp38
-rw-r--r--src/Protocol/Protocol125.h1
-rw-r--r--src/Protocol/Protocol132.cpp2
-rw-r--r--src/Protocol/Protocol14x.cpp2
-rw-r--r--src/Protocol/Protocol17x.cpp157
-rw-r--r--src/Protocol/Protocol17x.h38
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp10
-rw-r--r--src/Protocol/ProtocolRecognizer.h1
-rw-r--r--src/Root.cpp16
-rw-r--r--src/Root.h24
-rw-r--r--src/World.cpp20
-rw-r--r--src/World.h18
35 files changed, 990 insertions, 374 deletions
diff --git a/.gitignore b/.gitignore
index 007b21519..c8ad93a80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,9 @@ cloc.xsl
*.*~
*~
*.orig
+## Eclipse
+.cproject
+.project
# world inside source
ChunkWorx.ini
@@ -57,7 +60,7 @@ install_mainfest.txt
src/MCServer
lib/tolua++/tolua
src/Bindings/Bindings.*
-src/Bindings/BindingsDependecies.txt
+src/Bindings/BindingDependecies.txt
MCServer.dir/
#win32 cmake stuff
diff --git a/.travis.yml b/.travis.yml
index 38dd2f280..c6537cf47 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@ compiler:
- gcc
- clang
# Build MCServer
-script: cmake . -DCMAKE_BUILD_TYPE=RELEASE -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | ./MCServer)
+script: cmake . -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | ./MCServer)
# Notification Settings
notifications:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 57b200a2a..05b6d879b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,105 +3,20 @@ cmake_minimum_required (VERSION 2.6)
# Without this, the MSVC variable isn't defined for MSVC builds ( http://www.cmake.org/pipermail/cmake/2011-November/047130.html )
enable_language(CXX C)
-macro (add_flags_lnk FLAGS)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
- set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAGS}")
- set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAGS}")
- set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${FLAGS}")
-endmacro()
-
-macro(add_flags_cxx FLAGS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
-endmacro()
-
-# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
-if (NOT MSVC)
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
-endif()
-
-if(MSVC)
- # Make build use multiple threads under MSVC:
- add_flags_cxx("/MP")
-
- # Make release builds use link-time code generation:
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL")
- set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
- set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
- set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG")
-elseif(APPLE)
- #on os x clang adds pthread for us but we need to add it for gcc
- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
- else()
- add_flags_cxx("-pthread")
- endif()
-
-else()
- # Let gcc / clang know that we're compiling a multi-threaded app:
- add_flags_cxx("-pthread")
- if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
- endif()
-
- # We use a signed char (fixes #640 on RasPi)
- add_flags_cxx("-fsigned-char")
-endif()
-
-
-# Allow for a forced 32-bit build under 64-bit OS:
-if (FORCE_32)
- add_flags_cxx("-m32")
- add_flags_lnk("-m32")
-endif()
-
-
-# Have the compiler generate code specifically targeted at the current machine on Linux
-if(LINUX AND NOT CROSSCOMPILE)
- add_flags_cxx("-march=native")
-endif()
-
-
-# Use static CRT in MSVC builds:
-if (MSVC)
- string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
- string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
- string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+# This has to be done before any flags have been set up.
+if(${BUILD_TOOLS})
+ add_subdirectory(Tools/MCADefrag/)
+ add_subdirectory(Tools/ProtoProxy/)
endif()
-
-# Set lower warnings-level for the libraries:
-if (MSVC)
- # Remove /W3 from command line -- cannot just cancel it later with /w like in unix, MSVC produces a D9025 warning (option1 overriden by option2)
- string(REPLACE "/W3" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "/W3" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
- string(REPLACE "/W3" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
- string(REPLACE "/W3" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
-else()
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -w")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -w")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -w")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -w")
+if(${BUILD_UNSTABLE_TOOLS})
+ add_subdirectory(Tools/GeneratorPerformanceTest/)
endif()
+include(SetFlags.cmake)
+set_flags()
+set_lib_flags()
+enable_profile()
# Under Windows, we need Lua as DLL; on *nix we need it linked statically:
if (WIN32)
@@ -109,18 +24,6 @@ if (WIN32)
endif()
-# On Unix we use two dynamic loading libraries dl and ltdl.
-# Preference is for dl on unknown systems as it is specified in POSIX
-# the dynamic loader is used by lua and sqllite.
-if (UNIX)
- if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
- set(DYNAMIC_LOADER ltdl)
- else()
- set(DYNAMIC_LOADER dl)
- endif()
-endif()
-
-
# The Expat library is linked in statically, make the source files aware of that:
add_definitions(-DXML_STATIC)
@@ -129,64 +32,10 @@ if(${SELF_TEST})
add_definitions(-DSELF_TEST)
endif()
-# Declare the flags used for profiling builds:
-if (MSVC)
- set (CXX_PROFILING "")
- set (LNK_PROFILING "/PROFILE")
-else()
- set (CXX_PROFILING "-pg")
- set (LNK_PROFILING "-pg")
-endif()
-# Declare the profiling configurations:
-SET(CMAKE_CXX_FLAGS_DEBUGPROFILE
- "${CMAKE_CXX_FLAGS_DEBUG} ${PCXX_ROFILING}"
- CACHE STRING "Flags used by the C++ compiler during profile builds."
- FORCE )
-SET(CMAKE_C_FLAGS_DEBUGPROFILE
- "${CMAKE_C_FLAGS_DEBUG} ${CXX_PROFILING}"
- CACHE STRING "Flags used by the C compiler during profile builds."
- FORCE )
-SET(CMAKE_EXE_LINKER_FLAGS_DEBUGPROFILE
- "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${LNK_PROFILING}"
- CACHE STRING "Flags used for linking binaries during profile builds."
- FORCE )
-SET(CMAKE_SHARED_LINKER_FLAGS_DEBUGPROFILE
- "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${LNK_PROFILING}"
- CACHE STRING "Flags used by the shared libraries linker during profile builds."
- FORCE )
-MARK_AS_ADVANCED(
- CMAKE_CXX_FLAGS_DEBUGPROFILE
- CMAKE_C_FLAGS_DEBUGPROFILE
- CMAKE_EXE_LINKER_FLAGS_DEBUGPROFILE
- CMAKE_SHARED_LINKER_FLAGS_DEBUGPROFILE )
-
-SET(CMAKE_CXX_FLAGS_RELEASEPROFILE
- "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_PROFILING}"
- CACHE STRING "Flags used by the C++ compiler during profile builds."
- FORCE )
-SET(CMAKE_C_FLAGS_RELEASEPROFILE
- "${CMAKE_C_FLAGS_RELEASE} ${CXX_PROFILING}"
- CACHE STRING "Flags used by the C compiler during profile builds."
- FORCE )
-SET(CMAKE_EXE_LINKER_FLAGS_RELEASEPROFILE
- "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${LNK_PROFILING}"
- CACHE STRING "Flags used for linking binaries during profile builds."
- FORCE )
-SET(CMAKE_SHARED_LINKER_FLAGS_RELEASEPROFILE
- "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${LNK_PROFILING}"
- CACHE STRING "Flags used by the shared libraries linker during profile builds."
- FORCE )
-MARK_AS_ADVANCED(
- CMAKE_CXX_FLAGS_RELEASEPROFILE
- CMAKE_C_FLAGS_RELEASEPROFILE
- CMAKE_EXE_LINKER_FLAGS_RELEASEPROFILE
- CMAKE_SHARED_LINKER_FLAGS_RELEASEPROFILE )
-
-
-# The configuration types need to be set after their respective c/cxx/linker flags and before the project directive
-set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile" CACHE STRING "" FORCE)
+
+
project (MCServer)
# Include all the libraries:
@@ -203,24 +52,9 @@ add_subdirectory(lib/md5/)
# We use EXCLUDE_FROM_ALL so that only the explicit dependencies are used
# (PolarSSL also has test and example programs in their CMakeLists.txt, we don't want those)
-add_subdirectory(lib/polarssl/ EXCLUDE_FROM_ALL)
-
-
-# Remove disabling the maximum warning level:
-# clang does not like a command line that reads -Wall -Wextra -w -Wall -Wextra and does not output any warnings
-# We do not do that for MSVC since MSVC produces an awful lot of warnings for its own STL headers;
-# the important warnings are turned on using #pragma in Globals.h
-if (NOT MSVC)
- string(REPLACE "-w" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
- string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
- string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
- add_flags_cxx("-Wall")
-endif()
+include(lib/polarssl.cmake)
-if(${BUILD_TOOLS})
-add_subdirectory(Tools/GeneratorPerformanceTest/)
-endif()
+set_exe_flags()
add_subdirectory (src)
diff --git a/COMPILING.md b/COMPILING.md
index d3c896bdd..139f1a0ee 100644
--- a/COMPILING.md
+++ b/COMPILING.md
@@ -69,7 +69,7 @@ Assuming you are in the MCServer folder created in the initial setup step, you n
```
mkdir Release
cd Release
-cmake . -DCMAKE_BUILD_TYPE=RELEASE .. && make
+cmake -DCMAKE_BUILD_TYPE=RELEASE .. && make
```
The executable will be built in the `MCServer/MCServer` folder and will be named `MCServer`.
@@ -81,7 +81,7 @@ Assuming you are in the MCServer folder created in the Getting the sources step,
```
mkdir Debug
cd Debug
-cmake . -DCMAKE_BUILD_TYPE=DEBUG && make`
+cmake -DCMAKE_BUILD_TYPE=DEBUG .. && make
```
The executable will be built in the `MCServer/MCServer` folder and will be named `MCServer_debug`.
diff --git a/MCServer/.gitignore b/MCServer/.gitignore
index e3aebbf92..0fd04ef59 100644
--- a/MCServer/.gitignore
+++ b/MCServer/.gitignore
@@ -4,6 +4,7 @@
*.lib
*.ini
MCServer
+MCServer_debug
CommLogs/
logs
players
diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua
index 51b3a3a87..60e84c947 100644
--- a/MCServer/Plugins/Debuggers/Debuggers.lua
+++ b/MCServer/Plugins/Debuggers/Debuggers.lua
@@ -54,6 +54,7 @@ function Initialize(Plugin)
PM:BindCommand("/ff", "debuggers", HandleFurnaceFuel, "- Shows how long the currently held item would burn in a furnace");
PM:BindCommand("/sched", "debuggers", HandleSched, "- Schedules a simple countdown using cWorld:ScheduleTask()");
PM:BindCommand("/cs", "debuggers", HandleChunkStay, "- Tests the ChunkStay Lua integration for the specified chunk coords");
+ PM:BindCommand("/compo", "debuggers", HandleCompo, "- Tests the cCompositeChat bindings")
Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers)
Plugin:AddWebTab("StressTest", HandleRequest_StressTest)
@@ -1195,3 +1196,25 @@ end
+
+function HandleCompo(a_Split, a_Player)
+ -- Send one composite message to self:
+ local msg = cCompositeChat()
+ msg:AddTextPart("Hello! ", "b@e") -- bold yellow
+ msg:AddUrlPart("MCServer", "http://mc-server.org")
+ msg:AddTextPart(" rules! ")
+ msg:AddRunCommandPart("Set morning", "/time set 0")
+ a_Player:SendMessage(msg)
+
+ -- Broadcast another one to the world:
+ local msg2 = cCompositeChat()
+ msg2:AddSuggestCommandPart(a_Player:GetName(), "/tell " .. a_Player:GetName() .. " ")
+ msg2:AddTextPart(" knows how to use cCompositeChat!");
+ a_Player:GetWorld():BroadcastChat(msg2)
+
+ return true
+end
+
+
+
+
diff --git a/SetFlags.cmake b/SetFlags.cmake
new file mode 100644
index 000000000..162560c90
--- /dev/null
+++ b/SetFlags.cmake
@@ -0,0 +1,189 @@
+
+
+macro (add_flags_lnk FLAGS)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${FLAGS}")
+endmacro()
+
+macro(add_flags_cxx FLAGS)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
+endmacro()
+
+
+macro(set_flags)
+ # Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
+ if (NOT MSVC)
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
+ endif()
+
+ if(MSVC)
+ # Make build use multiple threads under MSVC:
+ add_flags_cxx("/MP")
+
+ # Make release builds use link-time code generation:
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL")
+ set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
+ set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
+ set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG")
+ elseif(APPLE)
+ #on os x clang adds pthread for us but we need to add it for gcc
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
+ else()
+ add_flags_cxx("-pthread")
+ endif()
+
+ else()
+ # Let gcc / clang know that we're compiling a multi-threaded app:
+ add_flags_cxx("-pthread")
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
+ endif()
+
+ # We use a signed char (fixes #640 on RasPi)
+ add_flags_cxx("-fsigned-char")
+ endif()
+
+
+ # Allow for a forced 32-bit build under 64-bit OS:
+ if (FORCE_32)
+ add_flags_cxx("-m32")
+ add_flags_lnk("-m32")
+ endif()
+
+
+ # Have the compiler generate code specifically targeted at the current machine on Linux
+ if(LINUX AND NOT CROSSCOMPILE)
+ add_flags_cxx("-march=native")
+ endif()
+
+
+ # Use static CRT in MSVC builds:
+ if (MSVC)
+ string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+ string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
+ string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ endif()
+endmacro()
+
+macro(set_lib_flags)
+ # Set lower warnings-level for the libraries:
+ if (MSVC)
+ # Remove /W3 from command line -- cannot just cancel it later with /w like in unix, MSVC produces a D9025 warning (option1 overriden by option2)
+ string(REPLACE "/W3" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+ string(REPLACE "/W3" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
+ string(REPLACE "/W3" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "/W3" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ else()
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -w")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -w")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -w")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -w")
+ endif()
+
+ # On Unix we use two dynamic loading libraries dl and ltdl.
+ # Preference is for dl on unknown systems as it is specified in POSIX
+ # the dynamic loader is used by lua and sqllite.
+ if (UNIX)
+ if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
+ set(DYNAMIC_LOADER ltdl)
+ else()
+ set(DYNAMIC_LOADER dl)
+ endif()
+ endif()
+endmacro()
+
+macro(enable_profile)
+ # Declare the flags used for profiling builds:
+ if (MSVC)
+ set (CXX_PROFILING "")
+ set (LNK_PROFILING "/PROFILE")
+ else()
+ set (CXX_PROFILING "-pg")
+ set (LNK_PROFILING "-pg")
+ endif()
+
+
+ # Declare the profiling configurations:
+ SET(CMAKE_CXX_FLAGS_DEBUGPROFILE
+ "${CMAKE_CXX_FLAGS_DEBUG} ${PCXX_ROFILING}"
+ CACHE STRING "Flags used by the C++ compiler during profile builds."
+ FORCE )
+ SET(CMAKE_C_FLAGS_DEBUGPROFILE
+ "${CMAKE_C_FLAGS_DEBUG} ${CXX_PROFILING}"
+ CACHE STRING "Flags used by the C compiler during profile builds."
+ FORCE )
+ SET(CMAKE_EXE_LINKER_FLAGS_DEBUGPROFILE
+ "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${LNK_PROFILING}"
+ CACHE STRING "Flags used for linking binaries during profile builds."
+ FORCE )
+ SET(CMAKE_SHARED_LINKER_FLAGS_DEBUGPROFILE
+ "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${LNK_PROFILING}"
+ CACHE STRING "Flags used by the shared libraries linker during profile builds."
+ FORCE )
+ MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_DEBUGPROFILE
+ CMAKE_C_FLAGS_DEBUGPROFILE
+ CMAKE_EXE_LINKER_FLAGS_DEBUGPROFILE
+ CMAKE_SHARED_LINKER_FLAGS_DEBUGPROFILE )
+
+ SET(CMAKE_CXX_FLAGS_RELEASEPROFILE
+ "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_PROFILING}"
+ CACHE STRING "Flags used by the C++ compiler during profile builds."
+ FORCE )
+ SET(CMAKE_C_FLAGS_RELEASEPROFILE
+ "${CMAKE_C_FLAGS_RELEASE} ${CXX_PROFILING}"
+ CACHE STRING "Flags used by the C compiler during profile builds."
+ FORCE )
+ SET(CMAKE_EXE_LINKER_FLAGS_RELEASEPROFILE
+ "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${LNK_PROFILING}"
+ CACHE STRING "Flags used for linking binaries during profile builds."
+ FORCE )
+ SET(CMAKE_SHARED_LINKER_FLAGS_RELEASEPROFILE
+ "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${LNK_PROFILING}"
+ CACHE STRING "Flags used by the shared libraries linker during profile builds."
+ FORCE )
+ MARK_AS_ADVANCED(
+ CMAKE_CXX_FLAGS_RELEASEPROFILE
+ CMAKE_C_FLAGS_RELEASEPROFILE
+ CMAKE_EXE_LINKER_FLAGS_RELEASEPROFILE
+ CMAKE_SHARED_LINKER_FLAGS_RELEASEPROFILE )
+ # The configuration types need to be set after their respective c/cxx/linker flags and before the project directive
+ set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile" CACHE STRING "" FORCE)
+endmacro()
+
+macro(set_exe_flags)
+ # Remove disabling the maximum warning level:
+ # clang does not like a command line that reads -Wall -Wextra -w -Wall -Wextra and does not output any warnings
+ # We do not do that for MSVC since MSVC produces an awful lot of warnings for its own STL headers;
+ # the important warnings are turned on using #pragma in Globals.h
+ if (NOT MSVC)
+ string(REPLACE "-w" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+ string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
+ string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
+ string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+ add_flags_cxx("-Wall")
+ endif()
+
+endmacro()
diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt
index 7296b8ddc..2a021049f 100644
--- a/Tools/MCADefrag/CMakeLists.txt
+++ b/Tools/MCADefrag/CMakeLists.txt
@@ -3,60 +3,13 @@ cmake_minimum_required (VERSION 2.6)
project (MCADefrag)
+# Without this, the MSVC variable isn't defined for MSVC builds ( http://www.cmake.org/pipermail/cmake/2011-November/047130.html )
+enable_language(CXX C)
-
-macro(add_flags_cxx FLAGS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
-endmacro()
-
-
-
-
-# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
-if (NOT MSVC)
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
-endif()
-
-
-
-if(MSVC)
- # Make build use multiple threads under MSVC:
- add_flags_cxx("/MP")
-
- # Make release builds use link-time code generation:
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL")
- set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
- set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
- set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG")
-elseif(APPLE)
- #on os x clang adds pthread for us but we need to add it for gcc
- if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- add_flags_cxx("-pthread")
- endif()
-else()
- # Let gcc / clang know that we're compiling a multi-threaded app:
- add_flags_cxx("-pthread")
-endif()
-
-
-
-
-# Use static CRT in MSVC builds:
-if (MSVC)
- string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
- string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
- string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
-endif()
+include(../../SetFlags.cmake)
+set_flags()
+set_lib_flags()
+enable_profile()
@@ -66,7 +19,6 @@ include_directories("../../lib")
include_directories("../../src")
-
function(flatten_files arg1)
set(res "")
foreach(f ${${arg1}})
@@ -78,12 +30,10 @@ endfunction()
# Include the libraries:
-file(GLOB ZLIB_SRC "../../lib/zlib/*.c")
-file(GLOB ZLIB_HDR "../../lib/zlib/*.h")
-flatten_files(ZLIB_SRC)
-flatten_files(ZLIB_HDR)
-source_group("ZLib" FILES ${ZLIB_SRC} ${ZLIB_HDR})
+add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib)
+
+set_exe_flags()
# Include the shared files:
set(SHARED_SRC
@@ -98,6 +48,10 @@ set(SHARED_HDR
../../src/Log.h
../../src/MCLogger.h
)
+flatten_files(SHARED_SRC)
+flatten_files(SHARED_HDR)
+source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR})
+
set(SHARED_OSS_SRC
../../src/OSSupport/CriticalSection.cpp
../../src/OSSupport/File.cpp
@@ -110,11 +64,10 @@ set(SHARED_OSS_HDR
../../src/OSSupport/IsThread.h
../../src/OSSupport/Timer.h
)
-flatten_files(SHARED_SRC)
-flatten_files(SHARED_HDR)
+
flatten_files(SHARED_OSS_SRC)
flatten_files(SHARED_OSS_HDR)
-source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR})
+
source_group("Shared\\OSSupport" FILES ${SHARED_OSS_SRC} ${SHARED_OSS_HDR})
@@ -138,7 +91,7 @@ add_executable(MCADefrag
${SHARED_HDR}
${SHARED_OSS_SRC}
${SHARED_OSS_HDR}
- ${ZLIB_SRC}
- ${ZLIB_HDR}
)
+target_link_libraries(MCADefrag zlib)
+
diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt
index 9e233a688..01f1e88ad 100644
--- a/Tools/ProtoProxy/CMakeLists.txt
+++ b/Tools/ProtoProxy/CMakeLists.txt
@@ -3,62 +3,10 @@ cmake_minimum_required (VERSION 2.6)
project (ProtoProxy)
+include(../../SetFlags.cmake)
-
-macro(add_flags_cxx FLAGS)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
-endmacro()
-
-
-
-
-# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
-if (NOT MSVC)
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
-endif()
-
-
-
-if(MSVC)
- # Make build use multiple threads under MSVC:
- add_flags_cxx("/MP")
-
- # Make release builds use link-time code generation:
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL")
- set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
- set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
- set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG")
-elseif(APPLE)
- #on os x clang adds pthread for us but we need to add it for gcc
- if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- add_flags_cxx("-pthread")
- endif()
-else()
- # Let gcc / clang know that we're compiling a multi-threaded app:
- add_flags_cxx("-pthread")
-endif()
-
-
-
-
-# Use static CRT in MSVC builds:
-if (MSVC)
- string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
- string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
- string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
- string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
-endif()
-
-
+set_flags()
+set_lib_flags()
# Set include paths to the used libraries:
@@ -77,20 +25,10 @@ function(flatten_files arg1)
set(${arg1} "${res}" PARENT_SCOPE)
endfunction()
+include(../../lib/polarssl.cmake)
+add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib)
-# Include the libraries:
-file(GLOB POLARSSL_SRC "../../lib/polarssl/library/*.c")
-file(GLOB POLARSSL_HDR "../../lib/polarssl/include/polarssl/*.h")
-flatten_files(POLARSSL_SRC)
-flatten_files(POLARSSL_HDR)
-source_group("PolarSSL" FILES ${POLARSSL_SRC} ${POLARSSL_HDR})
-
-file(GLOB ZLIB_SRC "../../lib/zlib/*.c")
-file(GLOB ZLIB_HDR "../../lib/zlib/*.h")
-flatten_files(ZLIB_SRC)
-flatten_files(ZLIB_HDR)
-source_group("ZLib" FILES ${ZLIB_SRC} ${ZLIB_HDR})
-
+set_exe_flags()
# Include the shared files:
set(SHARED_SRC
@@ -149,9 +87,7 @@ add_executable(ProtoProxy
${SHARED_HDR}
${SHARED_OSS_SRC}
${SHARED_OSS_HDR}
- ${POLARSSL_SRC}
- ${POLARSSL_HDR}
- ${ZLIB_SRC}
- ${ZLIB_HDR}
)
+target_link_libraries(ProtoProxy zlib polarssl)
+
diff --git a/lib/polarssl.cmake b/lib/polarssl.cmake
new file mode 100644
index 000000000..d57cc9220
--- /dev/null
+++ b/lib/polarssl.cmake
@@ -0,0 +1,5 @@
+
+if(NOT TARGET polarssl)
+ message("including polarssl")
+ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL )
+endif()
diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt
index 239232c38..5ec8ee822 100644
--- a/lib/tolua++/CMakeLists.txt
+++ b/lib/tolua++/CMakeLists.txt
@@ -19,7 +19,7 @@ add_library(tolualib ${LIB_SOURCE})
#m is the standard math librarys
if(UNIX)
-target_link_libraries(tolua m)
+target_link_libraries(tolua m ${DYNAMIC_LOADER})
endif()
target_link_libraries(tolua lua tolualib)
diff --git a/lib/zlib/CMakeLists.txt b/lib/zlib/CMakeLists.txt
index b1b74031d..6c52578ee 100644
--- a/lib/zlib/CMakeLists.txt
+++ b/lib/zlib/CMakeLists.txt
@@ -8,12 +8,14 @@ file(GLOB SOURCE
"*.c"
)
-add_library(zlib ${SOURCE})
+if(NOT TARGET zlib)
+ add_library(zlib ${SOURCE})
-if (MSVC)
- # Remove SCL warnings, we expect this library to have been tested safe
- SET_TARGET_PROPERTIES(
- zlib PROPERTIES COMPILE_FLAGS "-D_CRT_SECURE_NO_WARNINGS"
- )
+ if (MSVC)
+ # Remove SCL warnings, we expect this library to have been tested safe
+ SET_TARGET_PROPERTIES(
+ zlib PROPERTIES COMPILE_FLAGS "-D_CRT_SECURE_NO_WARNINGS"
+ )
+ endif()
endif()
diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg
index f65aed9bb..6c295102f 100644
--- a/src/Bindings/AllToLua.pkg
+++ b/src/Bindings/AllToLua.pkg
@@ -70,6 +70,7 @@ $cfile "../Generating/ChunkDesc.h"
$cfile "../CraftingRecipes.h"
$cfile "../UI/Window.h"
$cfile "../Mobs/Monster.h"
+$cfile "../CompositeChat.h"
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 1b3ebc3d4..b46bcfd47 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -31,6 +31,7 @@
#include "MersenneTwister.h"
#include "Protocol/ProtocolRecognizer.h"
+#include "CompositeChat.h"
@@ -94,6 +95,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) :
m_ShouldCheckDownloaded(false),
m_NumExplosionsThisTick(0),
m_UniqueID(0),
+ m_Locale("en_GB"),
m_HasSentPlayerChunk(false)
{
m_Protocol = new cProtocolRecognizer(this);
@@ -1729,7 +1731,7 @@ void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlock
-void cClientHandle::SendChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const AString & a_AdditionalData)
+void cClientHandle::SendChat(const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData)
{
bool ShouldAppendChatPrefixes = true;
@@ -1840,6 +1842,15 @@ void cClientHandle::SendChat(const AString & a_Message, ChatPrefixCodes a_ChatPr
+void cClientHandle::SendChat(const cCompositeChat & a_Message)
+{
+ m_Protocol->SendChat(a_Message);
+}
+
+
+
+
+
void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
{
ASSERT(m_Player != NULL);
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index d9a86d983..5faa94004 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -34,6 +34,7 @@ class cWindow;
class cFallingBlock;
class cItemHandler;
class cWorld;
+class cCompositeChat;
@@ -89,7 +90,8 @@ public:
void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage);
void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // tolua_export
void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes);
- void SendChat (const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const AString & a_AdditionalData = "");
+ void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = "");
+ void SendChat (const cCompositeChat & a_Message);
void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer);
void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player);
void SendDestroyEntity (const cEntity & a_Entity);
@@ -153,6 +155,9 @@ public:
void SetViewDistance(int a_ViewDistance); // tolua_export
int GetViewDistance(void) const { return m_ViewDistance; } // tolua_export
+
+ void SetLocale(AString & a_Locale) { m_Locale = a_Locale; } // tolua_export
+ AString GetLocale(void) const { return m_Locale; } // tolua_export
int GetUniqueID() const { return m_UniqueID; } // tolua_export
@@ -306,7 +311,9 @@ private:
/// Set to true when the chunk where the player is is sent to the client. Used for spawning the player
bool m_HasSentPlayerChunk;
-
+
+ /// Client Settings
+ AString m_Locale;
/// Returns true if the rate block interactions is within a reasonable limit (bot protection)
diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp
new file mode 100644
index 000000000..16ae58f56
--- /dev/null
+++ b/src/CompositeChat.cpp
@@ -0,0 +1,206 @@
+
+// CompositeChat.cpp
+
+// Implements the cCompositeChat class used to wrap a chat message with multiple parts (text, url, cmd)
+
+#include "Globals.h"
+#include "CompositeChat.h"
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat:
+
+cCompositeChat::cCompositeChat(void) :
+ m_MessageType(mtCustom)
+{
+}
+
+
+
+
+
+cCompositeChat::cCompositeChat(const AString & a_ParseText) :
+ m_MessageType(mtCustom)
+{
+ ParseText(a_ParseText);
+}
+
+
+
+
+
+cCompositeChat::~cCompositeChat()
+{
+ Clear();
+}
+
+
+
+
+
+void cCompositeChat::Clear(void)
+{
+ for (cParts::iterator itr = m_Parts.begin(), end = m_Parts.end(); itr != end; ++itr)
+ {
+ delete *itr;
+ } // for itr - m_Parts[]
+ m_Parts.clear();
+}
+
+
+
+
+
+void cCompositeChat::AddTextPart(const AString & a_Message, const AString & a_Style)
+{
+ m_Parts.push_back(new cTextPart(a_Message, a_Style));
+}
+
+
+
+
+
+void cCompositeChat::AddClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style)
+{
+ m_Parts.push_back(new cClientTranslatedPart(a_TranslationID, a_Parameters, a_Style));
+}
+
+
+
+
+
+void cCompositeChat::AddUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style)
+{
+ m_Parts.push_back(new cUrlPart(a_Text, a_Url, a_Style));
+}
+
+
+
+
+
+void cCompositeChat::AddRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style)
+{
+ m_Parts.push_back(new cRunCommandPart(a_Text, a_Command, a_Style));
+}
+
+
+
+
+
+void cCompositeChat::AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style)
+{
+ m_Parts.push_back(new cSuggestCommandPart(a_Text, a_SuggestedCommand, a_Style));
+}
+
+
+
+
+
+void cCompositeChat::ParseText(const AString & a_ParseText)
+{
+ // TODO
+}
+
+
+
+
+
+void cCompositeChat::SetMessageType(eMessageType a_MessageType)
+{
+ m_MessageType = a_MessageType;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat::cBasePart:
+
+cCompositeChat::cBasePart::cBasePart(cCompositeChat::ePartType a_PartType, const AString & a_Text, const AString & a_Style) :
+ m_PartType(a_PartType),
+ m_Text(a_Text),
+ m_Style(a_Style)
+{
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat::cTextPart:
+
+cCompositeChat::cTextPart::cTextPart(const AString & a_Text, const AString &a_Style) :
+ super(ptText, a_Text, a_Style)
+{
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat::cClientTranslatedPart:
+
+cCompositeChat::cClientTranslatedPart::cClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style) :
+ super(ptClientTranslated, a_TranslationID, a_Style),
+ m_Parameters(a_Parameters)
+{
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat::cUrlPart:
+
+cCompositeChat::cUrlPart::cUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style) :
+ super(ptUrl, a_Text, a_Style),
+ m_Url(a_Url)
+{
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat::cCommandPart:
+
+cCompositeChat::cCommandPart::cCommandPart(ePartType a_PartType, const AString & a_Text, const AString & a_Command, const AString & a_Style) :
+ super(a_PartType, a_Text, a_Style),
+ m_Command(a_Command)
+{
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat::cRunCommandPart:
+
+cCompositeChat::cRunCommandPart::cRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style) :
+ super(ptRunCommand, a_Text, a_Command, a_Style)
+{
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cCompositeChat::cSuggestCommandPart:
+
+cCompositeChat::cSuggestCommandPart::cSuggestCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style) :
+ super(ptSuggestCommand, a_Text, a_Command, a_Style)
+{
+}
+
+
+
+
diff --git a/src/CompositeChat.h b/src/CompositeChat.h
new file mode 100644
index 000000000..e220f6345
--- /dev/null
+++ b/src/CompositeChat.h
@@ -0,0 +1,172 @@
+
+// CompositeChat.h
+
+// Declares the cCompositeChat class used to wrap a chat message with multiple parts (text, url, cmd)
+
+#include "Defines.h"
+
+
+
+
+
+// tolua_begin
+/** Container for a single chat message composed of multiple functional parts.
+Each part corresponds roughly to the behavior supported by the client messaging:
+ - plain text, optionaly colorized / styled
+ - clickable URLs
+ - clickable commands (run)
+ - clickable commands (suggest)
+Each part has a text assigned to it that can be styled. The style is specified using a string,
+each character / character combination in the string specifies the style to use:
+ - b = bold
+ - i = italic
+ - u = underlined
+ - s = strikethrough
+ - o = obfuscated
+ - @X = color X (X is 0 - 9 or a - f, same as dye meta
+If the protocol version doesn't support all the features, it degrades gracefully.
+*/
+class cCompositeChat
+{
+public:
+ // tolua_end
+
+ enum ePartType
+ {
+ ptText,
+ ptClientTranslated,
+ ptUrl,
+ ptRunCommand,
+ ptSuggestCommand,
+ } ;
+
+ class cBasePart
+ {
+ public:
+ ePartType m_PartType;
+ AString m_Text;
+ AString m_Style;
+
+ cBasePart(ePartType a_PartType, const AString & a_Text, const AString & a_Style = "");
+ } ;
+
+ class cTextPart :
+ public cBasePart
+ {
+ typedef cBasePart super;
+ public:
+ cTextPart(const AString & a_Text, const AString & a_Style = "");
+ } ;
+
+ class cClientTranslatedPart :
+ public cBasePart
+ {
+ typedef cBasePart super;
+ public:
+ AStringVector m_Parameters;
+
+ cClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = "");
+ } ;
+
+ class cUrlPart :
+ public cBasePart
+ {
+ typedef cBasePart super;
+ public:
+ AString m_Url;
+
+ cUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style = "");
+ } ;
+
+ class cCommandPart :
+ public cBasePart
+ {
+ typedef cBasePart super;
+ public:
+ AString m_Command;
+
+ cCommandPart(ePartType a_PartType, const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
+ } ;
+
+ class cRunCommandPart :
+ public cCommandPart
+ {
+ typedef cCommandPart super;
+ public:
+ cRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
+ } ;
+
+ class cSuggestCommandPart :
+ public cCommandPart
+ {
+ typedef cCommandPart super;
+ public:
+ cSuggestCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "");
+ } ;
+
+ typedef std::vector<cBasePart *> cParts;
+
+ // tolua_begin
+
+ /** Creates a new empty chat message */
+ cCompositeChat(void);
+
+ /** Creates a new chat message and parses the text into parts.
+ Recognizes "http:" and "https:" links and @color-codes.
+ Uses ParseText() for the actual parsing. */
+ cCompositeChat(const AString & a_ParseText);
+
+ ~cCompositeChat();
+
+ /** Removes all parts from the object. */
+ void Clear(void);
+
+ /** Adds a plain text part, with optional style.
+ The default style is plain white text. */
+ void AddTextPart(const AString & a_Message, const AString & a_Style = "");
+
+ // tolua_end
+
+ /** Adds a part that is translated client-side, with the formatting parameters and optional style.
+ Exported in ManualBindings due to AStringVector usage - Lua uses an array-table of strings. */
+ void AddClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = "");
+
+ // tolua_begin
+
+ /** Adds a part that opens an URL when clicked.
+ The default style is underlined light blue text. */
+ void AddUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style = "u@c");
+
+ /** Adds a part that runs a command when clicked.
+ The default style is underlined light green text. */
+ void AddRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "u@a");
+
+ /** Adds a part that suggests a command (enters it into the chat message area, but doesn't send) when clicked.
+ The default style is underlined yellow text. */
+ void AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style = "u@b");
+
+ /** Parses text into various parts, adds those.
+ Recognizes "http:" and "https:" URLs and @color-codes. */
+ void ParseText(const AString & a_ParseText);
+
+ /** Sets the message type, which is indicated by prefixes added to the message when serializing. */
+ void SetMessageType(eMessageType a_MessageType);
+
+ /** Returns the message type set previously by SetMessageType(). */
+ eMessageType GetMessageType(void) const { return m_MessageType; }
+
+ // tolua_end
+
+ const cParts & GetParts(void) const { return m_Parts; }
+
+protected:
+ /** All the parts that */
+ cParts m_Parts;
+
+ /** The message type, as indicated by prefixes. */
+ eMessageType m_MessageType;
+} ; // tolua_export
+
+
+
+
diff --git a/src/Defines.h b/src/Defines.h
index 290f862ef..f33d1ae56 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -441,7 +441,10 @@ inline float GetSpecialSignf( float a_Val )
-enum ChatPrefixCodes
+
+// tolua_begin
+
+enum eMessageType
{
// http://forum.mc-server.org/showthread.php?tid=1212
// MessageType...
@@ -458,7 +461,9 @@ enum ChatPrefixCodes
mtLeave, // A player has left the server
};
-// tolua_begin
+
+
+
/** Normalizes an angle in degrees to the [-180, +180) range: */
inline double NormalizeAngleDegrees(const double a_Degrees)
diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp
index 04ee85823..3398f1c7b 100644
--- a/src/Entities/ExpOrb.cpp
+++ b/src/Entities/ExpOrb.cpp
@@ -51,7 +51,10 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
{
LOGD("Player %s picked up an ExpOrb. His reward is %i", a_ClosestPlayer->GetName().c_str(), m_Reward);
a_ClosestPlayer->DeltaExperience(m_Reward);
- Destroy(true);
+
+ m_World->BroadcastSoundEffect("random.orb", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64));
+
+ Destroy();
}
a_Distance.Normalize();
a_Distance *= ((float) (5.5 - Distance));
@@ -61,4 +64,4 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk)
BroadcastMovementUpdate();
}
HandlePhysics(a_Dt, a_Chunk);
-} \ No newline at end of file
+}
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 838bbd06c..70ddb3c98 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -839,6 +839,12 @@ void cPlayer::KilledBy(cEntity * a_Killer)
cItems Pickups;
m_Inventory.CopyToItems(Pickups);
m_Inventory.Clear();
+
+ if (GetName() == "Notch")
+ {
+ Pickups.Add(cItem(E_ITEM_RED_APPLE));
+ }
+
m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10);
SaveToDisk(); // Save it, yeah the world is a tough place !
@@ -1758,6 +1764,12 @@ void cPlayer::HandleFood(void)
{
// Ref.: http://www.minecraftwiki.net/wiki/Hunger
+ if (IsGameModeCreative())
+ {
+ // Hunger is disabled for Creative
+ return;
+ }
+
// Remember the food level before processing, for later comparison
int LastFoodLevel = m_FoodLevel;
@@ -1775,7 +1787,7 @@ void cPlayer::HandleFood(void)
Heal(1);
m_FoodExhaustionLevel += 3;
}
- else if (m_FoodLevel <= 0)
+ else if ((m_FoodLevel <= 0) && (m_Health > 1))
{
// Damage from starving
TakeDamage(dtStarving, NULL, 1, 1, 0);
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 7db9544cb..53e4b56db 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -203,6 +203,7 @@ public:
void SendMessageWarning (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtWarning); }
void SendMessageFatal (const AString & a_Message) { m_ClientHandle->SendChat(a_Message, mtFailure); }
void SendMessagePrivateMsg(const AString & a_Message, const AString & a_Sender) { m_ClientHandle->SendChat(a_Message, mtPrivateMessage, a_Sender); }
+ void SendMessage (const cCompositeChat & a_Message) { m_ClientHandle->SendChat(a_Message); }
const AString & GetName(void) const { return m_PlayerName; }
void SetName(const AString & a_Name) { m_PlayerName = a_Name; }
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index a3fa9d557..ef82c6e94 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -680,6 +680,7 @@ super(pkExpBottle, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25)
void cExpBottleEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
{
// Spawn an experience orb with a reward between 3 and 11.
+ m_World->BroadcastSoundParticleEffect(2002, POSX_TOINT, POSY_TOINT, POSZ_TOINT, 0);
m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), 3 + m_World->GetTickRandomNumber(8));
Destroy();
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index 791082537..f5b9fd403 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -28,6 +28,7 @@ class cWorld;
class cMonster;
class cChunkDataSerializer;
class cFallingBlock;
+class cCompositeChat;
@@ -58,6 +59,7 @@ public:
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0;
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0;
virtual void SendChat (const AString & a_Message) = 0;
+ virtual void SendChat (const cCompositeChat & a_Message) = 0;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) = 0;
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp
index 73d21161c..7020699d1 100644
--- a/src/Protocol/Protocol125.cpp
+++ b/src/Protocol/Protocol125.cpp
@@ -32,6 +32,8 @@ Documentation:
#include "../Mobs/IncludeAllMonsters.h"
+#include "../CompositeChat.h"
+
@@ -233,6 +235,42 @@ void cProtocol125::SendChat(const AString & a_Message)
+void cProtocol125::SendChat(const cCompositeChat & a_Message)
+{
+ // This version doesn't support composite messages, just extract each part's text and use it:
+ AString Msg;
+ const cCompositeChat::cParts & Parts = a_Message.GetParts();
+ for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
+ {
+ switch ((*itr)->m_PartType)
+ {
+ case cCompositeChat::ptText:
+ case cCompositeChat::ptClientTranslated:
+ case cCompositeChat::ptRunCommand:
+ case cCompositeChat::ptSuggestCommand:
+ {
+ Msg.append((*itr)->m_Text);
+ break;
+ }
+ case cCompositeChat::ptUrl:
+ {
+ Msg.append(((cCompositeChat::cUrlPart *)(*itr))->m_Url);
+ break;
+ }
+ } // switch (PartType)
+ } // for itr - Parts[]
+
+ // Send the message:
+ cCSLock Lock(m_CSPacket);
+ WriteByte (PACKET_CHAT);
+ WriteString(Msg);
+ Flush();
+}
+
+
+
+
+
void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
{
cCSLock Lock(m_CSPacket);
diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h
index cd15ab518..1a3209333 100644
--- a/src/Protocol/Protocol125.h
+++ b/src/Protocol/Protocol125.h
@@ -33,6 +33,7 @@ public:
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
+ virtual void SendChat (const cCompositeChat & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp
index 648e70151..1f9222a69 100644
--- a/src/Protocol/Protocol132.cpp
+++ b/src/Protocol/Protocol132.cpp
@@ -560,7 +560,7 @@ int cProtocol132::ParseLocaleViewDistance(void)
HANDLE_PACKET_READ(ReadChar, char, ViewDistance);
HANDLE_PACKET_READ(ReadChar, char, ChatFlags);
HANDLE_PACKET_READ(ReadChar, char, ClientDifficulty);
- // TODO: m_Client->HandleLocale(Locale);
+ m_Client->SetLocale(Locale);
// TODO: m_Client->HandleViewDistance(ViewDistance);
// TODO: m_Client->HandleChatFlags(ChatFlags);
// Ignoring client difficulty
diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp
index f82e6de45..232b2718e 100644
--- a/src/Protocol/Protocol14x.cpp
+++ b/src/Protocol/Protocol14x.cpp
@@ -85,7 +85,7 @@ int cProtocol142::ParseLocaleViewDistance(void)
HANDLE_PACKET_READ(ReadChar, char, ChatFlags);
HANDLE_PACKET_READ(ReadChar, char, ClientDifficulty);
HANDLE_PACKET_READ(ReadChar, char, ShouldShowCape); // <-- new in 1.4.2
- // TODO: m_Client->HandleLocale(Locale);
+ m_Client->SetLocale(Locale);
// TODO: m_Client->HandleViewDistance(ViewDistance);
// TODO: m_Client->HandleChatFlags(ChatFlags);
// Ignoring client difficulty
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 7eaf106cf..f7d13774d 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -8,6 +8,7 @@ Implements the 1.7.x protocol classes:
*/
#include "Globals.h"
+#include "json/json.h"
#include "Protocol17x.h"
#include "ChunkDataSerializer.h"
#include "../ClientHandle.h"
@@ -25,6 +26,7 @@ Implements the 1.7.x protocol classes:
#include "../Mobs/IncludeAllMonsters.h"
#include "../UI/Window.h"
#include "../BlockEntities/CommandBlockEntity.h"
+#include "../CompositeChat.h"
@@ -200,6 +202,78 @@ void cProtocol172::SendChat(const AString & a_Message)
+void cProtocol172::SendChat(const cCompositeChat & a_Message)
+{
+ // Compose the complete Json string to send:
+ Json::Value msg;
+ msg["text"] = ""; // The client crashes without this
+ const cCompositeChat::cParts & Parts = a_Message.GetParts();
+ for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
+ {
+ Json::Value Part;
+ switch ((*itr)->m_PartType)
+ {
+ case cCompositeChat::ptText:
+ {
+ Part["text"] = (*itr)->m_Text;
+ AddChatPartStyle(Part, (*itr)->m_Style);
+ break;
+ }
+
+ case cCompositeChat::ptClientTranslated:
+ {
+ const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
+ Part["translate"] = p.m_Text;
+ Json::Value With;
+ for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
+ {
+ With.append(*itrW);
+ }
+ if (!p.m_Parameters.empty())
+ {
+ Part["with"] = With;
+ }
+ AddChatPartStyle(Part, p.m_Style);
+ break;
+ }
+
+ case cCompositeChat::ptUrl:
+ {
+ const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
+ Part["text"] = p.m_Text;
+ Json::Value Url;
+ Url["action"] = "open_url";
+ Url["value"] = p.m_Url;
+ Part["clickEvent"] = Url;
+ AddChatPartStyle(Part, p.m_Style);
+ break;
+ }
+
+ case cCompositeChat::ptSuggestCommand:
+ case cCompositeChat::ptRunCommand:
+ {
+ const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
+ Part["text"] = p.m_Text;
+ Json::Value Cmd;
+ Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
+ Cmd["value"] = p.m_Command;
+ Part["clickEvent"] = Cmd;
+ AddChatPartStyle(Part, p.m_Style);
+ break;
+ }
+ }
+ msg["extra"].append(Part);
+ } // for itr - Parts[]
+
+ // Send the message to the client:
+ cPacketizer Pkt(*this, 0x02);
+ Pkt.WriteString(msg.toStyledString());
+}
+
+
+
+
+
void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
{
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
@@ -476,7 +550,7 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (cRoot::Get()->GetServer()->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4
Pkt.WriteChar((char)a_World.GetDimension());
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
- Pkt.WriteByte(cRoot::Get()->GetServer()->GetMaxPlayers());
+ Pkt.WriteByte(std::min(cRoot::Get()->GetServer()->GetMaxPlayers(), 60));
Pkt.WriteString("default"); // Level type - wtf?
}
@@ -1524,6 +1598,8 @@ void cProtocol172::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatColors);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Difficulty);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ShowCape);
+
+ m_Client->SetLocale(Locale);
// TODO: handle in m_Client
}
@@ -1979,6 +2055,85 @@ void cProtocol172::StartEncryption(const Byte * a_Key)
+void cProtocol172::AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle)
+{
+ size_t len = a_PartStyle.length();
+ for (size_t i = 0; i < len; i++)
+ {
+ switch (a_PartStyle[i])
+ {
+ case 'b':
+ {
+ // bold
+ a_Value["bold"] = Json::Value(true);
+ break;
+ }
+
+ case 'i':
+ {
+ // italic
+ a_Value["italic"] = Json::Value(true);
+ break;
+ }
+
+ case 'u':
+ {
+ // Underlined
+ a_Value["underlined"] = Json::Value(true);
+ break;
+ }
+
+ case 's':
+ {
+ // strikethrough
+ a_Value["strikethrough"] = Json::Value(true);
+ break;
+ }
+
+ case 'o':
+ {
+ // obfuscated
+ a_Value["obfuscated"] = Json::Value(true);
+ break;
+ }
+
+ case '@':
+ {
+ // Color, specified by the next char:
+ i++;
+ if (i >= len)
+ {
+ // String too short, didn't contain a color
+ break;
+ }
+ switch (a_PartStyle[i])
+ {
+ case '0': a_Value["color"] = Json::Value("black"); break;
+ case '1': a_Value["color"] = Json::Value("dark_blue"); break;
+ case '2': a_Value["color"] = Json::Value("dark_green"); break;
+ case '3': a_Value["color"] = Json::Value("dark_aqua"); break;
+ case '4': a_Value["color"] = Json::Value("dark_red"); break;
+ case '5': a_Value["color"] = Json::Value("dark_purple"); break;
+ case '6': a_Value["color"] = Json::Value("gold"); break;
+ case '7': a_Value["color"] = Json::Value("gray"); break;
+ case '8': a_Value["color"] = Json::Value("dark_gray"); break;
+ case '9': a_Value["color"] = Json::Value("blue"); break;
+ case 'a': a_Value["color"] = Json::Value("green"); break;
+ case 'b': a_Value["color"] = Json::Value("aqua"); break;
+ case 'c': a_Value["color"] = Json::Value("red"); break;
+ case 'd': a_Value["color"] = Json::Value("light_purple"); break;
+ case 'e': a_Value["color"] = Json::Value("yellow"); break;
+ case 'f': a_Value["color"] = Json::Value("white"); break;
+ } // switch (color)
+ } // case '@'
+ } // switch (Style[i])
+ } // for i - a_PartStyle[]
+}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cProtocol172::cPacketizer:
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 6a75e41c8..d19be0f05 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -36,6 +36,16 @@ Declares the 1.7.x protocol classes:
+// fwd:
+namespace Json
+{
+ class Value;
+}
+
+
+
+
+
class cProtocol172 :
public cProtocol
{
@@ -45,16 +55,17 @@ public:
cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
- /// Called when client sends some data:
+ /** Called when client sends some data: */
virtual void DataReceived(const char * a_Data, int a_Size) override;
- /// Sending stuff to clients (alphabetically sorted):
+ /** Sending stuff to clients (alphabetically sorted): */
virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
+ virtual void SendChat (const cCompositeChat & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
@@ -117,7 +128,7 @@ public:
protected:
- /// Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed
+ /** Composes individual packets in the protocol's m_OutPacketBuffer; sends them upon being destructed */
class cPacketizer
{
public:
@@ -206,16 +217,16 @@ protected:
AString m_AuthServerID;
- /// State of the protocol. 1 = status, 2 = login, 3 = game
+ /** State of the protocol. 1 = status, 2 = login, 3 = game */
UInt32 m_State;
- /// Buffer for the received data
+ /** Buffer for the received data */
cByteBuffer m_ReceivedData;
- /// Buffer for composing the outgoing packets, through cPacketizer
+ /** Buffer for composing the outgoing packets, through cPacketizer */
cByteBuffer m_OutPacketBuffer;
- /// Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer)
+ /** Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer) */
cByteBuffer m_OutPacketLenBuffer;
bool m_IsEncrypted;
@@ -227,7 +238,7 @@ protected:
cFile m_CommLogFile;
- /// Adds the received (unencrypted) data to m_ReceivedData, parses complete packets
+ /** 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.
@@ -268,21 +279,24 @@ protected:
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
- /// Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here.
+ /** Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. */
void WritePacket(cByteBuffer & a_Packet);
- /// Sends the data to the client, encrypting them if needed.
+ /** Sends the data to the client, encrypting them if needed. */
virtual void SendData(const char * a_Data, int a_Size) override;
void SendCompass(const cWorld & a_World);
- /// Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data
+ /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */
bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item);
- /// Parses item metadata as read by ReadItem(), into the item enchantments.
+ /** Parses item metadata as read by ReadItem(), into the item enchantments. */
void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);
void StartEncryption(const Byte * a_Key);
+
+ /** Adds the chat part's style (represented by the part's stylestring) into the Json object. */
+ void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle);
} ;
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index 32409c2aa..6e51ee9cd 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -159,6 +159,16 @@ void cProtocolRecognizer::SendChat(const AString & a_Message)
+void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message)
+{
+ ASSERT(m_Protocol != NULL);
+ m_Protocol->SendChat(a_Message);
+}
+
+
+
+
+
void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
{
ASSERT(m_Protocol != NULL);
diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h
index f58c66d10..800163be6 100644
--- a/src/Protocol/ProtocolRecognizer.h
+++ b/src/Protocol/ProtocolRecognizer.h
@@ -68,6 +68,7 @@ public:
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
+ virtual void SendChat (const cCompositeChat & a_Message) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
diff --git a/src/Root.cpp b/src/Root.cpp
index 749fbd288..206255916 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -543,11 +543,23 @@ void cRoot::ReloadGroups(void)
-void cRoot::LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix)
+void cRoot::BroadcastChat(const AString & a_Message, eMessageType a_ChatPrefix)
{
for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr)
{
- itr->second->LoopPlayersAndBroadcastChat(a_Message, a_ChatPrefix);
+ itr->second->BroadcastChat(a_Message, NULL, a_ChatPrefix);
+ } // for itr - m_WorldsByName[]
+}
+
+
+
+
+
+void cRoot::BroadcastChat(const cCompositeChat & a_Message)
+{
+ for (WorldMap::iterator itr = m_WorldsByName.begin(), end = m_WorldsByName.end(); itr != end; ++itr)
+ {
+ itr->second->BroadcastChat(a_Message);
} // for itr - m_WorldsByName[]
}
diff --git a/src/Root.h b/src/Root.h
index 13e208b8d..4bbd7586f 100644
--- a/src/Root.h
+++ b/src/Root.h
@@ -20,7 +20,8 @@ class cPluginManager;
class cServer;
class cWorld;
class cPlayer;
-class cCommandOutputCallback ;
+class cCommandOutputCallback;
+class cCompositeChat;
typedef cItemCallback<cPlayer> cPlayerListCallback;
typedef cItemCallback<cWorld> cWorldListCallback;
@@ -108,20 +109,19 @@ public:
/// Finds a player from a partial or complete player name and calls the callback - case-insensitive
bool FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS <<
- void LoopWorldsAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix);
- void BroadcastChatJoin (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtJoin); }
- void BroadcastChatLeave (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtLeave); }
- void BroadcastChatDeath (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtDeath); }
-
// tolua_begin
/// Sends a chat message to all connected clients (in all worlds)
- void BroadcastChat (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtCustom); }
- void BroadcastChatInfo (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtInformation); }
- void BroadcastChatFailure(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtFailure); }
- void BroadcastChatSuccess(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtSuccess); }
- void BroadcastChatWarning(const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtWarning); }
- void BroadcastChatFatal (const AString & a_Message) { LoopWorldsAndBroadcastChat(a_Message, mtFailure); }
+ void BroadcastChat (const AString & a_Message, eMessageType a_ChatPrefix = mtCustom);
+ void BroadcastChatInfo (const AString & a_Message) { BroadcastChat(a_Message, mtInformation); }
+ void BroadcastChatFailure(const AString & a_Message) { BroadcastChat(a_Message, mtFailure); }
+ void BroadcastChatSuccess(const AString & a_Message) { BroadcastChat(a_Message, mtSuccess); }
+ void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(a_Message, mtWarning); }
+ void BroadcastChatFatal (const AString & a_Message) { BroadcastChat(a_Message, mtFailure); }
+ void BroadcastChatJoin (const AString & a_Message) { BroadcastChat(a_Message, mtJoin); }
+ void BroadcastChatLeave (const AString & a_Message) { BroadcastChat(a_Message, mtLeave); }
+ void BroadcastChatDeath (const AString & a_Message) { BroadcastChat(a_Message, mtDeath); }
+ void BroadcastChat (const cCompositeChat & a_Message);
/// Returns the textual description of the protocol version: 49 -> "1.4.4". Provided specifically for Lua API
static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum);
diff --git a/src/World.cpp b/src/World.cpp
index cb07caa5d..d67ad36d1 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -1747,7 +1747,7 @@ void cWorld::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cons
-void cWorld::LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const cClientHandle * a_Exclude)
+void cWorld::BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude, eMessageType a_ChatPrefix)
{
cCSLock Lock(m_CSPlayers);
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
@@ -1765,6 +1765,24 @@ void cWorld::LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCo
+void cWorld::BroadcastChat(const cCompositeChat & a_Message, const cClientHandle * a_Exclude)
+{
+ cCSLock Lock(m_CSPlayers);
+ for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
+ {
+ cClientHandle * ch = (*itr)->GetClientHandle();
+ if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed())
+ {
+ continue;
+ }
+ ch->SendChat(a_Message);
+ }
+}
+
+
+
+
+
void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude)
{
m_ChunkMap->BroadcastChunkData(a_ChunkX, a_ChunkZ, a_Serializer, a_Exclude);
diff --git a/src/World.h b/src/World.h
index ca1b7dcc5..97358b88a 100644
--- a/src/World.h
+++ b/src/World.h
@@ -46,6 +46,7 @@ class cDispenserEntity;
class cFurnaceEntity;
class cNoteEntity;
class cMobCensus;
+class cCompositeChat;
typedef std::list< cPlayer * > cPlayerList;
@@ -167,16 +168,15 @@ public:
void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL);
void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); ///< If there is a block entity at the specified coods, sends it to all clients except a_Exclude
- void LoopPlayersAndBroadcastChat(const AString & a_Message, ChatPrefixCodes a_ChatPrefix, const cClientHandle * a_Exclude = NULL);
- void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtDeath, a_Exclude); }
-
// tolua_begin
- void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtCustom, a_Exclude); }
- void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtInformation, a_Exclude); }
- void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtFailure, a_Exclude); }
- void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtSuccess, a_Exclude); }
- void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtWarning, a_Exclude); }
- void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { LoopPlayersAndBroadcastChat(a_Message, mtFailure, a_Exclude); }
+ void BroadcastChat (const AString & a_Message, const cClientHandle * a_Exclude = NULL, eMessageType a_ChatPrefix = mtCustom);
+ void BroadcastChatInfo (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtInformation); }
+ void BroadcastChatFailure(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtFailure); }
+ void BroadcastChatSuccess(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtSuccess); }
+ void BroadcastChatWarning(const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtWarning); }
+ void BroadcastChatFatal (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtFailure); }
+ void BroadcastChatDeath (const AString & a_Message, const cClientHandle * a_Exclude = NULL) { BroadcastChat(a_Message, a_Exclude, mtDeath); }
+ void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = NULL);
// tolua_end
void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL);