1
0

Merge branch 'master' into master

This commit is contained in:
electromatter 2015-09-21 22:44:34 -04:00
commit a24cc01843
38 changed files with 405 additions and 1017 deletions

2
Server/.gitignore vendored
View File

@ -7,6 +7,8 @@ Cuberite
Cuberite_debug Cuberite_debug
CommLogs/ CommLogs/
GalExports/ GalExports/
GalExportWeb/
GalleryWeb/
logs logs
players players
world* world*

View File

@ -24,9 +24,9 @@
<p>ZBS is open-source, the sources are on GitHub: <a href="https://github.com/pkulchenko/ZeroBraneStudio">https://github.com/pkulchenko/ZeroBraneStudio</a>. The project's homepage is at <a href="http://studio.zerobrane.com/">http://studio.zerobrane.com/</a>. <p>ZBS is open-source, the sources are on GitHub: <a href="https://github.com/pkulchenko/ZeroBraneStudio">https://github.com/pkulchenko/ZeroBraneStudio</a>. The project's homepage is at <a href="http://studio.zerobrane.com/">http://studio.zerobrane.com/</a>.
<h2><img src="Static/zbs_logo.png" /> First-time setup</h2> <h2><img src="Static/zbs_logo.png" /> First-time setup</h2>
<p>Since ZBS is a universal Lua IDE, you need to first set it up so that it is ready for Cuberite plugin development. For that, you need to download one file, <a href="https://raw.githubusercontent.com/pkulchenko/ZeroBranePackage/master/mcserver.lua">mcserver.lua</a> from the <a href="https://github.com/pkulchenko/ZeroBranePackage">ZBS's plugin repository</a>. Place that file in the "packages" folder inside your ZBS's folder. Note that there are other useful plugins in the repository and you may want to have a look there later on to further customize your ZBS. To install them, simply save them into the same folder.</p> <p>Since ZBS is a universal Lua IDE, you need to first set it up so that it is ready for Cuberite plugin development. For that, you need to download one file, <a href="https://raw.githubusercontent.com/pkulchenko/ZeroBranePackage/master/cuberite.lua">cuberite.lua</a> from the <a href="https://github.com/pkulchenko/ZeroBranePackage">ZBS's plugin repository</a>. Place that file in the "packages" folder inside your ZBS's folder. Note that there are other useful plugins in the repository and you may want to have a look there later on to further customize your ZBS. To install them, simply save them into the same folder.</p>
<p>Next you should install the code-completion support specific for Cuberite. You should repeat this step from time to time, because the API evolves in time so new functions and classes are added to it quite often. You should have an APIDump plugin in your Cuberite installation. Enable the APIDump plugin in the server settings, it's very cheap to keep it enabled and it doesn't cost any performance during normal gameplay. To generate the code-completion support file, enter the <code style="background: #ddd; border: 1px solid #aaa">api</code> command into the server console. This will create a new file, "mcserver_api.lua", next to the Cuberite executable. Move that file into the "api/lua" subfolder inside your ZBS's folder.</p> <p>Next you should install the code-completion support specific for Cuberite. You should repeat this step from time to time, because the API evolves in time so new functions and classes are added to it quite often. You should have an APIDump plugin in your Cuberite installation. Enable the APIDump plugin in the server settings, it's very cheap to keep it enabled and it doesn't cost any performance during normal gameplay. To generate the code-completion support file, enter the <code style="background: #ddd; border: 1px solid #aaa">api</code> command into the server console. This will create a new file, "cuberite_api.lua", next to the Cuberite executable. Move that file into the "api/lua" subfolder inside your ZBS's folder. (Note that if you had the "mcserver_api.lua" file from previous versions, you should remove it)</p>
<p>After you download the mcserver.lua file and install the completion support, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "Cuberite - debug mode" and "Cuberite - release mode". The only difference between the two is which filename they use to launch Cuberite - mcserver_debug(.exe) for the debug option and "mcserver(.exe)" for the release option. If you built your own Cuberite executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled Cuberite executable from the internet, you should select the release mode option.</p> <p>After you download the cuberite.lua file and install the completion support, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "Cuberite - debug mode" and "Cuberite - release mode". The only difference between the two is which filename they use to launch Cuberite - cuberite_debug(.exe) for the debug option and "cuberite(.exe)" for the release option. If you built your own Cuberite executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled Cuberite executable from the internet, you should select the release mode option.</p>
<p>For a first time user, it might be a bit overwhelming that there are no GUI settings in the ZBS, yet the IDE is very configurable. There are two files that you edit in order to change settings, either system-wide (all users of the computer share those settings) or user-wide (the settings are only for a specific user of the computer). Those files are regular Lua sources and you can quickly locate them and edit them from within the IDE itself, select Edit -> Preferences -> Settings: XYZ from the menu, with XYZ being either System or User.</p> <p>For a first time user, it might be a bit overwhelming that there are no GUI settings in the ZBS, yet the IDE is very configurable. There are two files that you edit in order to change settings, either system-wide (all users of the computer share those settings) or user-wide (the settings are only for a specific user of the computer). Those files are regular Lua sources and you can quickly locate them and edit them from within the IDE itself, select Edit -> Preferences -> Settings: XYZ from the menu, with XYZ being either System or User.</p>
<p>There is a documentation on most of the settings on ZBS's webpage, have a look at <a href="http://studio.zerobrane.com/documentation.html">http://studio.zerobrane.com/documentation.html</a>, especially the Preferences section. Personally I recommend setting editor.usetabs to true and possibly adjusting the editor.tabwidth, turn off the editor.smartindent feature and for debugging the option debugger.alloweditting should be set to true unless you feel like punishing yourself.</p> <p>There is a documentation on most of the settings on ZBS's webpage, have a look at <a href="http://studio.zerobrane.com/documentation.html">http://studio.zerobrane.com/documentation.html</a>, especially the Preferences section. Personally I recommend setting editor.usetabs to true and possibly adjusting the editor.tabwidth, turn off the editor.smartindent feature and for debugging the option debugger.alloweditting should be set to true unless you feel like punishing yourself.</p>
@ -37,7 +37,7 @@
<h2><img src="Static/zbs_logo.png" /> Debugging</h2> <h2><img src="Static/zbs_logo.png" /> Debugging</h2>
<p>You are now ready to debug your code. Before doing that, though, don't forget to save your project files. If you haven't done so already, enable your plugin in the settings.ini file. If you want the program to break at a certain line, it is best to set the breakpoint before starting the program. Set the cursor on the line and hit F9 (or use menu Project -> Toggle Breakpoint) to toggle a breakpoint on that line. Finally, hit F5, or select menu Project -> Start Debugging to launch Cuberite under the debugger. The Cuberite window comes up and loads your plugin. If the window doesn't come up, inspect the Output pane in ZBS, there are usually two reasons for failure:<ul> <p>You are now ready to debug your code. Before doing that, though, don't forget to save your project files. If you haven't done so already, enable your plugin in the settings.ini file. If you want the program to break at a certain line, it is best to set the breakpoint before starting the program. Set the cursor on the line and hit F9 (or use menu Project -> Toggle Breakpoint) to toggle a breakpoint on that line. Finally, hit F5, or select menu Project -> Start Debugging to launch Cuberite under the debugger. The Cuberite window comes up and loads your plugin. If the window doesn't come up, inspect the Output pane in ZBS, there are usually two reasons for failure:<ul>
<li>Your code in the currently open file has a hard syntax error. These are reported as "Compilation error" in the Output pane, double-click the line to go to the error</li> <li>Your code in the currently open file has a hard syntax error. These are reported as "Compilation error" in the Output pane, double-click the line to go to the error</li>
<li>ZBS cannot find the Cuberite executable. Make sure you are editting a file two levels down the folder hierarchy from the Cuberite executable and that the Cuberite executable is named properly (mcserver[.exe] or mcserver_debug[.exe]). Also make sure you have selected the right Interpreter (menu Project -> Lua Interpreter).</li> <li>ZBS cannot find the Cuberite executable. Make sure you are editting a file two or three levels down the folder hierarchy from the Cuberite executable and that the Cuberite executable is named properly (cuberite[.exe] or cuberite_debug[.exe]). Also make sure you have selected the right Interpreter (menu Project -> Lua Interpreter).</li>
</ul></p> </ul></p>
<p>Once running, if the execution hits a breakpoint, the ZBS window will come up and a green arrow is displayed next to the breakpoint line. You can step through the code using F10 (Step Into) and Shift+F10 (Step Over). You can also use the Watch window to inspect variable values, or simply hover your mouse over a variable to display its value in the tooltip. Use the Remote console pane to execute commands directly *inside* the Cuberite's plugin context.</p> <p>Once running, if the execution hits a breakpoint, the ZBS window will come up and a green arrow is displayed next to the breakpoint line. You can step through the code using F10 (Step Into) and Shift+F10 (Step Over). You can also use the Watch window to inspect variable values, or simply hover your mouse over a variable to display its value in the tooltip. Use the Remote console pane to execute commands directly *inside* the Cuberite's plugin context.</p>
<p>You can also use the Project -> Break menu item to break into the debugger as soon as possible. You can also set breakpoints while the Cuberite plugin is running. Note that due to the way in which the debugger is implemented, Cuberite may execute some more Lua code before the break / breakpoint comes into effect. If Cuberite is not executing any Lua code in your plugin, it will not break until the plugin code kicks in again. This may result in missed breakpoints and delays before the Break command becomes effective. Therefore it's best to set breakpoints before running the program, or while the program is waiting in another breakpoint.</p> <p>You can also use the Project -> Break menu item to break into the debugger as soon as possible. You can also set breakpoints while the Cuberite plugin is running. Note that due to the way in which the debugger is implemented, Cuberite may execute some more Lua code before the break / breakpoint comes into effect. If Cuberite is not executing any Lua code in your plugin, it will not break until the plugin code kicks in again. This may result in missed breakpoints and delays before the Break command becomes effective. Therefore it's best to set breakpoints before running the program, or while the program is waiting in another breakpoint.</p>

