Merge branch 'master' into master
This commit is contained in:
commit
a24cc01843
2
Server/.gitignore
vendored
2
Server/.gitignore
vendored
@ -7,6 +7,8 @@ Cuberite
|
||||
Cuberite_debug
|
||||
CommLogs/
|
||||
GalExports/
|
||||
GalExportWeb/
|
||||
GalleryWeb/
|
||||
logs
|
||||
players
|
||||
world*
|
||||
|
@ -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>.
|
||||
|
||||
<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>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>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>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, "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 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>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>
|
||||
<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>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>
|
||||
<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>
|
||||
|
@ -1432,9 +1432,9 @@ end
|
||||
--- Dumps the entire API table into a file in the ZBS format
|
||||
local function DumpAPIZBS(a_API)
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -22,26 +22,26 @@ static const Byte g_Zeroes[4096] = {0};
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
cLogger::cListener * consoleLogListener = MakeConsoleListener(false);
|
||||
cLogger::cListener * fileLogListener = new cFileListener();
|
||||
cLogger::GetInstance().AttachListener(consoleLogListener);
|
||||
cLogger::GetInstance().AttachListener(fileLogListener);
|
||||
auto consoleLogListener = MakeConsoleListener(false);
|
||||
auto consoleAttachment = cLogger::GetInstance().AttachListener(std::move(consoleLogListener));
|
||||
auto fileLogListenerRet = MakeFileListener();
|
||||
if (!fileLogListenerRet.first)
|
||||
{
|
||||
LOGERROR("Failed to open log file, aborting");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
auto fileAttachment = cLogger::GetInstance().AttachListener(std::move(fileLogListenerRet.second));
|
||||
|
||||
cLogger::InitiateMultithreading();
|
||||
|
||||
cMCADefrag Defrag;
|
||||
if (!Defrag.Init(argc, argv))
|
||||
{
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
Defrag.Run();
|
||||
|
||||
cLogger::GetInstance().DetachListener(consoleLogListener);
|
||||
delete consoleLogListener;
|
||||
cLogger::GetInstance().DetachListener(fileLogListener);
|
||||
delete fileLogListener;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,17 @@
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
// Initialize logging subsystem:
|
||||
cLogger::InitiateMultithreading();
|
||||
auto consoleLogListener = MakeConsoleListener(false);
|
||||
auto fileLogListener = new cFileListener();
|
||||
cLogger::GetInstance().AttachListener(consoleLogListener);
|
||||
cLogger::GetInstance().AttachListener(fileLogListener);
|
||||
auto consoleAttachment = cLogger::GetInstance().AttachListener(std::move(consoleLogListener));
|
||||
auto fileLogListenerRet = MakeFileListener();
|
||||
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 ConnectPort = (argc > 2) ? atoi(argv[2]) : 25565;
|
||||
|
12
circle.yml
Normal file
12
circle.yml
Normal 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
|
@ -22,23 +22,23 @@ endif()
|
||||
# Lua needs to be linked dynamically on Windows and statically on *nix, so that LuaRocks work
|
||||
if (WIN32)
|
||||
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:
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
|
||||
# Output the executable into the $/Server folder, so that Cuberite can find it:
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server)
|
||||
SET_TARGET_PROPERTIES(lua PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
|
@ -30,28 +30,28 @@ if (WIN32)
|
||||
endif()
|
||||
|
||||
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
|
||||
OUTPUT_NAME "lua5.1"
|
||||
PREFIX ""
|
||||
)
|
||||
target_link_libraries(luaproxy lua)
|
||||
|
||||
# Output the executable into the $/MCServer folder, so that MCServer can find it:
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
|
||||
# Output the executable into the $/Server folder, so that Cuberite can find it:
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/Server)
|
||||
SET_TARGET_PROPERTIES(luaproxy PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/Server
|
||||
)
|
||||
|
||||
else()
|
||||
|
@ -20,7 +20,8 @@ SET (SRCS
|
||||
MobHeadEntity.cpp
|
||||
MobSpawnerEntity.cpp
|
||||
NoteEntity.cpp
|
||||
SignEntity.cpp)
|
||||
SignEntity.cpp
|
||||
)
|
||||
|
||||
SET (HDRS
|
||||
BeaconEntity.h
|
||||
@ -39,7 +40,9 @@ SET (HDRS
|
||||
MobHeadEntity.h
|
||||
MobSpawnerEntity.h
|
||||
NoteEntity.h
|
||||
SignEntity.h)
|
||||
RedstonePoweredEntity.h
|
||||
SignEntity.h
|
||||
)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set_source_files_properties(BeaconEntity.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=conversion -Wno-error=switch-enum")
|
||||
|
@ -1,13 +1,30 @@
|
||||
|
||||
// RedstonePoweredEntity.h
|
||||
|
||||
// Declares the cRedstonePoweredEntity class representing a mix-in for block entities that respond to redstone
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#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
|
||||
{
|
||||
public:
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
|
||||
{
|
||||
cFastRandom Random;
|
||||
if (Random.NextInt(30) == 0)
|
||||
if (Random.NextInt(10) == 0)
|
||||
{
|
||||
a_Pickups.Add(E_ITEM_FLINT, 1, 0);
|
||||
}
|
||||
|
@ -49,13 +49,12 @@ protected:
|
||||
Light = Blocklight;
|
||||
}
|
||||
|
||||
// Return true if there is enough light
|
||||
// Set m_ShouldDie if the base light amounts are not enough to sustain a plant
|
||||
// Based on light levels, decide between growth, stay and death:
|
||||
if (Light > 8)
|
||||
{
|
||||
return paGrowth;
|
||||
}
|
||||
else if (Blocklight < 9 && SkyLight < 9)
|
||||
else if ((Blocklight < 9) && (SkyLight < 9))
|
||||
{
|
||||
return paDeath;
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ SET (SRCS
|
||||
BlockDoor.cpp
|
||||
BlockHandler.cpp
|
||||
BlockPiston.cpp
|
||||
ChunkInterface.cpp)
|
||||
ChunkInterface.cpp
|
||||
)
|
||||
|
||||
SET (HDRS
|
||||
BlockAnvil.h
|
||||
@ -54,12 +55,15 @@ SET (HDRS
|
||||
BlockLilypad.h
|
||||
BlockMelon.h
|
||||
BlockMobHead.h
|
||||
BlockMobSpawner.h
|
||||
BlockMushroom.h
|
||||
BlockMycelium.h
|
||||
BlockNetherrack.h
|
||||
BlockNetherWart.h
|
||||
BlockOre.h
|
||||
BlockPiston.h
|
||||
BlockPlanks.h
|
||||
BlockPlant.h
|
||||
BlockPluginInterface.h
|
||||
BlockPortal.h
|
||||
BlockPressurePlate.h
|
||||
@ -72,6 +76,7 @@ SET (HDRS
|
||||
BlockRedstoneTorch.h
|
||||
BlockSand.h
|
||||
BlockSapling.h
|
||||
BlockSeaLantern.h
|
||||
BlockSideways.h
|
||||
BlockSignPost.h
|
||||
BlockSlab.h
|
||||
@ -80,8 +85,8 @@ SET (HDRS
|
||||
BlockStems.h
|
||||
BlockStone.h
|
||||
BlockSugarcane.h
|
||||
BlockTNT.h
|
||||
BlockTallGrass.h
|
||||
BlockTNT.h
|
||||
BlockTorch.h
|
||||
BlockTrapdoor.h
|
||||
BlockTripwire.h
|
||||
@ -92,8 +97,10 @@ SET (HDRS
|
||||
BroadcastInterface.h
|
||||
ChunkInterface.h
|
||||
ClearMetaOnDrop.h
|
||||
GetHandlerCompileTimeTemplate.h
|
||||
MetaRotator.h
|
||||
WorldInterface.h)
|
||||
WorldInterface.h
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_library(Blocks ${SRCS} ${HDRS})
|
||||
|
@ -98,6 +98,7 @@ SET (HDRS
|
||||
ChunkSender.h
|
||||
ChunkStay.h
|
||||
ClientHandle.h
|
||||
Color.h
|
||||
CommandOutput.h
|
||||
CompositeChat.h
|
||||
CraftingRecipes.h
|
||||
@ -316,7 +317,7 @@ if (MSVC)
|
||||
OUTPUT ${BINDING_OUTPUTS}
|
||||
|
||||
# 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:
|
||||
COMMAND tolua -L BindingsProcessor.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
|
||||
@ -330,7 +331,7 @@ endif()
|
||||
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_TARGET_PROPERTIES(${EXECUTABLE} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/Server
|
||||
|
@ -412,6 +412,12 @@ end
|
||||
|
||||
-- Process the files in the list:
|
||||
for _, fnam in ipairs(ToProcess) do
|
||||
|
||||
-- Remove the optional "./" prefix:
|
||||
if (fnam:sub(1, 2) == "./") then
|
||||
fnam = fnam:sub(3)
|
||||
end
|
||||
|
||||
ProcessItem(fnam)
|
||||
end
|
||||
|
||||
|
118
src/Chunk.cpp
118
src/Chunk.cpp
@ -199,9 +199,9 @@ void cChunk::MarkRegenerating(void)
|
||||
SetPresence(cpQueued);
|
||||
|
||||
// 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[]
|
||||
}
|
||||
|
||||
@ -474,25 +474,25 @@ void cChunk::Stay(bool a_Stay)
|
||||
void cChunk::CollectMobCensus(cMobCensus & toFill)
|
||||
{
|
||||
toFill.CollectSpawnableChunk(*this);
|
||||
std::list<const Vector3d *> playerPositions;
|
||||
cPlayer * currentPlayer;
|
||||
for (auto itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr)
|
||||
std::vector<Vector3d> PlayerPositions;
|
||||
PlayerPositions.reserve(m_LoadedByClient.size());
|
||||
for (auto ClientHandle : m_LoadedByClient)
|
||||
{
|
||||
currentPlayer = (*itr)->GetPlayer();
|
||||
playerPositions.push_back(&(currentPlayer->GetPosition()));
|
||||
const cPlayer * currentPlayer = ClientHandle->GetPlayer();
|
||||
PlayerPositions.push_back(currentPlayer->GetPosition());
|
||||
}
|
||||
|
||||
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());
|
||||
if ((*itr)->IsMob())
|
||||
if (entity->IsMob())
|
||||
{
|
||||
auto & Monster = reinterpret_cast<cMonster &>(**itr);
|
||||
auto & Monster = reinterpret_cast<cMonster &>(*entity);
|
||||
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[]
|
||||
@ -779,17 +779,17 @@ void cChunk::BroadcastPendingBlockChanges(void)
|
||||
if (m_PendingSendBlocks.size() >= 10240)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
// 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();
|
||||
@ -1758,9 +1758,9 @@ void cChunk::SetAreaBiome(int a_MinRelX, int a_MaxRelX, int a_MinRelZ, int a_Max
|
||||
MarkDirty();
|
||||
|
||||
// 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[]
|
||||
}
|
||||
|
||||
@ -1856,14 +1856,12 @@ void cChunk::RemoveBlockEntity(cBlockEntity * a_BlockEntity)
|
||||
|
||||
bool cChunk::AddClient(cClientHandle * a_Client)
|
||||
{
|
||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if (a_Client == *itr)
|
||||
if (std::find(m_LoadedByClient.begin(), m_LoadedByClient.end(), a_Client) != m_LoadedByClient.end())
|
||||
{
|
||||
// Already there, nothing needed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_LoadedByClient.push_back(a_Client);
|
||||
|
||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
||||
@ -1887,18 +1885,15 @@ bool cChunk::AddClient(cClientHandle * a_Client)
|
||||
|
||||
void cChunk::RemoveClient(cClientHandle * a_Client)
|
||||
{
|
||||
for (cClientHandleList::iterator itrC = m_LoadedByClient.begin(); itrC != m_LoadedByClient.end(); ++itrC)
|
||||
{
|
||||
if (*itrC != a_Client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m_LoadedByClient.erase(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())
|
||||
{
|
||||
for (cEntityList::iterator itrE = m_Entities.begin(); itrE != m_Entities.end(); ++itrE)
|
||||
for (auto Entity : m_Entities)
|
||||
{
|
||||
/*
|
||||
// DEBUG:
|
||||
@ -1907,11 +1902,11 @@ void cChunk::RemoveClient(cClientHandle * a_Client)
|
||||
(*itr)->GetUniqueID(), a_Client->GetUsername().c_str()
|
||||
);
|
||||
*/
|
||||
a_Client->SendDestroyEntity(*(*itrE));
|
||||
a_Client->SendDestroyEntity(*Entity);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} // for itr - m_LoadedByClient[]
|
||||
}
|
||||
|
||||
|
||||
@ -1920,14 +1915,7 @@ void cChunk::RemoveClient(cClientHandle * a_Client)
|
||||
|
||||
bool cChunk::HasClient(cClientHandle * a_Client)
|
||||
{
|
||||
for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr)
|
||||
{
|
||||
if ((*itr) == a_Client)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return std::find(m_LoadedByClient.begin(), m_LoadedByClient.end(), a_Client) != m_LoadedByClient.end();
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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[]
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -2843,7 +2831,7 @@ void cChunk::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cons
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -2939,7 +2927,7 @@ void cChunk::BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHand
|
||||
|
||||
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)
|
||||
{
|
||||
@ -2955,7 +2943,7 @@ void cChunk::BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle *
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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);
|
||||
} // for itr - LoadedByClient[]
|
||||
|
@ -439,7 +439,10 @@ public:
|
||||
void SetAlwaysTicked(bool a_AlwaysTicked);
|
||||
|
||||
// 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:
|
||||
|
||||
@ -479,7 +482,7 @@ private:
|
||||
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
|
||||
cClientHandleList m_LoadedByClient;
|
||||
std::vector<cClientHandle *> m_LoadedByClient;
|
||||
cEntityList m_Entities;
|
||||
cBlockEntityList m_BlockEntities;
|
||||
|
||||
|
@ -2086,8 +2086,9 @@ void cClientHandle::SendChat(const AString & a_Message, eMessageType a_ChatPrefi
|
||||
}
|
||||
}
|
||||
|
||||
AString Message = FormatMessageType(World->ShouldUseChatPrefixes(), a_ChatPrefix, a_AdditionalData);
|
||||
m_Protocol->SendChat(Message.append(a_Message));
|
||||
bool ShouldUsePrefixes = World->ShouldUseChatPrefixes();
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
m_Protocol->SendChatSystem(Message.append(a_Message));
|
||||
auto ShouldUsePrefixes = World->ShouldUseChatPrefixes();
|
||||
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)
|
||||
{
|
||||
m_Protocol->SendChatSystem(a_Message);
|
||||
m_Protocol->SendChat(a_Message, ctSystem, GetPlayer()->GetWorld()->ShouldUseChatPrefixes());
|
||||
}
|
||||
|
||||
|
||||
|
18
src/Color.h
18
src/Color.h
@ -25,31 +25,31 @@ public:
|
||||
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); }
|
||||
|
||||
/// Returns whether the color is a valid color
|
||||
/** Returns whether the color is a valid color */
|
||||
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);
|
||||
|
||||
/// Alters the red value of the color
|
||||
/** Alters the red value of the color */
|
||||
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);
|
||||
|
||||
/// Alters the blue value of the color
|
||||
/** Alters the blue value of the color */
|
||||
void SetBlue(unsigned char a_Red);
|
||||
|
||||
/// Returns the red value of the color
|
||||
/** Returns the red value of the color */
|
||||
unsigned char GetRed() const;
|
||||
|
||||
/// Returns the green value of the color
|
||||
/** Returns the green value of the color */
|
||||
unsigned char GetGreen() const;
|
||||
|
||||
/// Returns the blue value of the color
|
||||
/** Returns the blue value of the color */
|
||||
unsigned char GetBlue() const;
|
||||
|
||||
/// Resets the color
|
||||
/** Resets the color */
|
||||
void Clear() { m_Color = static_cast<unsigned int>(COLOR_NONE); }
|
||||
// tolua_end
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "Defines.h"
|
||||
#include "json/json.h"
|
||||
#include "Logger.h"
|
||||
|
||||
|
||||
|
||||
|
@ -271,7 +271,25 @@ template class SizeChecker<UInt8, 1>;
|
||||
#include "OSSupport/StackTrace.h"
|
||||
|
||||
#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
|
||||
// Logging functions
|
||||
void inline LOGERROR(const char * a_Format, ...) FORMATSTRING(1, 2);
|
||||
|
@ -5,7 +5,8 @@ project (MCServer)
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/../")
|
||||
|
||||
SET (SRCS
|
||||
ItemHandler.cpp)
|
||||
ItemHandler.cpp
|
||||
)
|
||||
|
||||
SET (HDRS
|
||||
ItemArmor.h
|
||||
@ -26,6 +27,7 @@ SET (HDRS
|
||||
ItemFishingRod.h
|
||||
ItemFlowerPot.h
|
||||
ItemFood.h
|
||||
ItemGoldenApple.h
|
||||
ItemHandler.h
|
||||
ItemHoe.h
|
||||
ItemItemFrame.h
|
||||
@ -36,6 +38,7 @@ SET (HDRS
|
||||
ItemMilk.h
|
||||
ItemMinecart.h
|
||||
ItemMobHead.h
|
||||
ItemMushroomSoup.h
|
||||
ItemNetherWart.h
|
||||
ItemPainting.h
|
||||
ItemPickaxe.h
|
||||
@ -47,8 +50,8 @@ SET (HDRS
|
||||
ItemSeeds.h
|
||||
ItemShears.h
|
||||
ItemShovel.h
|
||||
ItemSlab.h
|
||||
ItemSign.h
|
||||
ItemSlab.h
|
||||
ItemSpawnEgg.h
|
||||
ItemString.h
|
||||
ItemSugarcane.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
#include "Logger.h"
|
||||
|
||||
#include "OSSupport/IsThread.h"
|
||||
#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)
|
||||
{
|
||||
auto nonOwning = a_Listener.get();
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
m_LogListeners.push_back(a_Listener);
|
||||
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)
|
||||
{
|
||||
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_start(argList, a_Format);
|
||||
|
53
src/Logger.h
53
src/Logger.h
@ -23,13 +23,35 @@ public:
|
||||
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);
|
||||
|
||||
/** Logs the simple text message at the specified log level. */
|
||||
void LogSimple(AString a_Message, eLogLevel a_LogLevel = llRegular);
|
||||
|
||||
void AttachListener(cListener * a_Listener);
|
||||
void DetachListener(cListener * a_Listener);
|
||||
cAttachment AttachListener(std::unique_ptr<cListener> a_Listener);
|
||||
|
||||
static cLogger & GetInstance(void);
|
||||
// Must be called before calling GetInstance in a multithreaded context
|
||||
@ -37,37 +59,20 @@ public:
|
||||
private:
|
||||
|
||||
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 LOGINFO (const char * a_Format, ...) FORMATSTRING(1, 2);
|
||||
extern void LOGWARN (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 LOGWARNING LOGWARN
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -251,11 +251,11 @@ class cNullConsoleListener
|
||||
|
||||
|
||||
|
||||
cLogger::cListener * MakeConsoleListener(bool a_IsService)
|
||||
std::unique_ptr<cLogger::cListener> MakeConsoleListener(bool a_IsService)
|
||||
{
|
||||
if (a_IsService)
|
||||
{
|
||||
return new cNullConsoleListener;
|
||||
return cpp14::make_unique<cNullConsoleListener>();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -267,25 +267,25 @@ cLogger::cListener * MakeConsoleListener(bool a_IsService)
|
||||
HANDLE Console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
GetConsoleScreenBufferInfo(Console, &sbi);
|
||||
WORD DefaultConsoleAttrib = sbi.wAttributes;
|
||||
return new cWindowsConsoleListener(Console, DefaultConsoleAttrib);
|
||||
return cpp14::make_unique<cWindowsConsoleListener>(Console, DefaultConsoleAttrib);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new cVanillaCPPConsoleListener;
|
||||
return cpp14::make_unique<cVanillaCPPConsoleListener>();
|
||||
}
|
||||
|
||||
#elif defined (__linux) && !defined(ANDROID_NDK)
|
||||
// TODO: lookup terminal in terminfo
|
||||
if (isatty(fileno(stdout)))
|
||||
{
|
||||
return new cLinuxConsoleListener();
|
||||
return cpp14::make_unique<cLinuxConsoleListener>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new cVanillaCPPConsoleListener();
|
||||
return cpp14::make_unique<cVanillaCPPConsoleListener>();
|
||||
}
|
||||
#else
|
||||
return new cVanillaCPPConsoleListener();
|
||||
return cpp14::make_unique<cVanillaCPPConsoleListener>();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -296,10 +296,18 @@ cLogger::cListener * MakeConsoleListener(bool a_IsService)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cFileListener:
|
||||
|
||||
cFileListener::cFileListener(void)
|
||||
class cFileListener
|
||||
: public cLogger::cListener
|
||||
{
|
||||
public:
|
||||
|
||||
cFileListener(void) {}
|
||||
|
||||
bool Open()
|
||||
{
|
||||
// Assume creation succeeds, as the API does not provide a way to tell if the folder exists.
|
||||
cFile::CreateFolder(FILE_IO_PREFIX + AString("logs"));
|
||||
m_File.Open(
|
||||
bool success = m_File.Open(
|
||||
FILE_IO_PREFIX + Printf(
|
||||
"logs/LOG_%d.txt",
|
||||
std::chrono::duration_cast<std::chrono::duration<int, std::ratio<1>>>(
|
||||
@ -308,13 +316,10 @@ cFileListener::cFileListener(void)
|
||||
),
|
||||
cFile::fmAppend
|
||||
);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel)
|
||||
virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override
|
||||
{
|
||||
const char * LogLevelPrefix = "Unkn ";
|
||||
bool ShouldFlush = false;
|
||||
@ -350,6 +355,23 @@ void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel)
|
||||
}
|
||||
}
|
||||
|
||||
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)};
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,30 +2,8 @@
|
||||
#include "Logger.h"
|
||||
#include "OSSupport/File.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
std::unique_ptr<cLogger::cListener> MakeConsoleListener(bool a_IsService);
|
||||
std::pair<bool, std::unique_ptr<cLogger::cListener>> MakeFileListener();
|
||||
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
@ -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 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 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 SendChat (const AString & a_Message, eChatType a_Type) = 0;
|
||||
virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) = 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 SendDestroyEntity (const cEntity & a_Entity) = 0;
|
||||
|
@ -245,65 +245,11 @@ void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
|
||||
|
||||
|
||||
|
||||
void cProtocol172::SendChat(const AString & a_Message)
|
||||
{
|
||||
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)
|
||||
void cProtocol172::SendChat(const AString & a_Message, eChatType a_Type)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -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?
|
||||
|
||||
if (type != ctChatBox) // 1.7.2 doesn't support anything else
|
||||
if (a_Type != ctChatBox) // 1.7.2 doesn't support anything else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cWorld * World = m_Client->GetPlayer()->GetWorld();
|
||||
bool ShouldUseChatPrefixes = (World == nullptr) ? false : World->ShouldUseChatPrefixes();
|
||||
|
||||
// Send the message to the client:
|
||||
cPacketizer Pkt(*this, 0x02);
|
||||
Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes));
|
||||
Pkt.WriteString(a_Message.CreateJsonString(a_ShouldUseChatPrefixes));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 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 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 SendChat (const AString & a_Message, eChatType a_Type) override;
|
||||
virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) 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 SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
|
@ -246,84 +246,28 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
|
||||
|
||||
|
||||
|
||||
void cProtocol180::SendChat(const AString & a_Message)
|
||||
{
|
||||
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)
|
||||
void cProtocol180::SendChat(const AString & a_Message, eChatType a_Type)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, 0x02); // Chat Message packet
|
||||
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?
|
||||
|
||||
cWorld * World = m_Client->GetPlayer()->GetWorld();
|
||||
bool ShouldUseChatPrefixes = (World == nullptr) ? false : World->ShouldUseChatPrefixes();
|
||||
|
||||
// Send the message to the client:
|
||||
cPacketizer Pkt(*this, 0x02);
|
||||
Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes));
|
||||
Pkt.WriteBEInt8(type);
|
||||
Pkt.WriteString(a_Message.CreateJsonString(a_ShouldUseChatPrefixes));
|
||||
Pkt.WriteBEInt8(a_Type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 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 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 SendChat (const AString & a_Message, eChatType a_Type) override;
|
||||
virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) 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 SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
|
@ -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);
|
||||
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);
|
||||
m_Protocol->SendChat(a_Message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
m_Protocol->SendChat(a_Message, a_Type, a_ShouldUseChatPrefixes);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 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 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 SendChat (const AString & a_Message, eChatType a_Type) override;
|
||||
virtual void SendChat (const cCompositeChat & a_Message, eChatType a_Type, bool a_ShouldUseChatPrefixes) 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 SendDestroyEntity (const cEntity & a_Entity) override;
|
||||
|
19
src/Root.cpp
19
src/Root.cpp
@ -22,6 +22,7 @@
|
||||
#include "SettingsRepositoryInterface.h"
|
||||
#include "OverridesSettingsRepository.h"
|
||||
#include "SelfTests.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
cLogger::cListener * consoleLogListener = MakeConsoleListener(m_RunAsService);
|
||||
cLogger::cListener * fileLogListener = new cFileListener();
|
||||
cLogger::GetInstance().AttachListener(consoleLogListener);
|
||||
cLogger::GetInstance().AttachListener(fileLogListener);
|
||||
auto consoleLogListener = MakeConsoleListener(m_RunAsService);
|
||||
auto consoleAttachment = cLogger::GetInstance().AttachListener(std::move(consoleLogListener));
|
||||
auto fileLogListenerRet = MakeFileListener();
|
||||
if (!fileLogListenerRet.first)
|
||||
{
|
||||
LOGERROR("Failed to open log file, aborting");
|
||||
return;
|
||||
}
|
||||
auto fileAttachment = cLogger::GetInstance().AttachListener(std::move(fileLogListenerRet.second));
|
||||
|
||||
LOG("--- Started Log ---");
|
||||
|
||||
@ -317,11 +323,6 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo)
|
||||
LOG("Shutdown successful - restarting...");
|
||||
}
|
||||
LOG("--- Stopped Log ---");
|
||||
|
||||
cLogger::GetInstance().DetachListener(consoleLogListener);
|
||||
delete consoleLogListener;
|
||||
cLogger::GetInstance().DetachListener(fileLogListener);
|
||||
delete fileLogListener;
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,8 +255,6 @@ int cWorld::GetDefaultWeatherInterval(eWeather a_Weather)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
LOGWARNING("Unknown current weather: %d. Setting sunny.", m_Weather);
|
||||
ASSERT(!"Unknown weather");
|
||||
return eWeather_Sunny;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "OSSupport/NetworkSingleton.h"
|
||||
#include "BuildInfo.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include "MemorySettingsRepository.h"
|
||||
|
||||
@ -472,6 +473,10 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __unix__
|
||||
std::signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user