View File

@ -1432,9 +1432,9 @@ end
--- Dumps the entire API table into a file in the ZBS format --- Dumps the entire API table into a file in the ZBS format
local function DumpAPIZBS(a_API) local function DumpAPIZBS(a_API)
LOG("Dumping ZBS API description...") LOG("Dumping ZBS API description...")
local f, err = io.open("mcserver_api.lua", "w") local f, err = io.open("cuberite_api.lua", "w")
if (f == nil) then if (f == nil) then
LOG("Cannot open mcserver_lua.lua for writing, ZBS API will not be dumped. " .. err) LOG("Cannot open cuberite_api.lua for writing, ZBS API will not be dumped. " .. err)
return return
end end

View File

@ -22,26 +22,26 @@ static const Byte g_Zeroes[4096] = {0};
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
cLogger::cListener * consoleLogListener = MakeConsoleListener(false); auto consoleLogListener = MakeConsoleListener(false);
cLogger::cListener * fileLogListener = new cFileListener(); auto consoleAttachment = cLogger::GetInstance().AttachListener(std::move(consoleLogListener));
cLogger::GetInstance().AttachListener(consoleLogListener); auto fileLogListenerRet = MakeFileListener();
cLogger::GetInstance().AttachListener(fileLogListener); if (!fileLogListenerRet.first)
{
LOGERROR("Failed to open log file, aborting");
return EXIT_FAILURE;
}
auto fileAttachment = cLogger::GetInstance().AttachListener(std::move(fileLogListenerRet.second));
cLogger::InitiateMultithreading(); cLogger::InitiateMultithreading();
cMCADefrag Defrag; cMCADefrag Defrag;
if (!Defrag.Init(argc, argv)) if (!Defrag.Init(argc, argv))
{ {
return 1; return EXIT_FAILURE;
} }
Defrag.Run(); Defrag.Run();
cLogger::GetInstance().DetachListener(consoleLogListener);
delete consoleLogListener;
cLogger::GetInstance().DetachListener(fileLogListener);
delete fileLogListener;
return 0; return 0;
} }

View File

@ -15,11 +15,17 @@
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
// Initialize logging subsystem: // Initialize logging subsystem:
cLogger::InitiateMultithreading();
auto consoleLogListener = MakeConsoleListener(false); auto consoleLogListener = MakeConsoleListener(false);
auto fileLogListener = new cFileListener(); auto consoleAttachment = cLogger::GetInstance().AttachListener(std::move(consoleLogListener));
cLogger::GetInstance().AttachListener(consoleLogListener); auto fileLogListenerRet = MakeFileListener();
cLogger::GetInstance().AttachListener(fileLogListener); if (!fileLogListenerRet.first)
{
LOGERROR("Failed to open log file, aborting");
return EXIT_FAILURE;
}
auto fileAttachment = cLogger::GetInstance().AttachListener(std::move(fileLogListenerRet.second));
cLogger::InitiateMultithreading();
int ListenPort = (argc > 1) ? atoi(argv[1]) : 25564; int ListenPort = (argc > 1) ? atoi(argv[1]) : 25564;
int ConnectPort = (argc > 2) ? atoi(argv[2]) : 25565; int ConnectPort = (argc > 2) ? atoi(argv[2]) : 25565;

12
circle.yml Normal file
View File

@ -0,0 +1,12 @@
# This is the YML file that governs the CI builds at CircleCI.com
# The CI is used only for style-checking at this moment.
dependencies:
pre:
- sudo apt-get install lua5.1
test:
override:
- cd src && find . -name \*.cpp -or -name \*.h > AllFiles.lst
- cd src && lua CheckBasicStyle.lua

View File

@ -22,23 +22,23 @@ endif()
# Lua needs to be linked dynamically on Windows and statically on *nix, so that LuaRocks work # Lua needs to be linked dynamically on Windows and statically on *nix, so that LuaRocks work
if (WIN32) if (WIN32)
add_library(lua SHARED ${SOURCE}) add_library(lua SHARED ${SOURCE})
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server)
# Output the executable into the $/MCServer folder, so that MCServer can find it: # Output the executable into the $/Server folder, so that Cuberite can find it:
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server)
SET_TARGET_PROPERTIES(lua PROPERTIES SET_TARGET_PROPERTIES(lua PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
) )
if (MSVC) if (MSVC)

View File

@ -30,28 +30,28 @@ if (WIN32)
endif() endif()
add_library(luaproxy SHARED "lua5.1.def" "Dummy.c") add_library(luaproxy SHARED "lua5.1.def" "Dummy.c")
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server)
set_target_properties(luaproxy PROPERTIES set_target_properties(luaproxy PROPERTIES
OUTPUT_NAME "lua5.1" OUTPUT_NAME "lua5.1"
PREFIX "" PREFIX ""
) )
target_link_libraries(luaproxy lua) target_link_libraries(luaproxy lua)
# Output the executable into the $/MCServer folder, so that MCServer can find it: # Output the executable into the $/Server folder, so that Cuberite can find it:
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server)
SET_TARGET_PROPERTIES(luaproxy PROPERTIES SET_TARGET_PROPERTIES(luaproxy PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
) )
else() else()

View File

@ -20,7 +20,8 @@ SET (SRCS
MobHeadEntity.cpp MobHeadEntity.cpp
MobSpawnerEntity.cpp MobSpawnerEntity.cpp
NoteEntity.cpp NoteEntity.cpp
SignEntity.cpp) SignEntity.cpp
)
SET (HDRS SET (HDRS
BeaconEntity.h BeaconEntity.h
@ -39,7 +40,9 @@ SET (HDRS
MobHeadEntity.h MobHeadEntity.h
MobSpawnerEntity.h MobSpawnerEntity.h
NoteEntity.h NoteEntity.h
SignEntity.h) RedstonePoweredEntity.h
SignEntity.h
)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set_source_files_properties(BeaconEntity.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=conversion -Wno-error=switch-enum") set_source_files_properties(BeaconEntity.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=conversion -Wno-error=switch-enum")

View File

@ -1,13 +1,30 @@
// RedstonePoweredEntity.h
// Declares the cRedstonePoweredEntity class representing a mix-in for block entities that respond to redstone
#pragma once #pragma once
// Interface class representing a blockEntity that responds to redstone
/** Interface class representing a mix-in for block entities that respond to redstone */
class cRedstonePoweredEntity class cRedstonePoweredEntity
{ {
public: public:
virtual ~cRedstonePoweredEntity() {} virtual ~cRedstonePoweredEntity() {}
/// Sets the internal redstone power flag to "on" or "off", depending on the parameter. Calls Activate() if appropriate /** Sets the internal redstone power flag to "on" or "off", depending on the parameter.
Calls Activate() if appropriate */
virtual void SetRedstonePower(bool a_IsPowered) = 0; virtual void SetRedstonePower(bool a_IsPowered) = 0;
}; };

View File

@ -19,7 +19,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
cFastRandom Random; cFastRandom Random;
if (Random.NextInt(30) == 0) if (Random.NextInt(10) == 0)
{ {
a_Pickups.Add(E_ITEM_FLINT, 1, 0); a_Pickups.Add(E_ITEM_FLINT, 1, 0);
} }

View File

@ -49,13 +49,12 @@ protected:
Light = Blocklight; Light = Blocklight;
} }
// Return true if there is enough light // Based on light levels, decide between growth, stay and death:
// Set m_ShouldDie if the base light amounts are not enough to sustain a plant
if (Light > 8) if (Light > 8)
{ {
return paGrowth; return paGrowth;
} }
else if (Blocklight < 9 && SkyLight < 9) else if ((Blocklight < 9) && (SkyLight < 9))
{ {
return paDeath; return paDeath;
} }

View File

@ -9,7 +9,8 @@ SET (SRCS
BlockDoor.cpp BlockDoor.cpp
BlockHandler.cpp BlockHandler.cpp
BlockPiston.cpp BlockPiston.cpp
ChunkInterface.cpp) ChunkInterface.cpp
)
SET (HDRS SET (HDRS
BlockAnvil.h BlockAnvil.h
@ -54,12 +55,15 @@ SET (HDRS
BlockLilypad.h BlockLilypad.h
BlockMelon.h BlockMelon.h
BlockMobHead.h BlockMobHead.h
BlockMobSpawner.h
BlockMushroom.h BlockMushroom.h
BlockMycelium.h BlockMycelium.h
BlockNetherrack.h
BlockNetherWart.h BlockNetherWart.h
BlockOre.h BlockOre.h
BlockPiston.h BlockPiston.h
BlockPlanks.h BlockPlanks.h
BlockPlant.h
BlockPluginInterface.h BlockPluginInterface.h
BlockPortal.h BlockPortal.h
BlockPressurePlate.h BlockPressurePlate.h
@ -72,6 +76,7 @@ SET (HDRS
BlockRedstoneTorch.h BlockRedstoneTorch.h
BlockSand.h BlockSand.h
BlockSapling.h BlockSapling.h
BlockSeaLantern.h
BlockSideways.h BlockSideways.h
BlockSignPost.h BlockSignPost.h
BlockSlab.h BlockSlab.h
@ -80,8 +85,8 @@ SET (HDRS
BlockStems.h BlockStems.h
BlockStone.h BlockStone.h
BlockSugarcane.h BlockSugarcane.h
BlockTNT.h
BlockTallGrass.h BlockTallGrass.h
BlockTNT.h
BlockTorch.h BlockTorch.h
BlockTrapdoor.h BlockTrapdoor.h
BlockTripwire.h BlockTripwire.h
@ -92,8 +97,10 @@ SET (HDRS
BroadcastInterface.h BroadcastInterface.h
ChunkInterface.h ChunkInterface.h
ClearMetaOnDrop.h ClearMetaOnDrop.h
GetHandlerCompileTimeTemplate.h
MetaRotator.h MetaRotator.h
WorldInterface.h) WorldInterface.h
)
if(NOT MSVC) if(NOT MSVC)
add_library(Blocks ${SRCS} ${HDRS}) add_library(Blocks ${SRCS} ${HDRS})

View File

@ -98,6 +98,7 @@ SET (HDRS
ChunkSender.h ChunkSender.h
ChunkStay.h ChunkStay.h
ClientHandle.h ClientHandle.h
Color.h
CommandOutput.h CommandOutput.h
CompositeChat.h CompositeChat.h
CraftingRecipes.h CraftingRecipes.h
@ -316,7 +317,7 @@ if (MSVC)
OUTPUT ${BINDING_OUTPUTS} OUTPUT ${BINDING_OUTPUTS}
# Copy the Lua DLL into the Bindings folder, so that tolua can run from there: # Copy the Lua DLL into the Bindings folder, so that tolua can run from there:
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/MCServer/lua51.dll ./lua51.dll COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/Server/lua51.dll ./lua51.dll
# Regenerate bindings: # Regenerate bindings:
COMMAND tolua -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg COMMAND tolua -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
@ -330,7 +331,7 @@ endif()
add_executable(${EXECUTABLE} ${SOURCE}) add_executable(${EXECUTABLE} ${SOURCE})
# Output the executable into the $/MCServer folder, so that it has access to external resources: # Output the executable into the $/Server folder, so that it has access to external resources:
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server) set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server)
SET_TARGET_PROPERTIES(${EXECUTABLE} PROPERTIES SET_TARGET_PROPERTIES(${EXECUTABLE} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server

View File

@ -412,6 +412,12 @@ end
-- Process the files in the list: -- Process the files in the list:
for _, fnam in ipairs(ToProcess) do for _, fnam in ipairs(ToProcess) do
-- Remove the optional "./" prefix:
if (fnam:sub(1, 2) == "./") then
fnam = fnam:sub(3)
end
ProcessItem(fnam) ProcessItem(fnam)
end end

View File

@ -199,9 +199,9 @@ void cChunk::MarkRegenerating(void)
SetPresence(cpQueued); SetPresence(cpQueued);
// Tell all clients attached to this chunk that they want this chunk: // Tell all clients attached to this chunk that they want this chunk:
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto ClientHandle : m_LoadedByClient)
{ {
(*itr)->AddWantedChunk(m_PosX, m_PosZ); ClientHandle->AddWantedChunk(m_PosX, m_PosZ);
} // for itr - m_LoadedByClient[] } // for itr - m_LoadedByClient[]
} }
@ -474,25 +474,25 @@ void cChunk::Stay(bool a_Stay)
void cChunk::CollectMobCensus(cMobCensus & toFill) void cChunk::CollectMobCensus(cMobCensus & toFill)
{ {
toFill.CollectSpawnableChunk(*this); toFill.CollectSpawnableChunk(*this);
std::list<const Vector3d *> playerPositions; std::vector<Vector3d> PlayerPositions;
cPlayer * currentPlayer; PlayerPositions.reserve(m_LoadedByClient.size());
for (auto itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr) for (auto ClientHandle : m_LoadedByClient)
{ {
currentPlayer = (*itr)->GetPlayer(); const cPlayer * currentPlayer = ClientHandle->GetPlayer();
playerPositions.push_back(&(currentPlayer->GetPosition())); PlayerPositions.push_back(currentPlayer->GetPosition());
} }
Vector3d currentPosition; Vector3d currentPosition;
for (auto itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) for (auto entity : m_Entities)
{ {
// LOGD("Counting entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass()); // LOGD("Counting entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass());
if ((*itr)->IsMob()) if (entity->IsMob())
{ {
auto & Monster = reinterpret_cast<cMonster &>(**itr); auto & Monster = reinterpret_cast<cMonster &>(*entity);
currentPosition = Monster.GetPosition(); currentPosition = Monster.GetPosition();
for (auto itr2 = playerPositions.cbegin(); itr2 != playerPositions.cend(); ++itr2) for (const auto PlayerPos : PlayerPositions)
{ {
toFill.CollectMob(Monster, *this, (currentPosition - **itr2).SqrLength()); toFill.CollectMob(Monster, *this, (currentPosition - PlayerPos).SqrLength());
} }
} }
} // for itr - m_Entitites[] } // for itr - m_Entitites[]
@ -779,17 +779,17 @@ void cChunk::BroadcastPendingBlockChanges(void)
if (m_PendingSendBlocks.size() >= 10240) if (m_PendingSendBlocks.size() >= 10240)
{ {
// Resend the full chunk // Resend the full chunk
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr) for (auto ClientHandle : m_LoadedByClient)
{ {
m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM, (*itr)); m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM, ClientHandle);
} }
} }
else else
{ {
// Only send block changes // Only send block changes
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr) for (auto ClientHandle : m_LoadedByClient)
{ {
(*itr)->SendBlockChanges(m_PosX, m_PosZ, m_PendingSendBlocks); ClientHandle->SendBlockChanges(m_PosX, m_PosZ, m_PendingSendBlocks);
} }
} }
m_PendingSendBlocks.clear(); m_PendingSendBlocks.clear();
@ -1758,9 +1758,9 @@ void cChunk::SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_Max
MarkDirty(); MarkDirty();
// Re-send the chunk to all clients: // Re-send the chunk to all clients:
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto ClientHandle : m_LoadedByClient)
{ {
m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM, (*itr)); m_World->ForceSendChunkTo(m_PosX, m_PosZ, cChunkSender::E_CHUNK_PRIORITY_MEDIUM, ClientHandle);
} // for itr - m_LoadedByClient[] } // for itr - m_LoadedByClient[]
} }
@ -1856,15 +1856,13 @@ void cChunk::RemoveBlockEntity(cBlockEntity * a_BlockEntity)
bool cChunk::AddClient(cClientHandle * a_Client) bool cChunk::AddClient(cClientHandle * a_Client)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) if (std::find(m_LoadedByClient.begin(), m_LoadedByClient.end(), a_Client) != m_LoadedByClient.end())
{ {
if (a_Client == *itr) // Already there, nothing needed
{ return false;
// Already there, nothing needed
return false;
}
} }
m_LoadedByClient.push_back( a_Client);
m_LoadedByClient.push_back(a_Client);
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
{ {
@ -1887,31 +1885,28 @@ bool cChunk::AddClient(cClientHandle * a_Client)
void cChunk::RemoveClient(cClientHandle * a_Client) void cChunk::RemoveClient(cClientHandle * a_Client)
{ {
for (cClientHandleList::iterator itrC = m_LoadedByClient.begin(); itrC != m_LoadedByClient.end(); ++itrC) auto itr = std::remove(m_LoadedByClient.begin(), m_LoadedByClient.end(), a_Client);
// We should always remove at most one client.
ASSERT(std::distance(itr, m_LoadedByClient.end()) <= 1);
// Note: itr can equal m_LoadedByClient.end()
m_LoadedByClient.erase(itr, m_LoadedByClient.end());
if (!a_Client->IsDestroyed())
{ {
if (*itrC != a_Client) for (auto Entity : m_Entities)
{ {
continue; /*
// DEBUG:
LOGD("chunk [%i, %i] destroying entity #%i for player \"%s\"",
m_PosX, m_PosZ,
(*itr)->GetUniqueID(), a_Client->GetUsername().c_str()
);
*/
a_Client->SendDestroyEntity(*Entity);
} }
}
m_LoadedByClient.erase(itrC); return;
if (!a_Client->IsDestroyed())
{
for (cEntityList::iterator itrE = m_Entities.begin(); itrE != m_Entities.end(); ++itrE)
{
/*
// DEBUG:
LOGD("chunk [%i, %i] destroying entity #%i for player \"%s\"",
m_PosX, m_PosZ,
(*itr)->GetUniqueID(), a_Client->GetUsername().c_str()
);
*/
a_Client->SendDestroyEntity(*(*itrE));
}
}
return;
} // for itr - m_LoadedByClient[]
} }
@ -1920,14 +1915,7 @@ void cChunk::RemoveClient(cClientHandle * a_Client)
bool cChunk::HasClient(cClientHandle * a_Client) bool cChunk::HasClient(cClientHandle * a_Client)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) return std::find(m_LoadedByClient.begin(), m_LoadedByClient.end(), a_Client) != m_LoadedByClient.end();
{
if ((*itr) == a_Client)
{
return true;
}
}
return false;
} }
@ -2793,9 +2781,9 @@ cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) con
void cChunk::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) void cChunk::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto ClientHandle : m_LoadedByClient)
{ {
(*itr)->SendAttachEntity(a_Entity, a_Vehicle); ClientHandle->SendAttachEntity(a_Entity, a_Vehicle);
} // for itr - LoadedByClient[] } // for itr - LoadedByClient[]
} }
@ -2805,7 +2793,7 @@ void cChunk::BroadcastAttachEntity(const cEntity & a_Entity, const cEntity * a_V
void cChunk::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude) void cChunk::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2821,7 +2809,7 @@ void cChunk::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char
void cChunk::BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude) void cChunk::BroadcastBlockBreakAnimation(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2843,7 +2831,7 @@ void cChunk::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cons
{ {
return; return;
} }
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2859,7 +2847,7 @@ void cChunk::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cons
void cChunk::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude) void cChunk::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2875,7 +2863,7 @@ void cChunk::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_
void cChunk::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude) void cChunk::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2891,7 +2879,7 @@ void cChunk::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandl
void cChunk::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2907,7 +2895,7 @@ void cChunk::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int
void cChunk::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2923,7 +2911,7 @@ void cChunk::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum,
void cChunk::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2939,7 +2927,7 @@ void cChunk::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHand
void cChunk::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2955,7 +2943,7 @@ void cChunk::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle *
void cChunk::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2971,7 +2959,7 @@ void cChunk::BroadcastEntityMetadata(const cEntity & a_Entity, const cClientHand
void cChunk::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -2987,7 +2975,7 @@ void cChunk::BroadcastEntityRelMove(const cEntity & a_Entity, char a_RelX, char
void cChunk::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3003,7 +2991,7 @@ void cChunk::BroadcastEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, c
void cChunk::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3019,7 +3007,7 @@ void cChunk::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, cons
void cChunk::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3035,7 +3023,7 @@ void cChunk::BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHand
void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude) void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3051,7 +3039,7 @@ void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation
void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude) void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount, cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3067,7 +3055,7 @@ void cChunk::BroadcastParticleEffect(const AString & a_ParticleName, float a_Src
void cChunk::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude) void cChunk::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3083,7 +3071,7 @@ void cChunk::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectI
void cChunk::BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude) void cChunk::BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3099,7 +3087,7 @@ void cChunk::BroadcastSoundEffect(const AString & a_SoundName, double a_X, doubl
void cChunk::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude) void cChunk::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3115,7 +3103,7 @@ void cChunk::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY
void cChunk::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude) void cChunk::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3131,7 +3119,7 @@ void cChunk::BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Ex
void cChunk::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude) void cChunk::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
if (*itr == a_Exclude) if (*itr == a_Exclude)
{ {
@ -3147,7 +3135,7 @@ void cChunk::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, cons
void cChunk::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) void cChunk::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr) for (auto itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
{ {
(*itr)->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ); (*itr)->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
} // for itr - LoadedByClient[] } // for itr - LoadedByClient[]

View File

@ -439,7 +439,10 @@ public:
void SetAlwaysTicked(bool a_AlwaysTicked); void SetAlwaysTicked(bool a_AlwaysTicked);
// Makes a copy of the list // Makes a copy of the list
cClientHandleList GetAllClients(void) const {return m_LoadedByClient; } cClientHandleList GetAllClients(void) const
{
return cClientHandleList(m_LoadedByClient.begin(), m_LoadedByClient.end());
}
private: private:
@ -479,9 +482,9 @@ private:
sSetBlockQueueVector m_SetBlockQueue; ///< Block changes that are queued to a specific tick sSetBlockQueueVector m_SetBlockQueue; ///< Block changes that are queued to a specific tick
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
cClientHandleList m_LoadedByClient; std::vector<cClientHandle *> m_LoadedByClient;
cEntityList m_Entities; cEntityList m_Entities;
cBlockEntityList m_BlockEntities; cBlockEntityList m_BlockEntities;
/** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */ /** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */
int m_StayCount; int m_StayCount;

View File

@ -2086,8 +2086,9 @@ void cClientHandle::SendChat(const AString & a_Message, eMessageType a_ChatPrefi
} }
} }
AString Message = FormatMessageType(World->ShouldUseChatPrefixes(), a_ChatPrefix, a_AdditionalData); bool ShouldUsePrefixes = World->ShouldUseChatPrefixes();
m_Protocol->SendChat(Message.append(a_Message)); AString Message = FormatMessageType(ShouldUsePrefixes, a_ChatPrefix, a_AdditionalData);
m_Protocol->SendChat(Message.append(a_Message), ctChatBox, ShouldUsePrefixes);
} }
@ -2096,7 +2097,7 @@ void cClientHandle::SendChat(const AString & a_Message, eMessageType a_ChatPrefi
void cClientHandle::SendChat(const cCompositeChat & a_Message) void cClientHandle::SendChat(const cCompositeChat & a_Message)
{ {
m_Protocol->SendChat(a_Message); m_Protocol->SendChat(a_Message, ctChatBox, GetPlayer()->GetWorld()->ShouldUseChatPrefixes());
} }
@ -2116,7 +2117,7 @@ void cClientHandle::SendChatAboveActionBar(const AString & a_Message, eMessageTy
} }
AString Message = FormatMessageType(World->ShouldUseChatPrefixes(), a_ChatPrefix, a_AdditionalData); AString Message = FormatMessageType(World->ShouldUseChatPrefixes(), a_ChatPrefix, a_AdditionalData);
m_Protocol->SendChatAboveActionBar(Message.append(a_Message)); m_Protocol->SendChat(Message.append(a_Message), ctAboveActionBar);
} }
@ -2125,7 +2126,7 @@ void cClientHandle::SendChatAboveActionBar(const AString & a_Message, eMessageTy
void cClientHandle::SendChatAboveActionBar(const cCompositeChat & a_Message) void cClientHandle::SendChatAboveActionBar(const cCompositeChat & a_Message)
{ {
m_Protocol->SendChatAboveActionBar(a_Message); m_Protocol->SendChat(a_Message, ctAboveActionBar, GetPlayer()->GetWorld()->ShouldUseChatPrefixes());
} }
@ -2144,8 +2145,9 @@ void cClientHandle::SendChatSystem(const AString & a_Message, eMessageType a_Cha
} }
} }
AString Message = FormatMessageType(World->ShouldUseChatPrefixes(), a_ChatPrefix, a_AdditionalData); auto ShouldUsePrefixes = World->ShouldUseChatPrefixes();
m_Protocol->SendChatSystem(Message.append(a_Message)); AString Message = FormatMessageType(ShouldUsePrefixes, a_ChatPrefix, a_AdditionalData);
m_Protocol->SendChat(Message.append(a_Message), ctSystem, ShouldUsePrefixes);
} }
@ -2154,7 +2156,7 @@ void cClientHandle::SendChatSystem(const AString & a_Message, eMessageType a_Cha
void cClientHandle::SendChatSystem(const cCompositeChat & a_Message) void cClientHandle::SendChatSystem(const cCompositeChat & a_Message)
{ {
m_Protocol->SendChatSystem(a_Message); m_Protocol->SendChat(a_Message, ctSystem, GetPlayer()->GetWorld()->ShouldUseChatPrefixes());
} }

View File

@ -25,31 +25,31 @@ public:
cColor() { m_Color = static_cast<unsigned int>(COLOR_NONE);} cColor() { m_Color = static_cast<unsigned int>(COLOR_NONE);}
cColor(unsigned char a_Red, unsigned char a_Green, unsigned char a_Blue) { SetColor(a_Red, a_Green, a_Blue); } cColor(unsigned char a_Red, unsigned char a_Green, unsigned char a_Blue) { SetColor(a_Red, a_Green, a_Blue); }
/// Returns whether the color is a valid color /** Returns whether the color is a valid color */
bool IsValid() const { return m_Color != COLOR_NONE; } bool IsValid() const { return m_Color != COLOR_NONE; }
/// Changes the color /** Changes the color */
void SetColor(unsigned char a_Red, unsigned char a_Green, unsigned char a_Blue); void SetColor(unsigned char a_Red, unsigned char a_Green, unsigned char a_Blue);
/// Alters the red value of the color /** Alters the red value of the color */
void SetRed(unsigned char a_Red); void SetRed(unsigned char a_Red);
/// Alters the green value of the color /** Alters the green value of the color */
void SetGreen(unsigned char a_Red); void SetGreen(unsigned char a_Red);
/// Alters the blue value of the color /** Alters the blue value of the color */
void SetBlue(unsigned char a_Red); void SetBlue(unsigned char a_Red);
/// Returns the red value of the color /** Returns the red value of the color */
unsigned char GetRed() const; unsigned char GetRed() const;
/// Returns the green value of the color /** Returns the green value of the color */
unsigned char GetGreen() const; unsigned char GetGreen() const;
/// Returns the blue value of the color /** Returns the blue value of the color */
unsigned char GetBlue() const; unsigned char GetBlue() const;
/// Resets the color /** Resets the color */
void Clear() { m_Color = static_cast<unsigned int>(COLOR_NONE); } void Clear() { m_Color = static_cast<unsigned int>(COLOR_NONE); }
// tolua_end // tolua_end

View File

@ -5,6 +5,7 @@
#include "Defines.h" #include "Defines.h"
#include "json/json.h" #include "json/json.h"
#include "Logger.h"

View File

@ -271,7 +271,25 @@ template class SizeChecker<UInt8, 1>;
#include "OSSupport/StackTrace.h" #include "OSSupport/StackTrace.h"
#ifndef TEST_GLOBALS #ifndef TEST_GLOBALS
#include "Logger.h"
// These fiunctions are defined in Logger.cpp, but are declared here to avoid including all of logger.h
extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGERROR (const char * a_Format, ...) FORMATSTRING(1, 2);
// In debug builds, translate LOGD to LOG, otherwise leave it out altogether:
#ifdef _DEBUG
#define LOGD LOG
#else
#define LOGD(...)
#endif // _DEBUG
#define LOGWARN LOGWARNING
#else #else
// Logging functions // Logging functions
void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2); void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2);

View File

@ -5,7 +5,8 @@ project (MCServer)
include_directories ("${PROJECT_SOURCE_DIR}/../") include_directories ("${PROJECT_SOURCE_DIR}/../")
SET (SRCS SET (SRCS
ItemHandler.cpp) ItemHandler.cpp
)
SET (HDRS SET (HDRS
ItemArmor.h ItemArmor.h
@ -26,6 +27,7 @@ SET (HDRS
ItemFishingRod.h ItemFishingRod.h
ItemFlowerPot.h ItemFlowerPot.h
ItemFood.h ItemFood.h
ItemGoldenApple.h
ItemHandler.h ItemHandler.h
ItemHoe.h ItemHoe.h
ItemItemFrame.h ItemItemFrame.h
@ -36,6 +38,7 @@ SET (HDRS
ItemMilk.h ItemMilk.h
ItemMinecart.h ItemMinecart.h
ItemMobHead.h ItemMobHead.h
ItemMushroomSoup.h
ItemNetherWart.h ItemNetherWart.h
ItemPainting.h ItemPainting.h
ItemPickaxe.h ItemPickaxe.h
@ -47,8 +50,8 @@ SET (HDRS
ItemSeeds.h ItemSeeds.h
ItemShears.h ItemShears.h
ItemShovel.h ItemShovel.h
ItemSlab.h
ItemSign.h ItemSign.h
ItemSlab.h
ItemSpawnEgg.h ItemSpawnEgg.h
ItemString.h ItemString.h
ItemSugarcane.h ItemSugarcane.h

View File

@ -1,5 +1,6 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Logger.h"
#include "OSSupport/IsThread.h" #include "OSSupport/IsThread.h"
#ifdef _WIN32 #ifdef _WIN32
@ -73,10 +74,14 @@ void cLogger::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList
void cLogger::AttachListener(cListener * a_Listener) cLogger::cAttachment cLogger::AttachListener(std::unique_ptr<cListener> a_Listener)
{ {
cCSLock Lock(m_CriticalSection); auto nonOwning = a_Listener.get();
m_LogListeners.push_back(a_Listener); {
cCSLock Lock(m_CriticalSection);
m_LogListeners.push_back(std::move(a_Listener));
}
return cAttachment{nonOwning};
} }
@ -86,7 +91,16 @@ void cLogger::AttachListener(cListener * a_Listener)
void cLogger::DetachListener(cListener * a_Listener) void cLogger::DetachListener(cListener * a_Listener)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
m_LogListeners.erase(std::remove(m_LogListeners.begin(), m_LogListeners.end(), a_Listener)); m_LogListeners.erase(
std::remove_if(
m_LogListeners.begin(),
m_LogListeners.end(),
[=](std::unique_ptr<cListener> & a_OtherListener) -> bool
{
return a_OtherListener.get() == a_Listener;
}
)
);
} }
@ -120,7 +134,7 @@ void LOGINFO(const char * a_Format, ...)
void LOGWARN(const char * a_Format, ...) void LOGWARNING(const char * a_Format, ...)
{ {
va_list argList; va_list argList;
va_start(argList, a_Format); va_start(argList, a_Format);

View File

@ -23,13 +23,35 @@ public:
virtual ~cListener(){} virtual ~cListener(){}
}; };
class cAttachment
{
public:
cAttachment(cAttachment && a_other)
: m_listener(a_other.m_listener)
{
}
~cAttachment()
{
cLogger::GetInstance().DetachListener(m_listener);
}
private:
cListener * m_listener;
friend class cLogger;
cAttachment(cListener * a_listener) : m_listener(a_listener) {}
};
void Log (const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0); void Log (const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0);
/** Logs the simple text message at the specified log level. */ /** Logs the simple text message at the specified log level. */
void LogSimple(AString a_Message, eLogLevel a_LogLevel = llRegular); void LogSimple(AString a_Message, eLogLevel a_LogLevel = llRegular);
void AttachListener(cListener * a_Listener); cAttachment AttachListener(std::unique_ptr<cListener> a_Listener);
void DetachListener(cListener * a_Listener);
static cLogger & GetInstance(void); static cLogger & GetInstance(void);
// Must be called before calling GetInstance in a multithreaded context // Must be called before calling GetInstance in a multithreaded context
@ -37,37 +59,20 @@ public:
private: private:
cCriticalSection m_CriticalSection; cCriticalSection m_CriticalSection;
std::vector<cListener *> m_LogListeners; std::vector<std::unique_ptr<cListener>> m_LogListeners;
void DetachListener(cListener * a_Listener);
}; };
// These declarations are duplicated in globals.h
extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOG (const char * a_Format, ...) FORMATSTRING(1, 2); extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2); extern void LOGWARNING(const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGWARN (const char * a_Format, ...) FORMATSTRING(1, 2); extern void LOGERROR (const char * a_Format, ...) FORMATSTRING(1, 2);
extern void LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2);
// In debug builds, translate LOGD to LOG, otherwise leave it out altogether:
#ifdef _DEBUG
#define LOGD LOG
#else
#define LOGD(...)
#endif // _DEBUG
#define LOGWARNING LOGWARN

View File

@ -251,11 +251,11 @@ class cNullConsoleListener
cLogger::cListener * MakeConsoleListener(bool a_IsService) std::unique_ptr<cLogger::cListener> MakeConsoleListener(bool a_IsService)
{ {
if (a_IsService) if (a_IsService)
{ {
return new cNullConsoleListener; return cpp14::make_unique<cNullConsoleListener>();
} }
#ifdef _WIN32 #ifdef _WIN32
@ -267,25 +267,25 @@ cLogger::cListener * MakeConsoleListener(bool a_IsService)
HANDLE Console = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE Console = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(Console, &sbi); GetConsoleScreenBufferInfo(Console, &sbi);
WORD DefaultConsoleAttrib = sbi.wAttributes; WORD DefaultConsoleAttrib = sbi.wAttributes;
return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); return cpp14::make_unique<cWindowsConsoleListener>(Console, DefaultConsoleAttrib);
} }
else else
{ {
return new cVanillaCPPConsoleListener; return cpp14::make_unique<cVanillaCPPConsoleListener>();
} }
#elif defined (__linux) && !defined(ANDROID_NDK) #elif defined (__linux) && !defined(ANDROID_NDK)
// TODO: lookup terminal in terminfo // TODO: lookup terminal in terminfo
if (isatty(fileno(stdout))) if (isatty(fileno(stdout)))
{ {
return new cLinuxConsoleListener(); return cpp14::make_unique<cLinuxConsoleListener>();
} }
else else
{ {
return new cVanillaCPPConsoleListener(); return cpp14::make_unique<cVanillaCPPConsoleListener>();
} }
#else #else
return new cVanillaCPPConsoleListener(); return cpp14::make_unique<cVanillaCPPConsoleListener>();
#endif #endif
} }
@ -296,60 +296,82 @@ cLogger::cListener * MakeConsoleListener(bool a_IsService)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cFileListener: // cFileListener:
cFileListener::cFileListener(void) class cFileListener
: public cLogger::cListener
{ {
cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); public:
m_File.Open(
FILE_IO_PREFIX + Printf( cFileListener(void) {}
"logs/LOG_%d.txt",
std::chrono::duration_cast<std::chrono::duration<int, std::ratio<1>>>( bool Open()
std::chrono::system_clock::now().time_since_epoch() {
).count() // Assume creation succeeds, as the API does not provide a way to tell if the folder exists.
), cFile::CreateFolder(FILE_IO_PREFIX + AString("logs"));
cFile::fmAppend bool success = m_File.Open(
); FILE_IO_PREFIX + Printf(
"logs/LOG_%d.txt",
std::chrono::duration_cast<std::chrono::duration<int, std::ratio<1>>>(
std::chrono::system_clock::now().time_since_epoch()
).count()
),
cFile::fmAppend
);
return success;
}
virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override
{
const char * LogLevelPrefix = "Unkn ";
bool ShouldFlush = false;
switch (a_LogLevel)
{
case cLogger::llRegular:
{
LogLevelPrefix = " ";
break;
}
case cLogger::llInfo:
{
LogLevelPrefix = "Info ";
break;
}
case cLogger::llWarning:
{
LogLevelPrefix = "Warn ";
ShouldFlush = true;
break;
}
case cLogger::llError:
{
LogLevelPrefix = "Err ";
ShouldFlush = true;
break;
}
}
m_File.Printf("%s%s", LogLevelPrefix, a_Message.c_str());
if (ShouldFlush)
{
m_File.Flush();
}
}
private:
cFile m_File;
};
std::pair<bool, std::unique_ptr<cLogger::cListener>> MakeFileListener()
{
auto listener = cpp14::make_unique<cFileListener>();
if (!listener->Open())
{
return {false, nullptr};
}
return {true, std::move(listener)};
} }
void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel)
{
const char * LogLevelPrefix = "Unkn ";
bool ShouldFlush = false;
switch (a_LogLevel)
{
case cLogger::llRegular:
{
LogLevelPrefix = " ";
break;
}
case cLogger::llInfo:
{
LogLevelPrefix = "Info ";
break;
}
case cLogger::llWarning:
{
LogLevelPrefix = "Warn ";
ShouldFlush = true;
break;
}
case cLogger::llError:
{
LogLevelPrefix = "Err ";
ShouldFlush = true;
break;
}
}
m_File.Printf("%s%s", LogLevelPrefix, a_Message.c_str());
if (ShouldFlush)
{
m_File.Flush();
}
}

View File

@ -2,30 +2,8 @@
#include "Logger.h" #include "Logger.h"
#include "OSSupport/File.h" #include "OSSupport/File.h"
std::unique_ptr<cLogger::cListener> MakeConsoleListener(bool a_IsService);
std::pair<bool, std::unique_ptr<cLogger::cListener>> MakeFileListener();
class cFileListener
: public cLogger::cListener
{
public:
cFileListener();
cFileListener(AString a_Filename);
virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override;
private:
cFile m_File;
};
cLogger::cListener * MakeConsoleListener(bool a_IsService);

View File

@ -1,377 +0,0 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Socket.h"
#ifndef _WIN32
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h> // inet_ntoa()
#include <sys/ioctl.h> // ioctl()
#else
#define socklen_t int
#endif
cSocket::cSocket(xSocket a_Socket)
: m_Socket(a_Socket)
{
}
cSocket::operator cSocket::xSocket() const
{
return m_Socket;
}
cSocket::xSocket cSocket::GetSocket() const
{
return m_Socket;
}
bool cSocket::IsValidSocket(cSocket::xSocket a_Socket)
{
#ifdef _WIN32
return (a_Socket != INVALID_SOCKET);
#else // _WIN32
return (a_Socket >= 0);
#endif // else _WIN32
}
void cSocket::CloseSocket()
{
#ifdef _WIN32
closesocket(m_Socket);
#else // _WIN32
if (close(m_Socket) != 0)
{
LOGWARN("Error closing socket %d (%s): %s", m_Socket, m_IPString.c_str(), GetLastErrorString().c_str());
}
#endif // else _WIN32
// Invalidate the socket so that this object can be re-used for another connection
m_Socket = INVALID_SOCKET;
}
void cSocket::ShutdownReadWrite(void)
{
#ifdef _WIN32
int res = shutdown(m_Socket, SD_BOTH);
#else
int res = shutdown(m_Socket, SHUT_RDWR);
#endif
if (res != 0)
{
LOGWARN("%s: Error shutting down socket %d (%s): %d (%s)",
__FUNCTION__, m_Socket, m_IPString.c_str(), this->GetLastError(), GetLastErrorString().c_str()
);
}
}
int cSocket::GetLastError()
{
#ifdef _WIN32
return WSAGetLastError();
#else
return errno;
#endif
}
bool cSocket::SetReuseAddress(void)
{
#if defined(_WIN32) || defined(ANDROID_NDK)
char yes = 1;
#else
int yes = 1;
#endif
return (setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == 0);
}
int cSocket::WSAStartup(void)
{
#ifdef _WIN32
WSADATA wsaData;
memset(&wsaData, 0, sizeof(wsaData));
return ::WSAStartup(MAKEWORD(2, 2), &wsaData);
#else
return 0;
#endif
}
cSocket cSocket::CreateSocket(eFamily a_Family)
{
return socket((int)a_Family, SOCK_STREAM, 0);
}
bool cSocket::BindToAnyIPv4(unsigned short a_Port)
{
sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons((u_short)a_Port);
return (bind(m_Socket, (sockaddr *)&local, sizeof(local)) == 0);
}
bool cSocket::BindToAnyIPv6(unsigned short a_Port)
{
sockaddr_in6 local;
memset(&local, 0, sizeof(local));
local.sin6_family = AF_INET6;
local.sin6_port = htons((u_short)a_Port);
return (bind(m_Socket, (sockaddr *)&local, sizeof(local)) == 0);
}
bool cSocket::BindToLocalhostIPv4(unsigned short a_Port)
{
sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;;
local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
local.sin_port = htons((u_short)a_Port);
return (bind(m_Socket, (sockaddr*)&local, sizeof(local)) == 0);
}
bool cSocket::Listen(int a_Backlog)
{
return (listen(m_Socket, a_Backlog) == 0);
}
cSocket cSocket::AcceptIPv4(void)
{
sockaddr_in from;
socklen_t fromlen = sizeof(from);
cSocket SClient = accept(m_Socket, (sockaddr *)&from, &fromlen);
if (SClient.IsValid() && (from.sin_addr.s_addr != 0)) // Get IP in string form
{
SClient.m_IPString = inet_ntoa(from.sin_addr);
}
return SClient;
}
cSocket cSocket::AcceptIPv6(void)
{
sockaddr_in6 from;
socklen_t fromlen = sizeof(from);
cSocket SClient = accept(m_Socket, (sockaddr *)&from, &fromlen);
// Get IP in string form:
if (SClient.IsValid())
{
#if defined(_WIN32)
// Windows XP doesn't have inet_ntop, so we need to improvise. And MSVC has different headers than GCC
#ifdef _MSC_VER
// MSVC version
Printf(SClient.m_IPString, "%x:%x:%x:%x:%x:%x:%x:%x",
from.sin6_addr.u.Word[0],
from.sin6_addr.u.Word[1],
from.sin6_addr.u.Word[2],
from.sin6_addr.u.Word[3],
from.sin6_addr.u.Word[4],
from.sin6_addr.u.Word[5],
from.sin6_addr.u.Word[6],
from.sin6_addr.u.Word[7]
);
#else // _MSC_VER
// MinGW
Printf(SClient.m_IPString, "%x:%x:%x:%x:%x:%x:%x:%x",
from.sin6_addr.s6_addr16[0],
from.sin6_addr.s6_addr16[1],
from.sin6_addr.s6_addr16[2],
from.sin6_addr.s6_addr16[3],
from.sin6_addr.s6_addr16[4],
from.sin6_addr.s6_addr16[5],
from.sin6_addr.s6_addr16[6],
from.sin6_addr.s6_addr16[7]
);
#endif // else _MSC_VER
#else
char buffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &(from.sin6_addr), buffer, sizeof(buffer));
SClient.m_IPString.assign(buffer);
#endif // _WIN32
}
return SClient;
}
bool cSocket::ConnectToLocalhostIPv4(unsigned short a_Port)
{
sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
server.sin_port = htons(a_Port);
return (connect(m_Socket, (sockaddr *)&server, sizeof(server)) == 0);
}
bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Port)
{
// First try IP Address string to hostent conversion, because it's faster and local:
unsigned long addr = inet_addr(a_HostNameOrAddr.c_str());
if (addr == INADDR_NONE)
{
// It is not an IP Address string, but rather a regular hostname, resolve:
hostent * hp = gethostbyname(a_HostNameOrAddr.c_str());
if (hp == nullptr)
{
LOGWARNING("%s: Could not resolve hostname \"%s\"", __FUNCTION__, a_HostNameOrAddr.c_str());
CloseSocket();
return false;
}
memcpy(&addr, hp->h_addr, hp->h_length);
}
// If the socket is not created yet, create one:
if (!IsValid())
{
m_Socket = socket((int)IPv4, SOCK_STREAM, 0);
}
// Connect the socket:
sockaddr_in server;
server.sin_addr.s_addr = addr;
server.sin_family = AF_INET;
server.sin_port = htons((unsigned short)a_Port);
return (connect(m_Socket, (sockaddr *)&server, sizeof(server)) == 0);
}
int cSocket::Receive(char * a_Buffer, size_t a_Length, unsigned int a_Flags)
{
return recv(m_Socket, a_Buffer, (int)a_Length, a_Flags);
}
int cSocket::Send(const char * a_Buffer, size_t a_Length)
{
return send(m_Socket, a_Buffer, (int)a_Length, MSG_NOSIGNAL);
}
unsigned short cSocket::GetPort(void) const
{
ASSERT(IsValid());
sockaddr_in Addr;
socklen_t AddrSize = sizeof(Addr);
if (getsockname(m_Socket, (sockaddr *)&Addr, &AddrSize) != 0)
{
return 0;
}
return ntohs(Addr.sin_port);
}
void cSocket::SetNonBlocking(void)
{
#ifdef _WIN32
u_long NonBlocking = 1;
int res = ioctlsocket(m_Socket, FIONBIO, &NonBlocking);
#else
int NonBlocking = 1;
int res = ioctl(m_Socket, FIONBIO, (char *)&NonBlocking);
#endif
if (res != 0)
{
LOGERROR("Cannot set socket to non-blocking. This would make the server deadlock later on, aborting.\nErr: %d, %d, %s",
res, GetLastError(), GetLastErrorString().c_str()
);
abort();
}
}

View File

@ -1,125 +0,0 @@
#pragma once
// Windows and MacOSX don't have the MSG_NOSIGNAL flag
#if ( \
defined(_WIN32) || \
(defined(__APPLE__) && defined(__MACH__)) \
)
#define MSG_NOSIGNAL (0)
#endif
#include "Errors.h"
class cSocket
{
public:
enum eFamily
{
IPv4 = AF_INET,
IPv6 = AF_INET6,
#ifdef _WIN32
ErrWouldBlock = WSAEWOULDBLOCK,
#else
ErrWouldBlock = EWOULDBLOCK,
#endif
} ;
#ifdef _WIN32
typedef SOCKET xSocket;
#else
typedef int xSocket;
static const int INVALID_SOCKET = -1;
#endif
cSocket(void) : m_Socket(INVALID_SOCKET) {}
cSocket(xSocket a_Socket);
bool IsValid(void) const { return IsValidSocket(m_Socket); }
void CloseSocket(void);
/** Notifies the socket that we don't expect any more reads nor writes on it.
Most TCPIP implementations use this to send the FIN flag in a packet */
void ShutdownReadWrite(void);
operator xSocket(void) const;
xSocket GetSocket(void) const;
bool operator == (const cSocket & a_Other) {return m_Socket == a_Other.m_Socket; }
void SetSocket(xSocket a_Socket);
/// Sets the address-reuse socket flag; returns true on success
bool SetReuseAddress(void);
/// Initializes the network stack. Returns 0 on success, or another number as an error code.
static int WSAStartup(void);
static int GetLastError();
static AString GetLastErrorString(void)
{
return GetOSErrorString(GetLastError());
}
/// Creates a new socket of the specified address family
static cSocket CreateSocket(eFamily a_Family);
inline static bool IsSocketError(int a_ReturnedValue)
{
#ifdef _WIN32
return ((a_ReturnedValue == SOCKET_ERROR) || (a_ReturnedValue == 0));
#else
return (a_ReturnedValue <= 0);
#endif
}
static bool IsValidSocket(xSocket a_Socket);
static const unsigned short ANY_PORT = 0; // When given to Bind() functions, they will find a free port
static const int DEFAULT_BACKLOG = 10;
/// Binds to the specified port on "any" interface (0.0.0.0). Returns true if successful.
bool BindToAnyIPv4(unsigned short a_Port);
/// Binds to the specified port on "any" interface (::/128). Returns true if successful.
bool BindToAnyIPv6(unsigned short a_Port);
/// Binds to the specified port on localhost interface (127.0.0.1) through IPv4. Returns true if successful.
bool BindToLocalhostIPv4(unsigned short a_Port);
/// Sets the socket to listen for incoming connections. Returns true if successful.
bool Listen(int a_Backlog = DEFAULT_BACKLOG);
/// Accepts an IPv4 incoming connection. Blocks if none available.
cSocket AcceptIPv4(void);
/// Accepts an IPv6 incoming connection. Blocks if none available.
cSocket AcceptIPv6(void);
/// Connects to a localhost socket on the specified port using IPv4; returns true if successful.
bool ConnectToLocalhostIPv4(unsigned short a_Port);
/// Connects to the specified host or string IP address and port, using IPv4. Returns true if successful.
bool ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Port);
int Receive(char * a_Buffer, size_t a_Length, unsigned int a_Flags);
int Send (const char * a_Buffer, size_t a_Length);
unsigned short GetPort(void) const; // Returns 0 on failure
const AString & GetIPString(void) const { return m_IPString; }
/** Sets the socket into non-blocking mode */
void SetNonBlocking(void);
private:
xSocket m_Socket;
AString m_IPString;
};

View File

@ -68,14 +68,8 @@ public:
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) = 0; virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) = 0;
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; 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 SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0;
virtual void SendChat (const AString & a_Message) = 0; virtual void SendChat (const AString & a_Message, eChatType a_Type) = 0;
virtual void SendChat (const cCompositeChat & a_Message) = 0; virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) = 0;
virtual void SendChatAboveActionBar (const AString & a_Message) = 0;
virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) = 0;
virtual void SendChatSystem (const AString & a_Message) = 0;
virtual void SendChatSystem (const cCompositeChat & a_Message) = 0;
virtual void SendChatType (const AString & a_Message, eChatType type) = 0;
virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) = 0;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0; virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0;
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0; virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;

View File

@ -245,65 +245,11 @@ void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
void cProtocol172::SendChat(const AString & a_Message) void cProtocol172::SendChat(const AString & a_Message, eChatType a_Type)
{
this->SendChatType(a_Message, ctChatBox);
}
void cProtocol172::SendChat(const cCompositeChat & a_Message)
{
this->SendChatType(a_Message, ctChatBox);
}
void cProtocol172::SendChatSystem(const AString & a_Message)
{
this->SendChatType(a_Message, ctSystem);
}
void cProtocol172::SendChatSystem(const cCompositeChat & a_Message)
{
this->SendChatType(a_Message, ctSystem);
}
void cProtocol172::SendChatAboveActionBar(const AString & a_Message)
{
this->SendChatType(a_Message, ctAboveActionBar);
}
void cProtocol172::SendChatAboveActionBar(const cCompositeChat & a_Message)
{
this->SendChatType(a_Message, ctAboveActionBar);
}
void cProtocol172::SendChatType(const AString & a_Message, eChatType type)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
if (type != ctChatBox) // 1.7.2 doesn't support anything else if (a_Type != ctChatBox) // 1.7.2 doesn't support anything else
{ {
return; return;
} }
@ -316,21 +262,18 @@ void cProtocol172::SendChatType(const AString & a_Message, eChatType type)
void cProtocol172::SendChatType(const cCompositeChat & a_Message, eChatType type) void cProtocol172::SendChat(const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
if (type != ctChatBox) // 1.7.2 doesn't support anything else if (a_Type != ctChatBox) // 1.7.2 doesn't support anything else
{ {
return; return;
} }
cWorld * World = m_Client->GetPlayer()->GetWorld();
bool ShouldUseChatPrefixes = (World == nullptr) ? false : World->ShouldUseChatPrefixes();
// Send the message to the client: // Send the message to the client:
cPacketizer Pkt(*this, 0x02); cPacketizer Pkt(*this, 0x02);
Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes)); Pkt.WriteString(a_Message.CreateJsonString(a_ShouldUseChatPrefixes));
} }

View File

@ -66,14 +66,8 @@ public:
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; virtual void SendBlockBreakAnim (UInt32 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 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 SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override; virtual void SendChat (const AString & a_Message, eChatType a_Type) override;
virtual void SendChat (const cCompositeChat & a_Message) override; virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) override;
virtual void SendChatAboveActionBar (const AString & a_Message) override;
virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) override;
virtual void SendChatSystem (const AString & a_Message) override;
virtual void SendChatSystem (const cCompositeChat & a_Message) override;
virtual void SendChatType (const AString & a_Message, eChatType type) override;
virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override;

View File

@ -246,84 +246,28 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
void cProtocol180::SendChat(const AString & a_Message) void cProtocol180::SendChat(const AString & a_Message, eChatType a_Type)
{
this->SendChatType(a_Message, ctChatBox);
}
void cProtocol180::SendChat(const cCompositeChat & a_Message)
{
this->SendChatType(a_Message, ctChatBox);
}
void cProtocol180::SendChatSystem(const AString & a_Message)
{
this->SendChatType(a_Message, ctSystem);
}
void cProtocol180::SendChatSystem(const cCompositeChat & a_Message)
{
this->SendChatType(a_Message, ctSystem);
}
void cProtocol180::SendChatAboveActionBar(const AString & a_Message)
{
this->SendChatType(a_Message, ctAboveActionBar);
}
void cProtocol180::SendChatAboveActionBar(const cCompositeChat & a_Message)
{
this->SendChatType(a_Message, ctAboveActionBar);
}
void cProtocol180::SendChatType(const AString & a_Message, eChatType type)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x02); // Chat Message packet cPacketizer Pkt(*this, 0x02); // Chat Message packet
Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str())); Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str()));
Pkt.WriteBEInt8(type); Pkt.WriteBEInt8(a_Type);
} }
void cProtocol180::SendChatType(const cCompositeChat & a_Message, eChatType type) void cProtocol180::SendChat(const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
cWorld * World = m_Client->GetPlayer()->GetWorld();
bool ShouldUseChatPrefixes = (World == nullptr) ? false : World->ShouldUseChatPrefixes();
// Send the message to the client: // Send the message to the client:
cPacketizer Pkt(*this, 0x02); cPacketizer Pkt(*this, 0x02);
Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes)); Pkt.WriteString(a_Message.CreateJsonString(a_ShouldUseChatPrefixes));
Pkt.WriteBEInt8(type); Pkt.WriteBEInt8(a_Type);
} }

View File

@ -65,14 +65,8 @@ public:
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; virtual void SendBlockBreakAnim (UInt32 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 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 SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override; virtual void SendChat (const AString & a_Message, eChatType a_Type) override;
virtual void SendChat (const cCompositeChat & a_Message) override; virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) override;
virtual void SendChatAboveActionBar (const AString & a_Message) override;
virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) override;
virtual void SendChatSystem (const AString & a_Message) override;
virtual void SendChatSystem (const cCompositeChat & a_Message) override;
virtual void SendChatType (const AString & a_Message, eChatType type) override;
virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override;

View File

@ -138,80 +138,20 @@ void cProtocolRecognizer::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSe
void cProtocolRecognizer::SendChat(const AString & a_Message) void cProtocolRecognizer::SendChat(const AString & a_Message, eChatType a_Type)
{ {
ASSERT(m_Protocol != nullptr); ASSERT(m_Protocol != nullptr);
m_Protocol->SendChat(a_Message); m_Protocol->SendChat(a_Message, a_Type);
} }
void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message) void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes)
{ {
ASSERT(m_Protocol != nullptr); ASSERT(m_Protocol != nullptr);
m_Protocol->SendChat(a_Message); m_Protocol->SendChat(a_Message, a_Type, a_ShouldUseChatPrefixes);
}
void cProtocolRecognizer::SendChatAboveActionBar(const AString & a_Message)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChatAboveActionBar(a_Message);
}
void cProtocolRecognizer::SendChatAboveActionBar(const cCompositeChat & a_Message)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChatAboveActionBar(a_Message);
}
void cProtocolRecognizer::SendChatSystem(const AString & a_Message)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChatSystem(a_Message);
}
void cProtocolRecognizer::SendChatSystem(const cCompositeChat & a_Message)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChatSystem(a_Message);
}
void cProtocolRecognizer::SendChatType(const AString & a_Message, eChatType type)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChatType(a_Message, type);
}
void cProtocolRecognizer::SendChatType(const cCompositeChat & a_Message, eChatType type)
{
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChatType(a_Message, type);
} }

View File

@ -53,14 +53,8 @@ public:
virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; virtual void SendBlockBreakAnim (UInt32 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 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 SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override; virtual void SendChat (const AString & a_Message, eChatType a_Type) override;
virtual void SendChat (const cCompositeChat & a_Message) override; virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) override;
virtual void SendChatAboveActionBar (const AString & a_Message) override;
virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) override;
virtual void SendChatSystem (const AString & a_Message) override;
virtual void SendChatSystem (const cCompositeChat & a_Message) override;
virtual void SendChatType (const AString & a_Message, eChatType type) override;
virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override;

View File

@ -22,6 +22,7 @@
#include "SettingsRepositoryInterface.h" #include "SettingsRepositoryInterface.h"
#include "OverridesSettingsRepository.h" #include "OverridesSettingsRepository.h"
#include "SelfTests.h" #include "SelfTests.h"
#include "Logger.h"
#include <iostream> #include <iostream>
@ -107,10 +108,15 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo)
EnableMenuItem(ConsoleMenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling EnableMenuItem(ConsoleMenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling
#endif #endif
cLogger::cListener * consoleLogListener = MakeConsoleListener(m_RunAsService); auto consoleLogListener = MakeConsoleListener(m_RunAsService);
cLogger::cListener * fileLogListener = new cFileListener(); auto consoleAttachment = cLogger::GetInstance().AttachListener(std::move(consoleLogListener));
cLogger::GetInstance().AttachListener(consoleLogListener); auto fileLogListenerRet = MakeFileListener();
cLogger::GetInstance().AttachListener(fileLogListener); if (!fileLogListenerRet.first)
{
LOGERROR("Failed to open log file, aborting");
return;
}
auto fileAttachment = cLogger::GetInstance().AttachListener(std::move(fileLogListenerRet.second));
LOG("--- Started Log ---"); LOG("--- Started Log ---");
@ -317,11 +323,6 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo)
LOG("Shutdown successful - restarting..."); LOG("Shutdown successful - restarting...");
} }
LOG("--- Stopped Log ---"); LOG("--- Stopped Log ---");
cLogger::GetInstance().DetachListener(consoleLogListener);
delete consoleLogListener;
cLogger::GetInstance().DetachListener(fileLogListener);
delete fileLogListener;
} }

View File

@ -255,8 +255,6 @@ int cWorld::GetDefaultWeatherInterval(eWeather a_Weather)
return 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes return 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes
} }
} }
LOGWARNING("%s: Missing default weather interval for weather %d.", __FUNCTION__, a_Weather);
return -1;
} }
@ -646,10 +644,6 @@ eWeather cWorld::ChooseNewWeather()
return ((m_TickRand.randInt() % 256) < 32) ? eWeather_ThunderStorm : eWeather_Sunny; return ((m_TickRand.randInt() % 256) < 32) ? eWeather_ThunderStorm : eWeather_Sunny;
} }
} }
LOGWARNING("Unknown current weather: %d. Setting sunny.", m_Weather);
ASSERT(!"Unknown weather");
return eWeather_Sunny;
} }

View File

@ -14,6 +14,7 @@
#include "OSSupport/NetworkSingleton.h" #include "OSSupport/NetworkSingleton.h"
#include "BuildInfo.h" #include "BuildInfo.h"
#include "Logger.h"
#include "MemorySettingsRepository.h" #include "MemorySettingsRepository.h"
@ -471,6 +472,10 @@ int main(int argc, char **argv)
#endif // SIGABRT_COMPAT #endif // SIGABRT_COMPAT
#endif #endif
#ifdef __unix__
std::signal(SIGPIPE, SIG_IGN);
#endif
#ifdef _WIN32 #ifdef _WIN32
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE))