Merge branch 'master' into issue850
Conflicts: src/BlockID.h
This commit is contained in:
commit
93833069a8
3
.gitignore
vendored
3
.gitignore
vendored
@ -56,6 +56,7 @@ Makefile
|
||||
*.a
|
||||
*.d
|
||||
*.so
|
||||
BuildInfo.h
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
@ -64,7 +65,7 @@ install_mainfest.txt
|
||||
src/MCServer
|
||||
lib/tolua++/tolua
|
||||
src/Bindings/Bindings.*
|
||||
src/Bindings/BindingDependecies.txt
|
||||
src/Bindings/BindingDependencies.txt
|
||||
MCServer.dir/
|
||||
src/AllFiles.lst
|
||||
|
||||
|
17
.gitmodules
vendored
17
.gitmodules
vendored
@ -7,6 +7,21 @@
|
||||
[submodule "MCServer/Plugins/TransAPI"]
|
||||
path = MCServer/Plugins/TransAPI
|
||||
url = https://github.com/bearbin/transapi.git
|
||||
[submodule "MCServer/Plugins/ChunkWorx"]
|
||||
path = MCServer/Plugins/ChunkWorx
|
||||
url = https://github.com/mc-server/ChunkWorx.git
|
||||
[submodule "MCServer/Plugins/ChatLog"]
|
||||
path = MCServer/Plugins/ChatLog
|
||||
url = https://github.com/mc-server/ChatLog.git
|
||||
[submodule "MCServer/Plugins/Handy"]
|
||||
path = MCServer/Plugins/Handy
|
||||
url = https://github.com/mc-server/Handy.git
|
||||
[submodule "MCServer/Plugins/MagicCarpet"]
|
||||
path = MCServer/Plugins/MagicCarpet
|
||||
url = https://github.com/mc-server/MagicCarpet.git
|
||||
[submodule "lib/polarssl"]
|
||||
path = lib/polarssl
|
||||
url = https://github.com/mc-server/polarssl
|
||||
url = https://github.com/mc-server/polarssl.git
|
||||
[submodule "lib/SQLiteCpp"]
|
||||
path = lib/SQLiteCpp
|
||||
url = https://github.com/mc-server/SQLiteCpp.git
|
||||
|
13
Android/res/values-pl/strings.xml
Normal file
13
Android/res/values-pl/strings.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="hello">Hello World, MCServerActivity!</string>
|
||||
<string name="app_name">MCServer</string>
|
||||
<string name="start">Start</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="mcserver_is_running">MCServer jest włączony</string>
|
||||
<string name="mcserver_is_not_running">MCServer jest wyłączony</string>
|
||||
<string name="your_ip">Twoje IP …</string>
|
||||
<string name="configure">Ustawienia</string>
|
||||
|
||||
</resources>
|
@ -2,6 +2,10 @@
|
||||
|
||||
set -e
|
||||
|
||||
export MCSERVER_BUILD_SERIES_NAME="Travis $CC $TRAVIS_MCSERVER_BUILD_TYPE"
|
||||
export MCSERVER_BUILD_ID=$TRAVIS_JOB_NUMBER
|
||||
export MCSERVER_BUILD_DATETIME=`date`
|
||||
|
||||
cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1;
|
||||
make -j 2;
|
||||
make -j 2 test;
|
||||
|
@ -1,4 +1,4 @@
|
||||
cmake_minimum_required (VERSION 2.8.2)
|
||||
cmake_minimum_required (VERSION 2.8.7)
|
||||
|
||||
# Without this, the MSVC variable isn't defined for MSVC builds ( http://www.cmake.org/pipermail/cmake/2011-November/047130.html )
|
||||
enable_language(CXX C)
|
||||
@ -18,6 +18,25 @@ if(DEFINED ENV{TRAVIS_BUILD_WITH_COVERAGE})
|
||||
set(BUILD_WITH_COVERAGE $ENV{TRAVIS_BUILD_WITH_COVERAGE})
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{MCSERVER_BUILD_ID})
|
||||
set(BUILD_ID $ENV{MCSERVER_BUILD_ID})
|
||||
set(BUILD_SERIES_NAME $ENV{MCSERVER_BUILD_SERIES_NAME})
|
||||
set(BUILD_DATETIME $ENV{MCSERVER_BUILD_DATETIME})
|
||||
if(DEFINED ENV{MCSERVER_BUILD_COMMIT_ID})
|
||||
set(BUILD_COMMIT_ID $ENV{MCSERVER_BUILD_COMMIT_ID})
|
||||
else()
|
||||
message("Commit id not set, attempting to determine id from git")
|
||||
execute_process(
|
||||
COMMAND git rev-parse HEAD
|
||||
RESULT_VARIABLE GIT_EXECUTED
|
||||
OUTPUT_VARIABLE BUILD_COMMIT_ID)
|
||||
string(STRIP ${BUILD_COMMIT_ID} BUILD_COMMIT_ID)
|
||||
if (NOT (GIT_EXECUTED EQUAL 0))
|
||||
message(FATAL_ERROR "Could not identifiy git commit id")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# This has to be done before any flags have been set up.
|
||||
if(${BUILD_TOOLS})
|
||||
add_subdirectory(Tools/MCADefrag/)
|
||||
@ -53,6 +72,14 @@ endif()
|
||||
|
||||
project (MCServer)
|
||||
|
||||
# Set options for SQLiteCpp, disable all their tests and lints:
|
||||
set(SQLITECPP_RUN_CPPLINT OFF CACHE BOOL "Run cpplint.py tool for Google C++ StyleGuide." FORCE)
|
||||
set(SQLITECPP_RUN_CPPCHECK OFF CACHE BOOL "Run cppcheck C++ static analysis tool." FORCE)
|
||||
set(SQLITECPP_RUN_DOXYGEN OFF CACHE BOOL "Run Doxygen C++ documentation tool." FORCE)
|
||||
set(SQLITECPP_BUILD_EXAMPLES OFF CACHE BOOL "Build examples." FORCE)
|
||||
set(SQLITECPP_BUILD_TESTS OFF CACHE BOOL "Build and run tests." FORCE)
|
||||
set(SQLITECPP_INTERNAL_SQLITE OFF CACHE BOOL "Add the internal SQLite3 source to the project." FORCE)
|
||||
|
||||
# Include all the libraries:
|
||||
add_subdirectory(lib/inifile/)
|
||||
add_subdirectory(lib/jsoncpp/)
|
||||
@ -60,9 +87,16 @@ add_subdirectory(lib/zlib/)
|
||||
add_subdirectory(lib/lua/)
|
||||
add_subdirectory(lib/tolua++/)
|
||||
add_subdirectory(lib/sqlite/)
|
||||
add_subdirectory(lib/SQLiteCpp/)
|
||||
add_subdirectory(lib/expat/)
|
||||
add_subdirectory(lib/luaexpat/)
|
||||
|
||||
# Add proper include directories so that SQLiteCpp can find SQLite3:
|
||||
get_property(SQLITECPP_INCLUDES DIRECTORY "lib/SQLiteCpp/" PROPERTY INCLUDE_DIRECTORIES)
|
||||
set(SQLITECPP_INCLUDES "${SQLITECPP_INCLUDES}" "${CMAKE_CURRENT_SOURCE_DIR}/lib/sqlite/")
|
||||
set_property(DIRECTORY lib/SQLiteCpp/ PROPERTY INCLUDE_DIRECTORIES "${SQLITECPP_INCLUDES}")
|
||||
set_property(TARGET SQLiteCpp PROPERTY INCLUDE_DIRECTORIES "${SQLITECPP_INCLUDES}")
|
||||
|
||||
if (WIN32)
|
||||
add_subdirectory(lib/luaproxy/)
|
||||
endif()
|
||||
|
@ -29,5 +29,7 @@ worktycho
|
||||
xoft
|
||||
Yeeeeezus (Donated AlchemistVillage prefabs)
|
||||
Howaner
|
||||
Masy98
|
||||
WebFreak001
|
||||
|
||||
Please add yourself to this list if you contribute to MCServer.
|
||||
|
20
Install/ThirdPartyLicenses/SQLiteCpp-LICENSE.txt
Normal file
20
Install/ThirdPartyLicenses/SQLiteCpp-LICENSE.txt
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2014 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@ -6,9 +6,7 @@
|
||||
..\MCServer\furnace.txt
|
||||
..\MCServer\items.ini
|
||||
..\MCServer\monsters.ini
|
||||
..\MCServer\buildinfo.txt
|
||||
MCServer*debug.cmd
|
||||
*.example.ini
|
||||
Lua-LICENSE.txt
|
||||
LuaExpat-license.html
|
||||
LuaSQLite3-LICENSE.txt
|
||||
MersenneTwister-LICENSE.txt
|
||||
ThirdPartyLicenses
|
||||
|
@ -1,2 +1,3 @@
|
||||
MCServer\*.pdb
|
||||
MCServer\buildinfo.txt
|
||||
src\Bindings\Bindings.*
|
@ -523,22 +523,29 @@ end
|
||||
|
||||
Functions =
|
||||
{
|
||||
GenerateOfflineUUID = { Params = "Username", Return = "string", Notes = "(STATIC) Generates an UUID based on the player name provided. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. Returns a 36-char UUID (with dashes)." },
|
||||
GenerateOfflineUUID = { Params = "Username", Return = "string", Notes = "(STATIC) Generates an UUID based on the player name provided. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. Returns a 32-char UUID (no dashes)." },
|
||||
GetClientBrand = { Params = "", Return = "string", Notes = "Returns the brand that the client has sent in their MC|Brand plugin message." },
|
||||
GetIPString = { Params = "", Return = "string", Notes = "Returns the IP address of the connection, as a string. Only the address part is returned, without the port number." },
|
||||
GetLocale = { Params = "", Return = "Locale", Notes = "Returns the locale string that the client sends as part of the protocol handshake. Can be used to provide localized strings." },
|
||||
GetPing = { Params = "", Return = "number", Notes = "Returns the ping time, in ms" },
|
||||
GetPlayer = { Params = "", Return = "{{cPlayer|cPlayer}}", Notes = "Returns the player object connected to this client. Note that this may be nil, for example if the player object is not yet spawned." },
|
||||
GetProtocolVersion = { Params = "", Return = "number", Notes = "Returns the protocol version number of the protocol that the client is talking. Returns zero if the protocol version is not (yet) known." },
|
||||
GetUniqueID = { Params = "", Return = "number", Notes = "Returns the UniqueID of the client used to identify the client in the server" },
|
||||
GetUUID = { Params = "", Return = "string", Notes = "Returns the authentication-based UUID of the client. This UUID should be used to identify the player when persisting any player-related data." },
|
||||
GetUUID = { Params = "", Return = "string", Notes = "Returns the authentication-based UUID of the client. This UUID should be used to identify the player when persisting any player-related data. Returns a 32-char UUID (no dashes)" },
|
||||
GetUsername = { Params = "", Return = "string", Notes = "Returns the username that the client has provided" },
|
||||
GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" },
|
||||
HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." },
|
||||
IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."},
|
||||
Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" },
|
||||
SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." },
|
||||
SetClientBrand = { Params = "ClientBrand", Return = "", Notes = "Sets the value of the client's brand. Normally this value is received from the client by a MC|Brand plugin message, this function lets plugins overwrite the value." },
|
||||
SetLocale = { Params = "Locale", Return = "", Notes = "Sets the locale that MCServer keeps on record. Initially the locale is initialized in protocol handshake, this function allows plugins to override the stored value (but only server-side and only until the user disconnects)." },
|
||||
SetUsername = { Params = "Name", Return = "", Notes = "Sets the username" },
|
||||
SetViewDistance = { Params = "ViewDistance", Return = "", Notes = "Sets the viewdistance (number of chunks loaded for the player in each direction)" },
|
||||
SendBlockChange = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "", Notes = "Sends a BlockChange packet to the client. This can be used to create fake blocks only for that player." },
|
||||
SendEntityAnimation = { Params = "{{cEntity|Entity}}, AnimationNumber", Return = "", Notes = "Sends the specified animation of the specified entity to the client. The AnimationNumber is protocol-specific." },
|
||||
SendSoundEffect = { Params = "SoundName, X, Y, Z, Volume, Pitch", Return = "", Notes = "Sends a sound effect request to the client. The sound is played at the specified coords, with the specified volume (a float, 1.0 is full volume, can be more) and pitch (0-255, 63 is 100%)" },
|
||||
SendTimeUpdate = { Params = "WorldAge, TimeOfDay, DoDaylightCycle", Return = "", Notes = "Sends the specified time update to the client. WorldAge is the total age of the world, in ticks. TimeOfDay is the current day's time, in ticks (0 - 24000). DoDaylightCycle is a bool that specifies whether the client should automatically move the sun (true) or keep it in the same place (false)." },
|
||||
},
|
||||
Constants =
|
||||
{
|
||||
@ -554,9 +561,9 @@ end
|
||||
and commands suggested on click. The chat message can be sent by the regular chat-sending functions,
|
||||
{{cPlayer}}:SendMessage(), {{cWorld}}:BroadcastChat() and {{cRoot}}:BroadcastChat().</p>
|
||||
<p>
|
||||
Note that most of the functions in this class are so-called modifiers - they modify the object and
|
||||
then return the object itself, so that they can be chained one after another. See the Chaining
|
||||
example below for details.</p>
|
||||
Note that most of the functions in this class are so-called chaining modifiers - they modify the
|
||||
object and then return the object itself, so that they can be chained one after another. See the
|
||||
Chaining example below for details.</p>
|
||||
<p>
|
||||
Each part of the composite chat message takes a "Style" parameter, this is a string that describes
|
||||
the formatting. It uses the following strings, concatenated together:
|
||||
@ -580,14 +587,17 @@ end
|
||||
{ Params = "Text", Return = "", Notes = "Creates a chat message containing the specified text, parsed by the ParseText() function. This allows easy migration from old chat messages." },
|
||||
},
|
||||
AddRunCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, runs the specified command. Chaining." },
|
||||
AddShowAchievementPart = { Params = "PlayerName, AchievementName, [Style]", Return = "", Notes = "Adds a text that represents the 'Achievement get' message." },
|
||||
AddSuggestCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, puts the specified command into the player's chat input area. Chaining." },
|
||||
AddTextPart = { Params = "Text, [Style]", Return = "self", Notes = "Adds a regular text. Chaining." },
|
||||
AddUrlPart = { Params = "Text, Url, [Style]", Return = "self", Notes = "Adds a text which, when clicked, opens up a browser at the specified URL. Chaining." },
|
||||
Clear = { Params = "", Return = "", Notes = "Removes all parts from this object" },
|
||||
CreateJsonString = { Params = "[AddPrefixes]", Return = "string", Notes = "Returns the entire object serialized into JSON, as it would be sent to a client. AddPrefixes specifies whether the chat prefixes should be prepended to the message, true by default." },
|
||||
ExtractText = { Params = "", Return = "string", Notes = "Returns the text from the parts that comprises the human-readable data. Used for older protocols that don't support composite chat and for console-logging." },
|
||||
GetAdditionalMessageTypeData = { Params = "", Return = "string", Notes = "Returns the AdditionalData associated with the message, such as the sender's name for mtPrivateMessage" },
|
||||
GetMessageType = { Params = "", Return = "MessageType", Notes = "Returns the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.)" },
|
||||
ParseText = { Params = "Text", Return = "self", Notes = "Adds text, while recognizing http and https URLs and old-style formatting codes (\"@2\"). Chaining." },
|
||||
SetMessageType = { Params = "MessageType", Return = "self", Notes = "Sets the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.) Chaining." },
|
||||
SetMessageType = { Params = "MessageType, AdditionalData", Return = "self", Notes = "Sets the MessageType (mtXXX constant) that is associated with this message. Also sets the additional data (string) associated with the message, which is specific for the message type - such as the sender's name for mtPrivateMessage. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.). Chaining." },
|
||||
UnderlineUrls = { Params = "", Return = "self", Notes = "Makes all URL parts contained in the message underlined. Doesn't affect parts added in the future. Chaining." },
|
||||
},
|
||||
|
||||
@ -776,7 +786,9 @@ end</pre>
|
||||
AddSpeedX = { Params = "AddX", Return = "", Notes = "Adds the specified amount of speed in the X axis direction." },
|
||||
AddSpeedY = { Params = "AddY", Return = "", Notes = "Adds the specified amount of speed in the Y axis direction." },
|
||||
AddSpeedZ = { Params = "AddZ", Return = "", Notes = "Adds the specified amount of speed in the Z axis direction." },
|
||||
ArmorCoversAgainst = { Params = "{{cEntity|AttackerEntity}}, DamageType, RawDamage", Return = "number", Notes = "Returns the points out of a_RawDamage that the currently equipped armor would cover." },
|
||||
Destroy = { Params = "", Return = "", Notes = "Schedules the entity to be destroyed" },
|
||||
GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left). Note, this function is only updated with mobs or players." },
|
||||
GetArmorCoverAgainst = { Params = "AttackerEntity, DamageType, RawDamage", Return = "number", Notes = "Returns the number of hitpoints out of RawDamage that the currently equipped armor would cover. See {{TakeDamageInfo}} for more information on attack damage." },
|
||||
GetChunkX = { Params = "", Return = "number", Notes = "Returns the X-coord of the chunk in which the entity is placed" },
|
||||
GetChunkZ = { Params = "", Return = "number", Notes = "Returns the Z-coord of the chunk in which the entity is placed" },
|
||||
@ -792,6 +804,7 @@ end</pre>
|
||||
GetHeadYaw = { Params = "", Return = "number", Notes = "Returns the pitch of the entity's head (FIXME: Rename to GetHeadPitch() )." },
|
||||
GetHealth = { Params = "", Return = "number", Notes = "Returns the current health of the entity." },
|
||||
GetHeight = { Params = "", Return = "number", Notes = "Returns the height (Y size) of the entity" },
|
||||
GetInvulnerableTicks = { Params = "", Return = "number", Notes = "Returns the number of ticks that this entity will be invulnerable for. This is used for after-hit recovery - the entities are invulnerable for half a second after being hit." },
|
||||
GetKnockbackAmountAgainst = { Params = "ReceiverEntity", Return = "number", Notes = "Returns the amount of knockback that the currently equipped items would cause when attacking the ReceiverEntity." },
|
||||
GetLookVector = { Params = "", Return = "{{Vector3f}}", Notes = "Returns the vector that defines the direction in which the entity is looking" },
|
||||
GetMass = { Params = "", Return = "number", Notes = "Returns the mass of the entity. Currently unused." },
|
||||
@ -809,23 +822,29 @@ end</pre>
|
||||
GetSpeedX = { Params = "", Return = "number", Notes = "Returns the X-part of the speed vector" },
|
||||
GetSpeedY = { Params = "", Return = "number", Notes = "Returns the Y-part of the speed vector" },
|
||||
GetSpeedZ = { Params = "", Return = "number", Notes = "Returns the Z-part of the speed vector" },
|
||||
GetTicksAlive = { Params = "", Return = "number", Notes = "Returns the number of ticks that this entity has been alive for." },
|
||||
GetUniqueID = { Params = "", Return = "number", Notes = "Returns the ID that uniquely identifies the entity within the running server. Note that this ID is not persisted to the data files." },
|
||||
GetWidth = { Params = "", Return = "number", Notes = "Returns the width (X and Z size) of the entity." },
|
||||
GetWorld = { Params = "", Return = "{{cWorld}}", Notes = "Returns the world where the entity resides" },
|
||||
GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180. 0 means ZP, 90 means XM, -180 means ZM, -90 means XP." },
|
||||
HandleSpeedFromAttachee = { Params = "ForwardAmount, SidewaysAmount", Return = "", Notes = "Updates the entity's speed based on the attachee exerting the specified force forward and sideways. Used for entities being driven by other entities attached to them - usually players driving minecarts and boats." },
|
||||
Heal = { Params = "Hitpoints", Return = "", Notes = "Heals the specified number of hitpoints. Hitpoints is expected to be a positive number." },
|
||||
IsA = { Params = "ClassName", Return = "bool", Notes = "Returns true if the entity class is a descendant of the specified class name, or the specified class itself" },
|
||||
IsBoat = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cBoat|boat}}." },
|
||||
IsCrouched = { Params = "", Return = "bool", Notes = "Returns true if the entity is crouched. Always false for entities that don't support crouching." },
|
||||
IsDestroyed = { Params = "", Return = "bool", Notes = "Returns true if the entity has been destroyed and is awaiting removal from the internal structures." },
|
||||
IsEnderCrystal = { Params = "", Return = "bool", Notes = "Returns true if the entity is an ender crystal." },
|
||||
IsExpOrb = { Params = "", Return = "bool", Notes = "Returns true if the entity represents an experience orb" },
|
||||
IsFallingBlock = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cFallingBlock}} entity." },
|
||||
IsFireproof = { Params = "", Return = "bool", Notes = "Returns true if the entity takes no damage from being on fire." },
|
||||
IsFloater = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a fishing rod floater" },
|
||||
IsInvisible = { Params = "", Return = "bool", Notes = "Returns true if the entity is invisible" },
|
||||
IsItemFrame = { Params = "", Return = "bool", Notes = "Returns true if the entity is an item frame." },
|
||||
IsMinecart = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cMinecart|minecart}}" },
|
||||
IsMob = { Params = "", Return = "bool", Notes = "Returns true if the entity represents any {{cMonster|mob}}." },
|
||||
IsOnFire = { Params = "", Return = "bool", Notes = "Returns true if the entity is on fire" },
|
||||
IsPainting = { Params = "", Return = "bool", Notes = "Returns if this entity is a painting." },
|
||||
IsPawn = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cPawn}} descendant." },
|
||||
IsPickup = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cPickup|pickup}}." },
|
||||
IsPlayer = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cPlayer|player}}" },
|
||||
IsProjectile = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cProjectileEntity}} descendant." },
|
||||
@ -835,12 +854,19 @@ end</pre>
|
||||
IsSubmerged = { Params = "", Return = "bool", Notes = "Returns true if the mob or player is submerged in water (head is in a water block). Note, this function is only updated with mobs or players." },
|
||||
IsSwimming = { Params = "", Return = "bool", Notes = "Returns true if the mob or player is swimming in water (feet are in a water block). Note, this function is only updated with mobs or players." },
|
||||
IsTNT = { Params = "", Return = "bool", Notes = "Returns true if the entity represents a {{cTNTEntity|TNT entity}}" },
|
||||
Killed = { Params = "{{cEntity|Victim}}", Return = "", Notes = "This entity has killed another entity (the Victim). For players, adds the scoreboard statistics about the kill." },
|
||||
KilledBy = { Notes = "FIXME: Remove this from API" },
|
||||
GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left). Note, this function is only updated with mobs or players." },
|
||||
MoveToWorld =
|
||||
{
|
||||
{ Params = "{{cWorld|World}}, [ShouldSendRespawn]", Return = "bool", Notes = "Removes the entity from this world and starts moving it to the specified world. Note that to avoid deadlocks, the move is asynchronous - the entity is moved into a queue and will be moved from that queue into the destination world at some (unpredictable) time in the future. ShouldSendRespawn is used only for players, it specifies whether the player should be sent a Repawn packet upon leaving the world (The client handles respawns only between different dimensions)." },
|
||||
{ Params = "WorldName, [ShouldSendRespawn]", Return = "bool", Notes = "Removes the entity from this world and starts moving it to the specified world. Note that to avoid deadlocks, the move is asynchronous - the entity is moved into a queue and will be moved from that queue into the destination world at some (unpredictable) time in the future. ShouldSendRespawn is used only for players, it specifies whether the player should be sent a Repawn packet upon leaving the world (The client handles respawns only between different dimensions)." },
|
||||
},
|
||||
SetGravity = { Params = "Gravity", Return = "", Notes = "Sets the number that is used as the gravity for physics simulation. 1G (9.78) by default." },
|
||||
SetHeadYaw = { Params = "HeadPitch", Return = "", Notes = "Sets the head pitch (FIXME: Rename to SetHeadPitch() )." },
|
||||
SetHealth = { Params = "Hitpoints", Return = "", Notes = "Sets the entity's health to the specified amount of hitpoints. Doesn't broadcast any hurt animation. Doesn't kill the entity if health drops below zero. Use the TakeDamage() function instead for taking damage." },
|
||||
SetHeight = { Params = "", Return = "", Notes = "FIXME: Remove this from API" },
|
||||
SetInvulnerableTicks = { Params = "NumTicks", Return = "", Notes = "Sets the amount of ticks for which the entity will not receive any damage from other entities." },
|
||||
SetIsFireproof = { Params = "IsFireproof", Return = "", Notes = "Sets whether the entity receives damage from being on fire." },
|
||||
SetMass = { Params = "Mass", Return = "", Notes = "Sets the mass of the entity. Currently unused." },
|
||||
SetMaxHealth = { Params = "MaxHitpoints", Return = "", Notes = "Sets the maximum hitpoints of the entity. If current health is above MaxHitpoints, it is capped to MaxHitpoints." },
|
||||
SetPitch = { Params = "number", Return = "", Notes = "Sets the pitch (nose-down rotation) of the entity" },
|
||||
@ -855,7 +881,7 @@ end</pre>
|
||||
SetPosZ = { Params = "number", Return = "", Notes = "Sets the Z-coord of the entity's pivot" },
|
||||
SetRoll = { Params = "number", Return = "", Notes = "Sets the roll (sideways rotation) of the entity. Currently unused." },
|
||||
SetRot = { Params = "{{Vector3f|Rotation}}", Return = "", Notes = "Sets the entire rotation vector (Yaw, Pitch, Roll)" },
|
||||
SetYawFromSpeed = { Params = "", Return = "", Notes = "Sets the entity's yaw to match its current speed (entity looking forwards as it moves). (FIXME: Rename to SetYawFromSpeed)" },
|
||||
SetYawFromSpeed = { Params = "", Return = "", Notes = "Sets the entity's yaw to match its current speed (entity looking forwards as it moves)." },
|
||||
SetSpeed =
|
||||
{
|
||||
{ Params = "SpeedX, SpeedY, SpeedZ", Return = "", Notes = "Sets the current speed of the entity" },
|
||||
@ -881,18 +907,20 @@ end</pre>
|
||||
Constants =
|
||||
{
|
||||
etBoat = { Notes = "The entity is a {{cBoat}}" },
|
||||
etEnderCrystal = { Notes = "" },
|
||||
etEntity = { Notes = "No further specialization available" },
|
||||
etExpOrb = { Notes = "The entity is a {{cExpOrb}}" },
|
||||
etFallingBlock = { Notes = "The entity is a {{cFallingBlock}}" },
|
||||
etFloater = { Notes = "The entity is a fishing rod floater" },
|
||||
etItemFrame = { Notes = "" },
|
||||
etMinecart = { Notes = "The entity is a {{cMinecart}} descendant" },
|
||||
etMob = { Notes = "The entity is a {{cMonster}} descendant" },
|
||||
etMonster = { Notes = "The entity is a {{cMonster}} descendant" },
|
||||
etMinecart = { Notes = "The entity is a {{cMinecart}} descendant" },
|
||||
etPlayer = { Notes = "The entity is a {{cPlayer}}" },
|
||||
etPainting = { Notes = "The entity is a {{cPainting}}" },
|
||||
etPickup = { Notes = "The entity is a {{cPickup}}" },
|
||||
etPlayer = { Notes = "The entity is a {{cPlayer}}" },
|
||||
etProjectile = { Notes = "The entity is a {{cProjectileEntity}} descendant" },
|
||||
etTNT = { Notes = "The entity is a {{cTNTEntity}}" },
|
||||
etPainting = { Notes = "The entity is a {{cPainting}}" },
|
||||
},
|
||||
ConstantGroups =
|
||||
{
|
||||
@ -942,24 +970,6 @@ cFile:Delete("/usr/bin/virus.exe");
|
||||
Inherits = "cEntity",
|
||||
},
|
||||
|
||||
cGroup =
|
||||
{
|
||||
Desc = [[
|
||||
This class represents a group {{cPlayer|players}} can be in. Groups define the permissions players
|
||||
have, and optionally the color of their name in the chat.
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
SetName = { Return = "" },
|
||||
GetName = { Return = "string" },
|
||||
SetColor = { Return = "" },
|
||||
GetColor = { Return = "string" },
|
||||
AddCommand = { Return = "" },
|
||||
AddPermission = { Return = "" },
|
||||
InheritFrom = { Return = "" },
|
||||
},
|
||||
}, -- cGroup
|
||||
|
||||
cIniFile =
|
||||
{
|
||||
Desc = [[
|
||||
@ -1060,6 +1070,7 @@ ValueName0=SomeOtherValue
|
||||
GetValueSetB = { Params = "KeyName, ValueName, Default", Return = "bool", Notes = "Returns the value of the specified name under the specified key, as a bool. If the value doesn't exist, creates it with the specified default." },
|
||||
GetValueSetF = { Params = "KeyName, ValueName, Default", Return = "number", Notes = "Returns the value of the specified name under the specified key, as a floating-point number. If the value doesn't exist, creates it with the specified default." },
|
||||
GetValueSetI = { Params = "KeyName, ValueName, Default", Return = "number", Notes = "Returns the value of the specified name under the specified key, as an integer. If the value doesn't exist, creates it with the specified default." },
|
||||
HasValue = { Params = "KeyName, ValueName", Return = "bool", Notes = "Returns true if the specified value is present." },
|
||||
ReadFile = { Params = "FileName, [AllowExampleFallback]", Return = "bool", Notes = "Reads the values from the specified file. Previous in-memory contents are lost. If the file cannot be opened, and AllowExample is true, another file, \"filename.example.ini\", is loaded and then saved as \"filename.ini\". Returns true if successful, false if not." },
|
||||
SetValue =
|
||||
{
|
||||
@ -1206,7 +1217,7 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
constructor =
|
||||
{
|
||||
{ Params = "", Return = "cItem", Notes = "Creates a new empty cItem object" },
|
||||
{ Params = "ItemType, Count, Damage, EnchantmentString", Return = "cItem", Notes = "Creates a new cItem object of the specified type, count (1 by default), damage (0 by default) and enchantments (non-enchanted by default)" },
|
||||
{ Params = "ItemType, Count, Damage, EnchantmentString, CustomName, Lore", Return = "cItem", Notes = "Creates a new cItem object of the specified type, count (1 by default), damage (0 by default), enchantments (non-enchanted by default), CustomName (empty by default) and Lore (string, empty by default)" },
|
||||
{ Params = "cItem", Return = "cItem", Notes = "Creates an exact copy of the cItem object in the parameter" },
|
||||
} ,
|
||||
AddCount = { Params = "AmountToAdd", Return = "cItem", Notes = "Adds the specified amount to the item count. Returns self (useful for chaining)." },
|
||||
@ -1219,12 +1230,14 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
IsDamageable = { Params = "", Return = "bool", Notes = "Returns true if this item does account for its damage" },
|
||||
IsEmpty = { Params = "", Return = "bool", Notes = "Returns true if this object represents an empty item (zero count or invalid ID)" },
|
||||
IsEqual = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is the same as the one stored in the object (type, damage, lore, name and enchantments)" },
|
||||
IsEnchantable = { Params = "", Return = "bool", Notes = "Returns true if the item is enchantable" },
|
||||
IsFullStack = { Params = "", Return = "bool", Notes = "Returns true if the item is stacked up to its maximum stacking" },
|
||||
IsSameType = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is of the same ItemType as the one stored in the object. This is true even if the two items have different enchantments" },
|
||||
IsBothNameAndLoreEmpty = { Params = "", Return = "bool", Notes = "Returns if both the custom name and lore are not set." },
|
||||
IsCustomNameEmpty = { Params = "", Return = "bool", Notes = "Returns if the custom name of the cItem is empty." },
|
||||
IsLoreEmpty = { Params = "", Return = "", Notes = "Returns if the lore of the cItem is empty." },
|
||||
GetEnchantability = { Params = "", Return = "number", Notes = "Returns the enchantability of the item. When the item hasn't a enchantability, it will returns 0" },
|
||||
EnchantByXPLevels = { Params = "NumXPLevels", Return = "bool", Notes = "Enchants the item using the specified number of XP levels. Returns true if item enchanted, false if not." },
|
||||
IsEnchantable = { Params = "ItemType, WithBook", Return = "bool", Notes = "(STATIC) Returns true if the specified item type is enchantable. If WithBook is true, the function is used in the anvil inventory with book enchantments. So it checks the \"only book enchantments\" too. Example: You can only enchant a hoe with a book." },
|
||||
},
|
||||
Variables =
|
||||
{
|
||||
@ -1234,6 +1247,8 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
|
||||
m_ItemType = { Type = "number", Notes = "The item type. One of E_ITEM_ or E_BLOCK_ constants" },
|
||||
m_CustomName = { Type = "string", Notes = "The custom name for an item." },
|
||||
m_Lore = { Type = "string", Notes = "The lore for an item. Line breaks are represented by the ` character." },
|
||||
m_RepairCost = { Type = "number", Notes = "The repair cost of the item. The anvil need this value" },
|
||||
m_Enchantments = { Type = "{{cEnchantments|cEnchantments}}}", Notes = "The enchantments of the item." },
|
||||
},
|
||||
AdditionalInfo =
|
||||
{
|
||||
@ -1606,6 +1621,38 @@ a_Player:OpenWindow(Window);
|
||||
|
||||
}, -- cMapManager
|
||||
|
||||
cMojangAPI =
|
||||
{
|
||||
Desc = [[
|
||||
Provides interface to various API functions that Mojang provides through their servers. Note that
|
||||
some of these calls will wait for a response from the network, and so shouldn't be used while the
|
||||
server is fully running (or at least when there are players connected) to avoid percepted lag.</p>
|
||||
<p>
|
||||
All the functions are static, call them using the <code>cMojangAPI:Function()</code> convention.</p>
|
||||
<p>
|
||||
Mojang uses two formats for UUIDs, short and dashed. MCServer works with short UUIDs internally, but
|
||||
will convert to dashed UUIDs where needed - in the protocol login for example. The MakeUUIDShort()
|
||||
and MakeUUIDDashed() functions are provided for plugins to use for conversion between the two
|
||||
formats.</p>
|
||||
<p>
|
||||
This class will cache values returned by the API service. The cache will hold the values for 7 days
|
||||
by default, after that, they will no longer be available. This is in order to not let the server get
|
||||
banned from using the API service, since they are rate-limited to 600 queries per 10 minutes. The
|
||||
cache contents also gets updated whenever a player successfully joins, since that makes the server
|
||||
contact the API service, too, and retrieve the relevant data.</p>
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
AddPlayerNameToUUIDMapping = { Params = "PlayerName, UUID", Return = "", Notes = "(STATIC) Adds the specified PlayerName-to-UUID mapping into the cache, with current timestamp. Accepts both short or dashed UUIDs. " },
|
||||
GetPlayerNameFromUUID = { Params = "UUID, [UseOnlyCached]", Return = "PlayerName", Notes = "(STATIC) Returns the playername that corresponds to the given UUID, or an empty string on error. If UseOnlyCached is false (the default), queries the Mojang servers if the UUID is not in the cache. The UUID can be either short or dashed. <br /><b>WARNING</b>: Do NOT use this function with UseOnlyCached set to false while the server is running. Only use it when the server is starting up (inside the Initialize() method), otherwise you will lag the server severely." },
|
||||
GetUUIDFromPlayerName = { Params = "PlayerName, [UseOnlyCached]", Return = "UUID", Notes = "(STATIC) Returns the (short) UUID that corresponds to the given playername, or an empty string on error. If UseOnlyCached is false (the default), queries the Mojang servers if the playername is not in the cache. <br /><b>WARNING</b>: Do NOT use this function with UseOnlyCached set to false while the server is running. Only use it when the server is starting up (inside the Initialize() method), otherwise you will lag the server severely." },
|
||||
GetUUIDsFromPlayerNames = { Params = "PlayerNames, [UseOnlyCached]", Return = "table", Notes = "(STATIC) Returns a table that contains the map, 'PlayerName' -> '(short) UUID', for all valid playernames in the input array-table. PlayerNames not recognized will not be set in the returned map. If UseOnlyCached is false (the default), queries the Mojang servers for the results that are not in the cache. <br /><b>WARNING</b>: Do NOT use this function with UseOnlyCached set to false while the server is running. Only use it when the server is starting up (inside the Initialize() method), otherwise you will lag the server severely." },
|
||||
MakeUUIDDashed = { Params = "UUID", Return = "DashedUUID", Notes = "(STATIC) Converts the UUID to a dashed format (\"01234567-8901-2345-6789-012345678901\"). Accepts both dashed or short UUIDs. Logs a warning and returns an empty string if UUID format not recognized." },
|
||||
MakeUUIDShort = { Params = "UUID", Return = "ShortUUID", Notes = "(STATIC) Converts the UUID to a short format (without dashes, \"01234567890123456789012345678901\"). Accepts both dashed or short UUIDs. Logs a warning and returns an empty string if UUID format not recognized." },
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
cMonster =
|
||||
{
|
||||
Desc = [[
|
||||
@ -1615,6 +1662,11 @@ a_Player:OpenWindow(Window);
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
HasCustomName = { Params = "", Return = "bool", Notes = "Returns true if the monster has a custom name." },
|
||||
GetCustomName = { Params = "", Return = "string", Notes = "Gets the custom name of the monster. If no custom name is set, the function returns an empty string." },
|
||||
SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of the monster. You see the name over the monster. If you want to disable the custom name, simply set an empty string." },
|
||||
IsCustomNameAlwaysVisible = { Params = "", Return = "bool", Notes = "Is the custom name of this monster always visible? If not, you only see the name when you sight the mob." },
|
||||
SetCustomNameAlwaysVisible = { Params = "bool", Return = "", Notes = "Sets the custom name visiblity of this monster. If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name." },
|
||||
FamilyFromType = { Params = "{{cMonster#MobType|MobType}}", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "(STATIC) Returns the mob family ({{cMonster#MobFamily|mfXXX}} constants) based on the mob type ({{cMonster#MobType|mtXXX}} constants)" },
|
||||
GetMobFamily = { Params = "", Return = "{{cMonster#MobFamily|MobFamily}}", Notes = "Returns this mob's family ({{cMonster#MobFamily|mfXXX}} constant)" },
|
||||
GetMobType = { Params = "", Return = "{{cMonster#MobType|MobType}}", Notes = "Returns the type of this mob ({{cMonster#MobType|mtXXX}} constant)" },
|
||||
@ -1622,6 +1674,8 @@ a_Player:OpenWindow(Window);
|
||||
MobTypeToString = { Params = "{{cMonster#MobType|MobType}}", Return = "string", Notes = "(STATIC) Returns the string representing the given mob type ({{cMonster#MobType|mtXXX}} constant), or empty string if unknown type." },
|
||||
MoveToPosition = { Params = "Position", Return = "", Notes = "Moves mob to the specified position" },
|
||||
StringToMobType = { Params = "string", Return = "{{cMonster#MobType|MobType}}", Notes = "(STATIC) Returns the mob type ({{cMonster#MobType|mtXXX}} constant) parsed from the string type (\"creeper\"), or mtInvalidType if unrecognized." },
|
||||
GetRelativeWalkSpeed = { Params = "", Return = "number", Notes = "Returns the relative walk speed of this mob. Standard is 1.0" },
|
||||
SetRelativeWalkSpeed = { Params = "number", Return = "", Notes = "Sets the relative walk speed of this mob. Standard is 1.0" },
|
||||
},
|
||||
Constants =
|
||||
{
|
||||
@ -1714,6 +1768,7 @@ a_Player:OpenWindow(Window);
|
||||
GetItem = { Params = "", Return = "{{cItem|cItem}}", Notes = "Returns the item represented by this pickup" },
|
||||
IsCollected = { Params = "", Return = "bool", Notes = "Returns true if this pickup has already been collected (is waiting to be destroyed)" },
|
||||
IsPlayerCreated = { Params = "", Return = "bool", Notes = "Returns true if the pickup was created by a player" },
|
||||
SetAge = { Params = "AgeTicks", Return = "", Notes = "Sets the pickup's age, in ticks." },
|
||||
},
|
||||
Inherits = "cEntity",
|
||||
}, -- cPickup
|
||||
@ -1728,7 +1783,6 @@ a_Player:OpenWindow(Window);
|
||||
Functions =
|
||||
{
|
||||
AddFoodExhaustion = { Params = "Exhaustion", Return = "", Notes = "Adds the specified number to the food exhaustion. Only positive numbers expected." },
|
||||
AddToGroup = { Params = "GroupName", Return = "", Notes = "Temporarily adds the player to the specified group. The assignment is lost when the player disconnects." },
|
||||
CalcLevelFromXp = { Params = "XPAmount", Return = "number", Notes = "(STATIC) Returns the level which is reached with the specified amount of XP. Inverse of XpForLevel()." },
|
||||
CanFly = { Return = "bool", Notes = "Returns if the player is able to fly." },
|
||||
CloseWindow = { Params = "[CanRefuse]", Return = "", Notes = "Closes the currently open UI window. If CanRefuse is true (default), the window may refuse the closing." },
|
||||
@ -1738,8 +1792,9 @@ a_Player:OpenWindow(Window);
|
||||
FoodPoison = { Params = "NumTicks", Return = "", Notes = "Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two" },
|
||||
ForceSetSpeed = { Params = "{{Vector3d|Direction}}", Notes = "Forces the player to move to the given direction." },
|
||||
GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." },
|
||||
GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player (based on the first group). Prefix player messages with this code." },
|
||||
GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player's messages (based on their rank). Prefix player messages with this code." },
|
||||
GetCurrentXp = { Params = "", Return = "number", Notes = "Returns the current amount of XP" },
|
||||
GetCustomName = { Params = "", Return = "string", Notes = "Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string." },
|
||||
GetEffectiveGameMode = { Params = "", Return = "{{Globals#GameMode|GameMode}}", Notes = "(OBSOLETE) Returns the current resolved game mode of the player. If the player is set to inherit the world's gamemode, returns that instead. See also GetGameMode() and IsGameModeXXX() functions. Note that this function is the same as GetGameMode(), use that function instead." },
|
||||
GetEquippedItem = { Params = "", Return = "{{cItem}}", Notes = "Returns the item that the player is currently holding; empty item if holding nothing." },
|
||||
GetEyeHeight = { Return = "number", Notes = "Returns the height of the player's eyes, in absolute coords" },
|
||||
@ -1752,21 +1807,26 @@ a_Player:OpenWindow(Window);
|
||||
GetFoodSaturationLevel = { Params = "", Return = "number", Notes = "Returns the food saturation (overcharge of the food level, is depleted before food level)" },
|
||||
GetFoodTickTimer = { Params = "", Return = "", Notes = "Returns the number of ticks past the last food-based heal or damage action; when this timer reaches 80, a new heal / damage is applied." },
|
||||
GetGameMode = { Return = "{{Globals#GameMode|GameMode}}", Notes = "Returns the player's gamemode. The player may have their gamemode unassigned, in which case they inherit the gamemode from the current {{cWorld|world}}.<br /> <b>NOTE:</b> Instead of comparing the value returned by this function to the gmXXX constants, use the IsGameModeXXX() functions. These functions handle the gamemode inheritance automatically."},
|
||||
GetGroups = { Return = "array-table of {{cGroup}}", Notes = "Returns all the groups that this player is member of, as a table. The groups are stored in the array part of the table, beginning with index 1."},
|
||||
GetIP = { Return = "string", Notes = "Returns the IP address of the player, if available. Returns an empty string if there's no IP to report."},
|
||||
GetInventory = { Return = "{{cInventory|Inventory}}", Notes = "Returns the player's inventory"},
|
||||
GetLastBedPos = { Params = "", Return = "{{Vector3i}}", Notes = "Returns the position of the last bed the player has slept in, or the world's spawn if no such position was recorded." },
|
||||
GetMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's current maximum speed, relative to the game default speed. Takes into account the sprinting / flying status." },
|
||||
GetName = { Return = "string", Notes = "Returns the player's name" },
|
||||
GetNormalMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum walking speed, relative to the game default speed. Defaults to 1, but plugins may modify it for faster or slower walking." },
|
||||
GetPermissions = { Params = "", Return = "array-table of strings", Notes = "Returns the list of all permissions that the player has assigned to them through their rank." },
|
||||
GetPlayerListName = { Return = "string", Notes = "Returns the name that is used in the playerlist." },
|
||||
GetResolvedPermissions = { Return = "array-table of string", Notes = "Returns all the player's permissions, as a table. The permissions are stored in the array part of the table, beginning with index 1." },
|
||||
GetSprintingMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum sprinting speed, relative to the game default speed. Defaults to 1.3, but plugins may modify it for faster or slower sprinting." },
|
||||
GetStance = { Return = "number", Notes = "Returns the player's stance (Y-pos of player's eyes)" },
|
||||
GetTeam = { Params = "", Return = "{{cTeam}}", Notes = "Returns the team that the player belongs to, or nil if none." },
|
||||
GetThrowSpeed = { Params = "SpeedCoeff", Return = "{{Vector3d}}", Notes = "Returns the speed vector for an object thrown with the specified speed coeff. Basically returns the normalized look vector multiplied by the coeff, with a slight random variation." },
|
||||
GetThrowStartPos = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the position where the projectiles should start when thrown by this player." },
|
||||
GetUUID = { Params = "", Return = "string", Notes = "Returns the (short) UUID that the player is using. Could be empty string for players that don't have a Mojang account assigned to them (in the future, bots for example)." },
|
||||
GetWindow = { Params = "", Return = "{{cWindow}}", Notes = "Returns the currently open UI window. If the player doesn't have any UI window open, returns the inventory window." },
|
||||
GetXpLevel = { Params = "", Return = "number", Notes = "Returns the current XP level (based on current XP amount)." },
|
||||
GetXpLifetimeTotal = { Params = "", Return = "number", Notes = "Returns the amount of XP that has been accumulated throughout the player's lifetime." },
|
||||
GetXpPercentage = { Params = "", Return = "number", Notes = "Returns the percentage of the experience bar - the amount of XP towards the next XP level. Between 0 and 1." },
|
||||
HasCustomName = { Params = "", Return = "bool", Notes = "Returns true if the player has a custom name." },
|
||||
HasPermission = { Params = "PermissionString", Return = "bool", Notes = "Returns true if the player has the specified permission" },
|
||||
Heal = { Params = "HitPoints", Return = "", Notes = "Heals the player by the specified amount of HPs. Only positive amounts are expected. Sends a health update to the client." },
|
||||
IsEating = { Params = "", Return = "bool", Notes = "Returns true if the player is currently eating the item in their hand." },
|
||||
@ -1774,16 +1834,17 @@ a_Player:OpenWindow(Window);
|
||||
IsFlying = { Return = "bool", Notes = "Returns true if the player is flying." },
|
||||
IsGameModeAdventure = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmAdventure gamemode, or has their gamemode unset and the world is a gmAdventure world." },
|
||||
IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmCreative gamemode, or has their gamemode unset and the world is a gmCreative world." },
|
||||
IsGameModeSpectator = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmSpectator gamemode, or has their gamemode unset and the world is a gmSpectator world." },
|
||||
IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmSurvival gamemode, or has their gamemode unset and the world is a gmSurvival world." },
|
||||
IsInGroup = { Params = "GroupNameString", Return = "bool", Notes = "Returns true if the player is a member of the specified group." },
|
||||
IsInBed = { Params = "", Return = "bool", Notes = "Returns true if the player is currently lying in a bed." },
|
||||
IsOnGround = { Params = "", Return = "bool", Notes = "Returns true if the player is on ground (not falling, not jumping, not flying)" },
|
||||
IsSatiated = { Params = "", Return = "bool", Notes = "Returns true if the player is satiated (cannot eat)." },
|
||||
IsVisible = { Params = "", Return = "bool", Notes = "Returns true if the player is visible to other players" },
|
||||
LoadPermissionsFromDisk = { Params = "", Return = "", Notes = "Reloads the player's permissions from the disk. This loses any temporary changes made to the player's groups." },
|
||||
LoadRank = { Params = "", Return = "", Notes = "Reloads the player's rank, message visuals and permissions from the {{cRankManager}}, based on the player's current rank." },
|
||||
MoveTo = { Params = "{{Vector3d|NewPosition}}", Return = "Tries to move the player into the specified position." },
|
||||
MoveToWorld = { Params = "WorldName", Return = "bool", Return = "Moves the player to the specified world. Returns true if successful." },
|
||||
OpenWindow = { Params = "{{cWindow|Window}}", Return = "", Notes = "Opens the specified UI window for the player." },
|
||||
RemoveFromGroup = { Params = "GroupName", Return = "", Notes = "Temporarily removes the player from the specified group. This change is lost when the player disconnects." },
|
||||
PermissionMatches = { Params = "Permission, Template", Return = "bool", Notes = "(STATIC) Returns true if the specified permission matches the specified template. The template may contain wildcards." },
|
||||
Respawn = { Params = "", Return = "", Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet." },
|
||||
SendMessage = { Params = "Message", Return = "", Notes = "Sends the specified message to the player." },
|
||||
SendMessageFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For a command that failed to run because of insufficient permissions, etc." },
|
||||
@ -1792,9 +1853,12 @@ a_Player:OpenWindow(Window);
|
||||
SendMessagePrivateMsg = { Params = "Message, SenderName", Return = "", Notes = "Prepends Light Blue [MSG: *SenderName*] / prepends SenderName and colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. For private messaging." },
|
||||
SendMessageSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Success notification." },
|
||||
SendMessageWarning = { Params = "Message, Sender", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and sends message to player. Denotes that something concerning, such as plugin reload, is about to happen." },
|
||||
SendRotation = { Params = "YawDegrees, PitchDegrees", Return = "", Notes = "Sends the specified rotation to the player, forcing them to look that way" },
|
||||
SetBedPos = { Params = "{{Vector3i|Position}}", Return = "", Notes = "Sets the internal representation of the last bed position the player has slept in. The player will respawn at this position if they die." },
|
||||
SetCanFly = { Params = "CanFly", Notes = "Sets if the player can fly or not." },
|
||||
SetCrouch = { Params = "IsCrouched", Return = "", Notes = "Sets the crouch state, broadcasts the change to other players." },
|
||||
SetCurrentExperience = { Params = "XPAmount", Return = "", Notes = "Sets the current amount of experience (and indirectly, the XP level)." },
|
||||
SetCustomName = { Params = "string", Return = "", Notes = "Sets the custom name of this player. If you want to disable the custom name, simply set an empty string. The custom name will be used in the tab-list, in the player nametag and in the tab-completion." },
|
||||
SetFlying = { Params = "IsFlying", Notes = "Sets if the player is flying or not." },
|
||||
SetFlyingMaxSpeed = { Params = "FlyingMaxSpeed", Return = "", Notes = "Sets the flying maximum speed, relative to the game default speed. The default value is 1. Sends the updated speed to the client." },
|
||||
SetFoodExhaustionLevel = { Params = "ExhaustionLevel", Return = "", Notes = "Sets the food exhaustion to the specified level." },
|
||||
@ -1808,7 +1872,11 @@ a_Player:OpenWindow(Window);
|
||||
SetNormalMaxSpeed = { Params = "NormalMaxSpeed", Return = "", Notes = "Sets the normal (walking) maximum speed, relative to the game default speed. The default value is 1. Sends the updated speed to the client, if appropriate." },
|
||||
SetSprint = { Params = "IsSprinting", Return = "", Notes = "Sets whether the player is sprinting or not." },
|
||||
SetSprintingMaxSpeed = { Params = "SprintingMaxSpeed", Return = "", Notes = "Sets the sprinting maximum speed, relative to the game default speed. The default value is 1.3. Sends the updated speed to the client, if appropriate." },
|
||||
SetTeam = { Params = "{{cTeam|Team}}", Return = "", Notes = "Moves the player to the specified team." },
|
||||
SetVisible = { Params = "IsVisible", Return = "", Notes = "Sets the player visibility to other players" },
|
||||
TossEquippedItem = { Params = "[Amount]", Return = "", Notes = "Tosses the item that the player has selected in their hotbar. Amount defaults to 1." },
|
||||
TossHeldItem = { Params = "[Amount]", Return = "", Notes = "Tosses the item held by the cursor, then the player is in a UI window. Amount defaults to 1." },
|
||||
TossPickup = { Params = "{{cItem|Item}}", Return = "", Notes = "Tosses a pickup newly created from the specified item." },
|
||||
XpForLevel = { Params = "XPLevel", Return = "number", Notes = "(STATIC) Returns the total amount of XP needed for the specified XP level. Inverse of CalcLevelFromXp()." },
|
||||
},
|
||||
Constants =
|
||||
@ -1870,13 +1938,13 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
},
|
||||
BindCommand =
|
||||
{
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
{ Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split, {{cPlayer|Player}})</pre> The Split parameter contains an array-table of the words that the player has sent, Player is the {{cPlayer}} object representing the player who sent the command. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server sends a warning to the player that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
},
|
||||
BindConsoleCommand =
|
||||
{
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split)</pre> The Split parameter contains an array-table of the words that the admin has typed. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server issues a warning to the console that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
{ Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error. The callback uses the following signature: <pre class=\"prettyprint lang-lua\">function(Split)</pre> The Split parameter contains an array-table of the words that the admin has typed. If the callback returns true, the command is assumed to have executed successfully; in all other cases the server issues a warning to the console that the command is unknown (this is so that subcommands can be implemented)." },
|
||||
},
|
||||
CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." },
|
||||
DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." },
|
||||
@ -1958,6 +2026,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
HOOK_PLAYER_USING_ITEM = { Notes = "Called when the player is about to right-click with a usable item in their hand." },
|
||||
HOOK_POST_CRAFTING = { Notes = "Called after a valid recipe has been chosen for the current contents of the crafting grid. Plugins may modify the recipe." },
|
||||
HOOK_PRE_CRAFTING = { Notes = "Called before a recipe is searched for the current contents of the crafting grid. Plugins may provide a recipe and cancel the built-in search." },
|
||||
HOOK_SERVER_PING = { Notes = "Called when a client pings the server from the server list. Plugins may change the favicon, server description, players online and maximum players values." },
|
||||
HOOK_SPAWNED_ENTITY = { Notes = "Called after an entity is spawned in a {{cWorld|world}}. The entity is already part of the world." },
|
||||
HOOK_SPAWNED_MONSTER = { Notes = "Called after a mob is spawned in a {{cWorld|world}}. The mob is already part of the world." },
|
||||
HOOK_SPAWNING_ENTITY = { Notes = "Called just before an entity is spawned in a {{cWorld|world}}." },
|
||||
@ -1972,6 +2041,74 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
},
|
||||
}, -- cPluginManager
|
||||
|
||||
cRankManager =
|
||||
{
|
||||
Desc = [[
|
||||
Manages the players' permissions. The players are assigned a single rank, which contains groups of
|
||||
permissions. The functions in this class query or modify these.</p>
|
||||
<p>
|
||||
All the functions are static, call them using the <code>cRankManager:Function()</code> convention.</p>
|
||||
<p>
|
||||
The players are identified by their UUID, to support player renaming.</p>
|
||||
<p>
|
||||
The rank also contains specific "mesage visuals" - bits that are used for formatting messages from the
|
||||
players. There's a message prefix, which is put in front of every message the player sends, and the
|
||||
message suffix that is appended to each message. There's also a PlayerNameColorCode, which holds the
|
||||
color that is used for the player's name in the messages.</p>
|
||||
<p>
|
||||
Each rank can contain any number of permission groups. These groups allow for an easier setup of the
|
||||
permissions - you can share groups among ranks, so the usual approach is to group similar permissions
|
||||
together and add that group to any rank that should use those permissions.</p>
|
||||
<p>
|
||||
Permissions are added to individual groups. Each group can support unlimited permissions. Note that
|
||||
adding a permission to a group will make the permission available to all the ranks that contain that
|
||||
permission group.</p>
|
||||
<p>
|
||||
One rank is reserved as the Default rank. All players that don't have an explicit rank assigned to them
|
||||
will behave as if assigned to this rank. The default rank can be changed to any other rank at any time.
|
||||
Note that the default rank cannot be removed from the RankManager - RemoveRank() will change the default
|
||||
rank to the replacement rank, if specified, and fail if no replacement rank is specified. Renaming the
|
||||
default rank using RenameRank() will change the default rank to the new name.
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
AddGroup = { Params = "GroupName", Return = "", Notes = "Adds the group of the specified name. Logs a warning and does nothing if the group already exists." },
|
||||
AddGroupToRank = { Params = "GroupName, RankName", Return = "bool", Notes = "Adds the specified group to the specified rank. Returns true on success, false on failure - if the group name or the rank name is not found." },
|
||||
AddPermissionToGroup = { Params = "Permission, GroupName", Return = "bool", Notes = "Adds the specified permission to the specified group. Returns true on success, false on failure - if the group name is not found." },
|
||||
AddRank = { Params = "RankName, MsgPrefix, MsgSuffix, MsgNameColorCode", Return = "", Notes = "Adds a new rank of the specified name and with the specified message visuals. Logs an info message and does nothing if the rank already exists." },
|
||||
ClearPlayerRanks = { Params = "", Return = "", Notes = "Removes all player ranks from the database. Note that this doesn't change the cPlayer instances for the already connected players, you need to update all the instances manually." },
|
||||
GetAllGroups = { Params = "", Return = "array-table of groups' names", Notes = "Returns an array-table containing the names of all the groups that are known to the manager." },
|
||||
GetAllPermissions = { Params = "", Return = "array-table of permissions", Notes = "Returns an array-table containing all the permissions that are known to the manager." },
|
||||
GetAllPlayerUUIDs = { Params = "", Return = "array-table of uuids", Notes = "Returns the short uuids of all players stored in the rank DB, sorted by the players' names (case insensitive)." },
|
||||
GetAllRanks = { Params = "", Return = "array-table of ranks' names", Notes = "Returns an array-table containing the names of all the ranks that are known to the manager." },
|
||||
GetDefaultRank = { Params = "", Return = "string", Notes = "Returns the name of the default rank. " },
|
||||
GetGroupPermissions = { Params = "GroupName", Return = "array-table of permissions", Notes = "Returns an array-table containing the permissions that the specified group contains." },
|
||||
GetPlayerGroups = { Params = "PlayerUUID", Return = "array-table of groups' names", Notes = "Returns an array-table of the names of the groups that are assigned to the specified player through their rank. Returns an empty table if the player is not known or has no rank or groups assigned to them." },
|
||||
GetPlayerMsgVisuals = { Params = "PlayerUUID", Return = "MsgPrefix, MsgSuffix, MsgNameColorCode", Notes = "Returns the message visuals assigned to the player. If the player is not explicitly assigned a rank, the default rank's visuals are returned. If there is an error, no value is returned at all." },
|
||||
GetPlayerPermissions = { Params = "PlayerUUID", Return = "array-table of permissions", Notes = "Returns the permissions that the specified player is assigned through their rank. Returns the default rank's permissions if the player has no explicit rank assigned to them. Returns an empty array on error." },
|
||||
GetPlayerRankName = { Params = "PlayerUUID", Return = "RankName", Notes = "Returns the name of the rank that is assigned to the specified player. An empty string (NOT the default rank) is returned if the player has no rank assigned to them." },
|
||||
GetPlayerName = { Params = "PlayerUUID", Return = "PlayerName", Notes = "Returns the last name that the specified player has, for a player in the ranks database. An empty string is returned if the player isn't in the database." },
|
||||
GetRankGroups = { Params = "RankName", Return = "array-table of groups' names", Notes = "Returns an array-table of the names of all the groups that are assigned to the specified rank. Returns an empty table if there is no such rank." },
|
||||
GetRankPermissions = { Params = "RankName", Return = "array-table of permissions", Notes = "Returns an array-table of all the permissions that are assigned to the specified rank through its groups. Returns an empty table if there is no such rank." },
|
||||
GetRankVisuals = { Params = "RankName", Return = "MsgPrefix, MsgSuffix, MsgNameColorCode", Notes = "Returns the message visuals for the specified rank. Returns no value if the specified rank does not exist." },
|
||||
GroupExists = { Params = "GroupName", Return = "bool", Notes = "Returns true iff the specified group exists." },
|
||||
IsGroupInRank = { Params = "GroupName, RankName", Return = "bool", Notes = "Returns true iff the specified group is assigned to the specified rank." },
|
||||
IsPermissionInGroup = { Params = "Permission, GroupName", Return = "bool", Notes = "Returns true iff the specified permission is assigned to the specified group." },
|
||||
IsPlayerRankSet = { Params = "PlayerUUID", Return = "bool", Notes = "Returns true iff the specified player has a rank assigned to them." },
|
||||
RankExists = { Params = "RankName", Return = "bool", Notes = "Returns true iff the specified rank exists." },
|
||||
RemoveGroup = { Params = "GroupName", Return = "", Notes = "Removes the specified group completely. The group will be removed from all the ranks using it and then erased from the manager. Logs an info message and does nothing if the group doesn't exist." },
|
||||
RemoveGroupFromRank = { Params = "GroupName, RankName", Return = "", Notes = "Removes the specified group from the specified rank. The group will still exist, even if it isn't assigned to any rank. Logs an info message and does nothing if the group or rank doesn't exist." },
|
||||
RemovePermissionFromGroup = { Params = "Permission, GroupName", Return = "", Notes = "Removes the specified permission from the specified group. Logs an info message and does nothing if the group doesn't exist." },
|
||||
RemovePlayerRank = { Params = "PlayerUUID", Return = "", Notes = "Removes the player's rank; the player's left without a rank. Note that this doesn't change the {{cPlayer}} instances for the already connected players, you need to update all the instances manually. No action if the player has no rank assigned to them already." },
|
||||
RemoveRank = { Params = "RankName, [ReplacementRankName]", Return = "", Notes = "Removes the specified rank. If ReplacementRankName is given, the players that have RankName will get their rank set to ReplacementRankName. If it isn't given, or is an invalid rank, the players will be removed from the manager, their ranks will be unset completely. Logs an info message and does nothing if the rank is not found." },
|
||||
RenameGroup = { Params = "OldName, NewName", Return = "", Notes = "Renames the specified group. Logs an info message and does nothing if the group is not found or the new name is already used." },
|
||||
RenameRank = { Params = "OldName, NewName", Return = "", Notes = "Renames the specified rank. Logs an info message and does nothing if the rank is not found or the new name is already used." },
|
||||
SetDefaultRank = { Params = "RankName", Return = "bool", Notes = "Sets the specified rank as the default rank. Returns true on success, false on failure (rank doesn't exist)." },
|
||||
SetPlayerRank = { Params = "PlayerUUID, PlayerName, RankName", Return = "", Notes = "Updates the rank for the specified player. The player name is provided for reference, the UUID is used for identification. Logs a warning and does nothing if the rank is not found." },
|
||||
SetRankVisuals = { Params = "RankName, MsgPrefix, MsgSuffix, MsgNameColorCode", Return = "", Notes = "Updates the rank's message visuals. Logs an info message and does nothing if rank not found." },
|
||||
},
|
||||
}, -- cRankManager
|
||||
|
||||
cRoot =
|
||||
{
|
||||
Desc = [[
|
||||
@ -1985,22 +2122,28 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
|
||||
]],
|
||||
Functions =
|
||||
{
|
||||
Get = { Params = "", Return = "Root object", Notes = "(STATIC)This function returns the cRoot object." },
|
||||
BroadcastChat = { Params = "Message", Return = "", Notes = "Broadcasts a message to every player in the server. No formatting is done by the server." },
|
||||
BroadcastChatFailure = { Params = "Message", Return = "", Notes = "Prepends Rose [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a command that failed to run because of insufficient permissions, etc." },
|
||||
BroadcastChatFatal = { Params = "Message", Return = "", Notes = "Prepends Red [FATAL] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For a plugin that crashed, or similar." },
|
||||
BroadcastChatInfo = { Params = "Message", Return = "", Notes = "Prepends Yellow [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For informational messages, such as command usage." },
|
||||
BroadcastChatSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." },
|
||||
BroadcastChatWarning = { Params = "Message", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." },
|
||||
CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil." },
|
||||
BroadcastChat =
|
||||
{
|
||||
{ Params = "MessageText, MessageType", Return = "", Notes = "Broadcasts a message to all players, with its message type set to MessageType (default: mtCustom)." },
|
||||
{ Params = "{{cCompositeChat|CompositeChat}}", Return = "", Notes = "Broadcasts a {{cCompositeChat|composite chat message} to all players." },
|
||||
},
|
||||
BroadcastChatDeath = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtDeath. Use for when a player has died." },
|
||||
BroadcastChatFailure = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtFailure. Use for a command that failed to run because of insufficient permissions, etc." },
|
||||
BroadcastChatFatal = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtFatal. Use for a plugin that crashed, or similar." },
|
||||
BroadcastChatInfo = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtInfo. Use for informational messages, such as command usage." },
|
||||
BroadcastChatJoin = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtJoin. Use for players joining the server." },
|
||||
BroadcastChatLeave = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtLeave. Use for players leaving the server." },
|
||||
BroadcastChatSuccess = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtSuccess. Use for success messages." },
|
||||
BroadcastChatWarning = { Params = "MessageText", Return = "", Notes = "Broadcasts the specified message to all players, with its message type set to mtWarning. Use for concerning events, such as plugin reload etc." },
|
||||
CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil.<br/><br/><b>NOTE</b>This function is currently unsafe, do not use!" },
|
||||
FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for all players with names partially (or fully) matching the name string provided." },
|
||||
ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|cPlayer}})</pre>" },
|
||||
ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cWorld|cWorld}})</pre>" },
|
||||
Get = { Params = "", Return = "Root object", Notes = "(STATIC)This function returns the cRoot object." },
|
||||
GetCraftingRecipes = { Params = "", Return = "{{cCraftingRecipe|cCraftingRecipe}}", Notes = "Returns the CraftingRecipes object" },
|
||||
GetDefaultWorld = { Params = "", Return = "{{cWorld|cWorld}}", Notes = "Returns the world object from the default world." },
|
||||
GetFurnaceFuelBurnTime = { Params = "{{cItem|Fuel}}", Return = "number", Notes = "(STATIC) Returns the number of ticks for how long the item would fuel a furnace. Returns zero if not a fuel." },
|
||||
GetFurnaceRecipe = { Params = "{{cItem|InItem}}", Return = "{{cItem|OutItem}}, NumTicks, {{cItem|InItem}}", Notes = "(STATIC) Returns the furnace recipe for smelting the specified input. If a recipe is found, returns the smelted result, the number of ticks required for the smelting operation, and the input consumed (note that MCServer supports smelting M items into N items and different smelting rates). If no recipe is found, returns no value." },
|
||||
GetGroupManager = { Params = "", Return = "{{cGroupManager|cGroupManager}}", Notes = "Returns the cGroupManager object." },
|
||||
GetPhysicalRAMUsage = { Params = "", Return = "number", Notes = "Returns the amount of physical RAM that the entire MCServer process is using, in KiB. Negative if the OS doesn't support this query." },
|
||||
GetPluginManager = { Params = "", Return = "{{cPluginManager|cPluginManager}}", Notes = "Returns the cPluginManager object." },
|
||||
GetPrimaryServerVersion = { Params = "", Return = "number", Notes = "Returns the servers primary server version." },
|
||||
@ -2084,10 +2227,11 @@ end
|
||||
{
|
||||
GetDescription = { Return = "string", Notes = "Returns the server description set in the settings.ini." },
|
||||
GetMaxPlayers = { Return = "number", Notes = "Returns the max amount of players who can join the server." },
|
||||
SetMaxPlayers = { Params = "number", Notes = "Sets the max amount of players who can join." },
|
||||
GetNumPlayers = { Return = "number", Notes = "Returns the amount of players online." },
|
||||
GetServerID = { Return = "string", Notes = "Returns the ID of the server?" },
|
||||
IsHardcore = { Params = "", Return = "bool", Notes = "Returns true if the server is hardcore (players get banned on death)." },
|
||||
SetMaxPlayers = { Params = "number", Notes = "Sets the max amount of players who can join." },
|
||||
ShouldAuthenticate = { Params = "", Return = "bool", Notes = "Returns true iff the server is set to authenticate players (\"online mode\")." },
|
||||
},
|
||||
}, -- cServer
|
||||
|
||||
@ -2244,6 +2388,7 @@ end
|
||||
DigBlock = { Params = "X, Y, Z", Return = "", Notes = "Replaces the specified block with air, without dropping the usual pickups for the block. Wakes up the simulators for the block and its neighbors." },
|
||||
DoExplosionAt = { Params = "Force, X, Y, Z, CanCauseFire, Source, SourceData", Return = "", Notes = "Creates an explosion of the specified relative force in the specified position. If CanCauseFire is set, the explosion will set blocks on fire, too. The Source parameter specifies the source of the explosion, one of the esXXX constants. The SourceData parameter is specific to each source type, usually it provides more info about the source." },
|
||||
DoWithBlockEntityAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a block entity at the specified coords, calls the CallbackFunction with the {{cBlockEntity}} parameter representing the block entity. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBlockEntity|BlockEntity}}, [CallbackData])</pre> The function returns false if there is no block entity, or if there is, it returns the bool value that the callback has returned. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." },
|
||||
DoWithBeaconAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a beacon at the specified coords, calls the CallbackFunction with the {{cBeaconEntity}} parameter representing the beacon. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBeaconEntity|BeaconEntity}}, [CallbackData])</pre> The function returns false if there is no beacon, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithChestAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a chest at the specified coords, calls the CallbackFunction with the {{cChestEntity}} parameter representing the chest. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cChestEntity|ChestEntity}}, [CallbackData])</pre> The function returns false if there is no chest, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithCommandBlockAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a command block at the specified coords, calls the CallbackFunction with the {{cCommandBlockEntity}} parameter representing the command block. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cCommandBlockEntity|CommandBlockEntity}}, [CallbackData])</pre> The function returns false if there is no command block, or if there is, it returns the bool value that the callback has returned." },
|
||||
DoWithDispenserAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a dispenser at the specified coords, calls the CallbackFunction with the {{cDispenserEntity}} parameter representing the dispenser. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cDispenserEntity|DispenserEntity}}, [CallbackData])</pre> The function returns false if there is no dispenser, or if there is, it returns the bool value that the callback has returned." },
|
||||
@ -2264,6 +2409,7 @@ end
|
||||
ForEachBlockEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each block entity in the chunk. Returns true if all block entities in the chunk have been processed (including when there are zero block entities), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cBlockEntity|BlockEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next block entity, or true to abort the enumeration. Use {{tolua}}.cast() to cast the Callback's BlockEntity parameter to the correct {{cBlockEntity}} descendant." },
|
||||
ForEachChestInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each chest in the chunk. Returns true if all chests in the chunk have been processed (including when there are zero chests), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cChestEntity|ChestEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next chest, or true to abort the enumeration." },
|
||||
ForEachEntity = { Params = "CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each entity in the loaded world. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
ForEachEntityInBox = { Params = "{{cBoundingBox|Box}}, CallbackFunction", Return = "bool", Notes = "Calls the specified callback for each entity in the specified bounding box. Returns true if all the entities have been processed (including when there are zero entities), or false if the callback function has aborted the enumeration by returning true. If any chunk within the bounding box is not valid, it is silently skipped without any notification. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}})</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
ForEachEntityInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each entity in the specified chunk. Returns true if all the entities have been processed (including when there are zero entities), or false if the chunk is not loaded or the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cEntity|Entity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next entity, or true to abort the enumeration." },
|
||||
ForEachFurnaceInChunk = { Params = "ChunkX, ChunkZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each furnace in the chunk. Returns true if all furnaces in the chunk have been processed (including when there are zero furnaces), or false if the callback has aborted the enumeration by returning true. The CallbackFunction has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cFurnaceEntity|FurnaceEntity}}, [CallbackData])</pre> The callback should return false or no value to continue with the next furnace, or true to abort the enumeration." },
|
||||
ForEachPlayer = { Params = "CallbackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each player in the loaded world. Returns true if all the players have been processed (including when there are zero players), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature: <pre class=\"prettyprint lang-lua\">function Callback({{cPlayer|Player}}, [CallbackData])</pre> The callback should return false or no value to continue with the next player, or true to abort the enumeration." },
|
||||
@ -2494,8 +2640,8 @@ World:ForEachEntity(
|
||||
The following code snippet checks if the player holds a shovel.
|
||||
<pre class="prettyprint lang-lua">
|
||||
-- a_Player is a {{cPlayer}} object, possibly received as a hook param
|
||||
local HeldItem = a_Player:GetEquippedItem();
|
||||
if (cItemCategory:IsShovel(HeldItem.m_ItemType)) then
|
||||
local HeldItem = a_Player:GetEquippedItem()
|
||||
if (ItemCategory.IsShovel(HeldItem.m_ItemType)) then
|
||||
-- It's a shovel
|
||||
end
|
||||
</pre>
|
||||
@ -2721,7 +2867,7 @@ end
|
||||
Globals =
|
||||
{
|
||||
Desc = [[
|
||||
These functions are available directly, without a class instance. Any plugin cal call them at any
|
||||
These functions are available directly, without a class instance. Any plugin can call them at any
|
||||
time.
|
||||
]],
|
||||
Functions =
|
||||
@ -2729,6 +2875,7 @@ end
|
||||
AddFaceDirection = {Params = "BlockX, BlockY, BlockZ, BlockFace, [IsInverse]", Return = "BlockX, BlockY, BlockZ", Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFaces|face}}"},
|
||||
BlockFaceToString = {Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "string", Notes = "Returns the string representation of the {{Globals#BlockFaces|eBlockFace}} constant. Uses the axis-direction-based names, such as BLOCK_FACE_XP." },
|
||||
BlockStringToType = {Params = "BlockTypeString", Return = "BLOCKTYPE", Notes = "Returns the block type parsed from the given string"},
|
||||
Clamp = {Params = "Number, Min, Max", Return = "number", Notes = "Clamp the number to the specified range."},
|
||||
ClickActionToString = {Params = "{{Globals#ClickAction|ClickAction}}", Return = "string", Notes = "Returns a string description of the ClickAction enumerated value"},
|
||||
DamageTypeToString = {Params = "{{Globals#DamageType|DamageType}}", Return = "string", Notes = "Converts the {{Globals#DamageType|DamageType}} enumerated value to a string representation "},
|
||||
EscapeString = {Params = "string", Return = "string", Notes = "Returns a copy of the string with all quotes and backslashes escaped by a backslash"},
|
||||
@ -2769,7 +2916,7 @@ end
|
||||
MirrorBlockFaceY = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after mirroring it around the Y axis (or rotating 180 degrees around it)." },
|
||||
NoCaseCompare = {Params = "string, string", Return = "number", Notes = "Case-insensitive string comparison; returns 0 if the strings are the same"},
|
||||
NormalizeAngleDegrees = { Params = "AngleDegrees", Return = "AngleDegrees", Notes = "Returns the angle, wrapped into the [-180, +180) range." },
|
||||
ReplaceString = {Params = "full-string, to-be-replaced-string, to-replace-string", Notes = "Replaces *each* occurence of to-be-replaced-string in full-string with to-replace-string"},
|
||||
ReplaceString = {Params = "full-string, to-be-replaced-string, to-replace-string", Return = "string", Notes = "Replaces *each* occurence of to-be-replaced-string in full-string with to-replace-string"},
|
||||
RotateBlockFaceCCW = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after rotating it around the Y axis 90 degrees counter-clockwise." },
|
||||
RotateBlockFaceCW = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after rotating it around the Y axis 90 degrees clockwise." },
|
||||
StringSplit = {Params = "string, SeperatorsString", Return = "array table of strings", Notes = "Seperates string into multiple by splitting every time any of the characters in SeperatorsString is encountered."},
|
||||
|
@ -50,6 +50,32 @@ return
|
||||
},
|
||||
},
|
||||
|
||||
cBeaconEntity =
|
||||
{
|
||||
Desc = [[
|
||||
A beacon entity is a {{cBlockEntityWithItems|cBlockEntityWithItems}} descendant that represents a beacon
|
||||
in the world.
|
||||
]],
|
||||
|
||||
Inherits = "cBlockEntityWithItems",
|
||||
|
||||
Functions =
|
||||
{
|
||||
IsActive = { Params = "", Return = "bool", Notes = "Is the beacon active?" },
|
||||
GetBeaconLevel = { Params = "", Return = "number", Notes = "Returns the beacon level. (0 - 4)" },
|
||||
GetPrimaryEffect = { Params = "", Return = "EffectType", Notes = "Returns the primary effect." },
|
||||
GetSecondaryEffect = { Params = "", Return = "EffectType", Notes = "Returns the secondary effect." },
|
||||
SetPrimaryEffect = { Params = "EffectType", Return = "bool", Notes = "Select the primary effect. Returns false when the effect is invalid." },
|
||||
SetSecondaryEffect = { Params = "EffectType", Return = "bool", Notes = "Select the secondary effect. Returns false when the effect is invalid." },
|
||||
CalculatePyramidLevel = { Params = "", Return = "number", Notes = "Calculate the amount of layers the pyramid below the beacon has." },
|
||||
IsBeaconBlocked = { Params = "", Return = "bool", Notes = "Is the beacon blocked by non-transparent blocks that are higher than the beacon?" },
|
||||
UpdateBeacon = { Params = "", Return = "", Notes = "Update the beacon." },
|
||||
GiveEffects = { Params = "", Return = "", Notes = "Give the near-players the effects." },
|
||||
IsMineralBlock = { Params = "BLOCKTYPE", Return = "bool", Notes = "Returns true if the block is a diamond block, a golden block, an iron block or an emerald block." },
|
||||
IsValidEffect = { Params = "EffectType", Return = "bool", Notes = "Returns true if the effect can be used." },
|
||||
},
|
||||
},
|
||||
|
||||
cChestEntity =
|
||||
{
|
||||
Desc = [[
|
||||
|
@ -11,9 +11,11 @@ return
|
||||
Params =
|
||||
{
|
||||
{ Name = "Player", Type = "{{cPlayer}}", Notes = "The player who has moved. The object already has the new position stored in it." },
|
||||
{ Name = "OldPosition", Type = "{{Vector3d}}", Notes = "The old position." },
|
||||
{ Name = "NewPosition", Type = "{{Vector3d}}", Notes = "The new position." },
|
||||
},
|
||||
Returns = [[
|
||||
If the function returns true, movement is prohibited. FIXME: The player's client is not informed.</p>
|
||||
If the function returns true, movement is prohibited.</p>
|
||||
<p>
|
||||
If the function returns false or no value, other plugins' callbacks are called and finally the new
|
||||
position is permanently stored in the cPlayer object.</p>
|
||||
|
50
MCServer/Plugins/APIDump/Hooks/OnServerPing.lua
Normal file
50
MCServer/Plugins/APIDump/Hooks/OnServerPing.lua
Normal file
@ -0,0 +1,50 @@
|
||||
return
|
||||
{
|
||||
HOOK_SERVER_PING =
|
||||
{
|
||||
CalledWhen = "Client pings the server from the server list.",
|
||||
DefaultFnName = "OnServerPing", -- also used as pagename
|
||||
Desc = [[
|
||||
A plugin may implement an OnServerPing() function and register it as a Hook to process pings from
|
||||
clients in the server server list. It can change the logged in players and player capacity, as well
|
||||
as the server description and the favicon, that are displayed to the client in the server list.
|
||||
]],
|
||||
Params = {
|
||||
{ Name = "ClientHandle", Type = "{{cClientHandle}}", Notes = "The client handle that pinged the server" },
|
||||
{ Name = "ServerDescription", Type = "string", Notes = "The server description" },
|
||||
{ Name = "OnlinePlayersCount", Type = "number", Notes = "The number of players currently on the server" },
|
||||
{ Name = "MaxPlayersCount", Type = "number", Notes = "The current player cap for the server" },
|
||||
{ Name = "Favicon", Type = "string", Notes = "The base64 encoded favicon to be displayed in the server list for compatible clients" },
|
||||
},
|
||||
Returns = [[
|
||||
The plugin can return whether to continue processing of the hook with other plugins, the server description to
|
||||
be displayed to the client, the currently online players, the player cap and the base64/png favicon data, in that order.
|
||||
]],
|
||||
CodeExamples = {
|
||||
{
|
||||
Title = "Change information returned to the player",
|
||||
Desc = "Tells the client that the server description is 'test', there are one more players online than there actually are, and that the player cap is zero. It also changes the favicon data.",
|
||||
Code = [[
|
||||
function OnServerPing(ClientHandle, ServerDescription, OnlinePlayers, MaxPlayers, Favicon)
|
||||
-- Change Server Description
|
||||
ServerDescription = "Test"
|
||||
|
||||
-- Change online / max players
|
||||
OnlinePlayers = OnlinePlayers + 1
|
||||
MaxPlayers = 0
|
||||
|
||||
-- Change favicon
|
||||
if cFile:IsFile("my-favicon.png") then
|
||||
local FaviconData = cFile:ReadWholeFile("my-favicon.png")
|
||||
if (FaviconData ~= "") and (FaviconData ~= nil) then
|
||||
Favicon = Base64Encode(FaviconData)
|
||||
end
|
||||
end
|
||||
|
||||
return false, ServerDescription, OnlinePlayers, MaxPlayers, Favicon
|
||||
end
|
||||
]],
|
||||
},
|
||||
},
|
||||
}, -- HOOK_SERVER_PING
|
||||
}
|
@ -6,8 +6,9 @@ return
|
||||
DefaultFnName = "OnSpawningEntity", -- also used as pagename
|
||||
Desc = [[
|
||||
This hook is called before the server spawns an {{cEntity|entity}}. The plugin can either modify the
|
||||
entity before it is spawned, or disable the spawning altogether. If the entity spawning is a
|
||||
monster, the {{OnSpawningMonster|HOOK_SPAWNING_MONSTER}} hook is called before this hook.</p>
|
||||
entity before it is spawned, or disable the spawning altogether. You can't disable the spawning if the
|
||||
entity is a player. If the entity spawning is a monster, the {{OnSpawningMonster|HOOK_SPAWNING_MONSTER}}
|
||||
hook is called before this hook.</p>
|
||||
<p>
|
||||
See also the {{OnSpawnedEntity|HOOK_SPAWNED_ENTITY}} hook for a similar hook called after the
|
||||
entity is spawned.
|
||||
|
@ -202,7 +202,7 @@ function Explode(Split, Player)
|
||||
if (#Split ~= 2) then
|
||||
-- There was more or less than one argument (excluding the "/explode" bit)
|
||||
-- Send the proper usage to the player and exit
|
||||
SendMessage(Player, "Usage: /explode [playername]")
|
||||
Player:SendMessage("Usage: /explode [playername]")
|
||||
return true
|
||||
end
|
||||
|
||||
@ -213,7 +213,7 @@ function Explode(Split, Player)
|
||||
if (Explodee:GetName() == Split[2]) then
|
||||
-- Create an explosion at the same position as they are; see <a href="cWorld.html">API docs</a> for further details of this function
|
||||
Player:GetWorld():DoExplosionAt(Explodee:GetPosX(), Explodee:GetPosY(), Explodee:GetPosZ(), false, esPlugin)
|
||||
SendMessageSuccess(Player, Split[2] .. " was successfully exploded")
|
||||
Player:SendMessageSuccess(Split[2] .. " was successfully exploded")
|
||||
HasExploded = true;
|
||||
return true -- Signalize to MCS that we do not need to call this callback for any more players
|
||||
end
|
||||
@ -224,7 +224,7 @@ function Explode(Split, Player)
|
||||
|
||||
if not(HasExploded) then
|
||||
-- We have not broken out so far, therefore, the player must not exist, send failure
|
||||
SendMessageFailure(Player, Split[2] .. " was not found")
|
||||
Player:SendMessageFailure(Split[2] .. " was not found")
|
||||
end
|
||||
|
||||
return true
|
||||
|
1
MCServer/Plugins/ChatLog
Submodule
1
MCServer/Plugins/ChatLog
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 983d23ca37baa89f7e4dc11d71502d9c059f6376
|
@ -1,31 +0,0 @@
|
||||
|
||||
-- plugin.lua
|
||||
|
||||
-- Implements the main entrypoint for the plugin, as well as all the handling needed
|
||||
|
||||
-- ChatLog plugin logs all chat messages into the server log
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
Plugin:SetName("ChatLog")
|
||||
Plugin:SetVersion(3)
|
||||
|
||||
cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChat)
|
||||
|
||||
LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion())
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnChat(Player, Message)
|
||||
-- Lets get loggin'
|
||||
LOGINFO("[" .. Player:GetName() .. "]: " .. StripColorCodes(Message));
|
||||
|
||||
return false
|
||||
end
|
1
MCServer/Plugins/ChunkWorx
Submodule
1
MCServer/Plugins/ChunkWorx
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 894c7e32049e9d2a1e736f7d721aaacd1ae29e53
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project>
|
||||
<file>
|
||||
<filename>chunkworx_main.lua</filename>
|
||||
</file>
|
||||
<file>
|
||||
<filename>chunkworx_web.lua</filename>
|
||||
</file>
|
||||
</project>
|
@ -1,128 +0,0 @@
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
GENERATION_STATE = 0
|
||||
OPERATION_CODE = 0 -- 0 = generation
|
||||
CX = 0
|
||||
CZ = 0
|
||||
CURRENT = 0
|
||||
TOTAL = 0
|
||||
|
||||
-- AREA Variables
|
||||
AreaStartX = -10
|
||||
AreaStartZ = -10
|
||||
AreaEndX = 10
|
||||
AreaEndZ = 10
|
||||
|
||||
-- RADIAL Variables
|
||||
RadialX = 0
|
||||
RadialZ = 0
|
||||
Radius = 10
|
||||
|
||||
-- WORLD
|
||||
WORK_WORLD = cRoot:Get():GetDefaultWorld():GetName()
|
||||
WW_instance = cRoot:Get():GetDefaultWorld()
|
||||
WORLDS = {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin
|
||||
|
||||
PLUGIN:SetName("ChunkWorx")
|
||||
PLUGIN:SetVersion(6)
|
||||
|
||||
cPluginManager.AddHook(cPluginManager.HOOK_TICK, OnTick)
|
||||
|
||||
Plugin:AddWebTab("(Re)Generation", HandleRequest_Generation)
|
||||
|
||||
GENERATION_STATE = 0
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
if (WW_instance == nil) then
|
||||
LOG("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": NO WORLD found :(")
|
||||
end
|
||||
|
||||
-- Read the stored values:
|
||||
local SettingsIni = cIniFile();
|
||||
SettingsIni:ReadFile("ChunkWorx.ini"); -- ignore any read errors
|
||||
AreaStartX = SettingsIni:GetValueSetI("Area data", "StartX", AreaStartX)
|
||||
AreaStartZ = SettingsIni:GetValueSetI("Area data", "StartZ", AreaStartZ)
|
||||
AreaEndX = SettingsIni:GetValueSetI("Area data", "EndX", AreaEndX)
|
||||
AreaEndZ = SettingsIni:GetValueSetI("Area data", "EndZ", AreaEndZ)
|
||||
RadialX = SettingsIni:GetValueSetI("Radial data", "RadialX", RadialX)
|
||||
RadialZ = SettingsIni:GetValueSetI("Radial data", "RadialZ", RadialZ)
|
||||
Radius = SettingsIni:GetValueSetI("Radial data", "Radius", Radius)
|
||||
SettingsIni:WriteFile("ChunkWorx.ini");
|
||||
|
||||
LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnTick( DeltaTime )
|
||||
if (GENERATION_STATE == 1 or GENERATION_STATE == 3) then
|
||||
LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works STARTED!")
|
||||
LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": At world: " .. WORK_WORLD)
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
if (GENERATION_STATE == 1) then GENERATION_STATE = 2 end
|
||||
if (GENERATION_STATE == 3) then GENERATION_STATE = 4 end
|
||||
|
||||
-- Changing in case coordinates are flipped
|
||||
local shifter = AreaEndX
|
||||
if (AreaStartX > AreaEndX) then
|
||||
AreaEndX = AreaStartX
|
||||
AreaStartX = shifter
|
||||
end
|
||||
shifter = AreaEndZ
|
||||
if (AreaStartZ > AreaEndZ) then
|
||||
AreaEndZ = AreaStartZ
|
||||
AreaStartZ = shifter
|
||||
end
|
||||
|
||||
CX = AreaStartX
|
||||
CZ = AreaStartZ
|
||||
CURRENT = 0
|
||||
|
||||
if (WW_instance == nil) then
|
||||
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED")
|
||||
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": NO WORLD found :(")
|
||||
GENERATION_STATE = 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
|
||||
if (WW_instance:GetGeneratorQueueLength() < 200
|
||||
and WW_instance:GetLightingQueueLength() < 200
|
||||
and (WW_instance:GetStorageSaveQueueLength() + WW_instance:GetStorageLoadQueueLength()) < 80) then
|
||||
local chunk_sum = (1+ AreaEndX - AreaStartX) * (1+ AreaEndZ - AreaStartZ)
|
||||
TOTAL = chunk_sum
|
||||
LOG("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": PROCESSING 100 chunks, (" .. CURRENT .. "/" .. chunk_sum .. ")")
|
||||
for C = 1, 100 do
|
||||
if (GENERATION_STATE == 2) then WW_instance:GenerateChunk(CX, CZ) end
|
||||
if (GENERATION_STATE == 4) then WW_instance:RegenerateChunk(CX, CZ) end
|
||||
|
||||
CX = CX + 1
|
||||
CURRENT = CURRENT + 1
|
||||
if (CX > AreaEndX) then
|
||||
CX = AreaStartX
|
||||
CZ = CZ + 1
|
||||
if (CZ > AreaEndZ) then
|
||||
if (GENERATION_STATE == 2) then LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " - generation ENDED!") end
|
||||
if (GENERATION_STATE == 4) then LOGINFO("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " - REgeneration ENDED!") end
|
||||
|
||||
GENERATION_STATE = 0
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
WW_instance:QueueSaveAllChunks()
|
||||
WW_instance:QueueUnloadUnusedChunks()
|
||||
end
|
||||
end
|
||||
end
|
@ -1,274 +0,0 @@
|
||||
|
||||
-- chunkworx_web.lua
|
||||
|
||||
-- WebAdmin-related functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function Buttons_Player( Name )
|
||||
return "<form method='POST'><input type='hidden' name='PlayerName' value='"..Name.."'><input type='submit' name='PlayerExact' value='Exact'><input type='submit' name='Player3x3' value='3x3'></form>"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function Button_World( Name )
|
||||
return "<form method='POST'><input type='hidden' name='WorldName' value='"..Name.."'><input type='submit' name='SelectWorld' value='Select'></form>"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local function SaveSettings()
|
||||
local SettingsIni = cIniFile()
|
||||
SettingsIni:SetValueI("Area data", "StartX", AreaStartX)
|
||||
SettingsIni:SetValueI("Area data", "StartZ", AreaStartZ)
|
||||
SettingsIni:SetValueI("Area data", "EndX", AreaEndX)
|
||||
SettingsIni:SetValueI("Area data", "EndZ", AreaEndZ)
|
||||
SettingsIni:SetValueI("Radial data", "RadialX", RadialX)
|
||||
SettingsIni:SetValueI("Radial data", "RadialZ", RadialZ)
|
||||
SettingsIni:SetValueI("Radial data", "Radius", Radius)
|
||||
SettingsIni:WriteFile("ChunkWorx.ini")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleRequest_Generation( Request )
|
||||
local Content = ""
|
||||
if (Request.PostParams["AGHRRRR"] ~= nil) then
|
||||
GENERATION_STATE = 0
|
||||
WW_instance:QueueSaveAllChunks()
|
||||
WW_instance:QueueUnloadUnusedChunks()
|
||||
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin")
|
||||
end
|
||||
--Content = Content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
|
||||
-- PROCESSING
|
||||
--------------------------------------------------------------------------------------------------
|
||||
local function ProcessingContent()
|
||||
local _small_content = ""
|
||||
_small_content = _small_content .. "<head><meta http-equiv=\"refresh\" content=\"2;\"></head>"
|
||||
_small_content = _small_content .. "<h4>World for operations:</h4>"..WORK_WORLD
|
||||
if (OPERATION_CODE == 0) then
|
||||
_small_content = _small_content .. "<h4>Operation:</h4>Generation"
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
_small_content = _small_content .. "<h4>Operation:</h4>Regeneration"
|
||||
end
|
||||
_small_content = _small_content .. "<h4>Area: </h4>["..AreaStartX..":"..AreaStartZ.."] ["..AreaEndX..":"..AreaEndZ.."]"
|
||||
_small_content = _small_content .. "<h4>Progress:</h4>"..CURRENT.."/"..TOTAL
|
||||
_small_content = _small_content .. "<br>"
|
||||
_small_content = _small_content .. "<form method='POST'>"
|
||||
_small_content = _small_content .. "<input type='submit' name='AGHRRRR' value='Stop'>"
|
||||
_small_content = _small_content .. "</form>"
|
||||
return _small_content
|
||||
end
|
||||
if (GENERATION_STATE == 2 or GENERATION_STATE == 4) then
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
-- SELECTING
|
||||
--------------------------------------------------------------------------------------------------
|
||||
if ( Request.PostParams["FormSetWorld"] ) then
|
||||
WORK_WORLD = Request.PostParams["FormWorldName"]
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
end
|
||||
|
||||
if( Request.PostParams["SelectWorld"] ~= nil
|
||||
and Request.PostParams["WorldName"] ~= nil ) then -- World is selected!
|
||||
WORK_WORLD = Request.PostParams["WorldName"]
|
||||
WW_instance = cRoot:Get():GetWorld(WORK_WORLD)
|
||||
end
|
||||
|
||||
if(Request.PostParams["OperationGenerate"] ~= nil) then
|
||||
OPERATION_CODE = 0
|
||||
end
|
||||
if(Request.PostParams["OperationReGenerate"] ~= nil) then
|
||||
OPERATION_CODE = 1
|
||||
end
|
||||
|
||||
if (GENERATION_STATE == 0) then
|
||||
if( Request.PostParams["FormAreaStartX"] ~= nil
|
||||
and Request.PostParams["FormAreaStartZ"] ~= nil
|
||||
and Request.PostParams["FormAreaEndX"] ~= nil
|
||||
and Request.PostParams["FormAreaEndZ"] ~= nil ) then --(Re)Generation valid!
|
||||
-- COMMON (Re)gen
|
||||
if( Request.PostParams["StartArea"]) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormAreaStartX"])
|
||||
AreaStartZ = tonumber(Request.PostParams["FormAreaStartZ"])
|
||||
AreaEndX = tonumber(Request.PostParams["FormAreaEndX"])
|
||||
AreaEndZ = tonumber(Request.PostParams["FormAreaEndZ"])
|
||||
SaveSettings();
|
||||
if (OPERATION_CODE == 0) then
|
||||
GENERATION_STATE = 1
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
GENERATION_STATE = 3
|
||||
end
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
if( Request.PostParams["FormRadialX"] ~= nil
|
||||
and Request.PostParams["FormRadialZ"] ~= nil
|
||||
and Request.PostParams["FormRadius"] ~= nil ) then --(Re)Generation valid!
|
||||
-- COMMON (Re)gen
|
||||
if( Request.PostParams["StartRadial"]) then
|
||||
RadialX = tonumber(Request.PostParams["FormRadialX"]) or 0
|
||||
RadialZ = tonumber(Request.PostParams["FormRadialZ"]) or 0
|
||||
Radius = tonumber(Request.PostParams["FormRadius"]) or 10
|
||||
AreaStartX = RadialX - Radius
|
||||
AreaStartZ = RadialZ - Radius
|
||||
AreaEndX = RadialX + Radius
|
||||
AreaEndZ = RadialZ + Radius
|
||||
SaveSettings()
|
||||
if (OPERATION_CODE == 0) then
|
||||
GENERATION_STATE = 1
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
GENERATION_STATE = 3
|
||||
end
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
-- POINT REGEN!
|
||||
if( Request.PostParams["FormPointX"] ~= nil
|
||||
and Request.PostParams["FormPointZ"] ~= nil ) then --ReGeneration valid!
|
||||
-- EXACT
|
||||
if ( Request.PostParams["PointExact"] ~= nil) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormPointX"])
|
||||
AreaStartZ = tonumber(Request.PostParams["FormPointZ"])
|
||||
AreaEndX = AreaStartX
|
||||
AreaEndZ = AreaStartZ
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
-- 3x3
|
||||
if ( Request.PostParams["Point3x3"] ~= nil) then
|
||||
AreaStartX = tonumber(Request.PostParams["FormPointX"]) - 1
|
||||
AreaStartZ = tonumber(Request.PostParams["FormPointZ"]) - 1
|
||||
AreaEndX = AreaStartX + 2
|
||||
AreaEndZ = AreaStartZ + 2
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
|
||||
local GetAreaByPlayer = function(Player)
|
||||
-- Player is valid only within this function, it cannot be stord and used later!
|
||||
AreaStartX = Player:GetChunkX()
|
||||
AreaStartZ = Player:GetChunkZ()
|
||||
end
|
||||
-- PLAYERS REGEN!
|
||||
if( Request.PostParams["PlayerExact"] ~= nil
|
||||
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
|
||||
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
|
||||
AreaEndX = AreaStartX
|
||||
AreaEndZ = AreaStartZ
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
if( Request.PostParams["Player3x3"] ~= nil
|
||||
and Request.PostParams["PlayerName"] ~= nil ) then -- Making BOOM! I meant, regenereate...
|
||||
cRoot:Get():GetWorld(WORK_WORLD):DoWithPlayer(Request.PostParams["PlayerName"],GetAreaByPlayer)
|
||||
AreaStartX = AreaStartX - 1
|
||||
AreaStartZ = AreaStartZ - 1
|
||||
AreaEndX = AreaStartX + 2
|
||||
AreaEndZ = AreaStartZ + 2
|
||||
GENERATION_STATE = 3
|
||||
Content = ProcessingContent()
|
||||
return Content
|
||||
end
|
||||
end
|
||||
|
||||
--Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
|
||||
--Content = Content .. "<form method='POST'>"
|
||||
--Content = Content .. "<input type='text' name='FormWorldName' value='Input world name here'><input type='submit' name='FormSetWorld' value='Set world'>"
|
||||
--Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING WORK_WORLD
|
||||
Content = Content .. "<h4>World for operations: " .. WORK_WORLD .. "</h4>"
|
||||
Content = Content .. "<table>"
|
||||
local WorldNum = 0
|
||||
local AddWorldToTable = function(World)
|
||||
WorldNum = WorldNum + 1
|
||||
Content = Content .. "<tr>"
|
||||
Content = Content .. "<td style='width: 10px;'>" .. WorldNum .. ".</td>"
|
||||
Content = Content .. "<td>" .. World:GetName() .. "</td>"
|
||||
Content = Content .. "<td>" .. Button_World(World:GetName()) .. "</td>"
|
||||
Content = Content .. "</tr>"
|
||||
end
|
||||
cRoot:Get():ForEachWorld(AddWorldToTable)
|
||||
if( WorldNum == 0 ) then
|
||||
Content = Content .. "<tr><td>No worlds! O_O</td></tr>"
|
||||
end
|
||||
Content = Content .. "</table>"
|
||||
Content = Content .. "<br>"
|
||||
|
||||
-- SELECTING OPERATION
|
||||
if (OPERATION_CODE == 0) then
|
||||
Content = Content .. "<h4>Operation: Generation</h4>"
|
||||
elseif (OPERATION_CODE == 1) then
|
||||
Content = Content .. "<h4>Operation: Regeneration</h4>"
|
||||
end
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='submit' name='OperationGenerate' value='Generation'>"
|
||||
Content = Content .. "<input type='submit' name='OperationReGenerate' value='Regeneration'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING AREA
|
||||
Content = Content .. "<h4>Area: </h4>Start X, Start Z; End X, End Z"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormAreaStartX' value='" .. AreaStartX .. "'><input type='text' name='FormAreaStartZ' value='" .. AreaStartZ .. "'>"
|
||||
Content = Content .. "<input type='text' name='FormAreaEndX' value='" .. AreaEndX .. "'><input type='text' name='FormAreaEndZ' value='" .. AreaEndZ .. "'>"
|
||||
Content = Content .. "<input type='submit' name='StartArea' value='Start'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING RADIAL
|
||||
Content = Content .. "<h4>Radial: </h4>Center X, Center Z, Radius"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormRadialX' value='" .. RadialX .. "'><input type='text' name='FormRadialZ' value='" .. RadialZ .. "'><input type='text' name='FormRadius' value='" .. Radius .. "'>"
|
||||
Content = Content .. "<input type='submit' name='StartRadial' value='Start'>"
|
||||
Content = Content .. "</form>"
|
||||
Content = Content .. "<br>"
|
||||
Content = Content .. "<br>"
|
||||
Content = Content .. "<br>"
|
||||
|
||||
-- SELECTING POINT
|
||||
Content = Content .. "<h4>Point regeneration:</h4> X, Z"
|
||||
Content = Content .. "<form method='POST'>"
|
||||
Content = Content .. "<input type='text' name='FormPointX' value='0'><input type='text' name='FormPointZ' value='0'>"
|
||||
Content = Content .. "<input type='submit' name='PointExact' value='Exact'>"
|
||||
Content = Content .. "<input type='submit' name='Point3x3' value='3x3'>"
|
||||
Content = Content .. "</form>"
|
||||
|
||||
-- SELECTING PLAYERS
|
||||
Content = Content .. "<h4>Player-based regeneration:</h4>"
|
||||
Content = Content .. "<table>"
|
||||
local PlayerNum = 0
|
||||
local AddPlayerToTable = function( Player )
|
||||
PlayerNum = PlayerNum + 1
|
||||
Content = Content .. "<tr>"
|
||||
Content = Content .. "<td style='width: 10px;'>" .. PlayerNum .. ".</td>"
|
||||
Content = Content .. "<td>" .. Player:GetName() .. "</td>"
|
||||
Content = Content .. "<td>" .. Buttons_Player(Player:GetName()) .. "</td>"
|
||||
Content = Content .. "</tr>"
|
||||
end
|
||||
if (cRoot:Get():GetWorld(WORK_WORLD) == nil) then
|
||||
Content = Content .. "<tr><td>Incorrect world selection</td></tr>"
|
||||
else
|
||||
cRoot:Get():GetWorld(WORK_WORLD):ForEachPlayer( AddPlayerToTable )
|
||||
if( PlayerNum == 0 ) then
|
||||
Content = Content .. "<tr><td>No connected players</td></tr>"
|
||||
end
|
||||
end
|
||||
Content = Content .. "</table>"
|
||||
Content = Content .. "<br>"
|
||||
return Content
|
||||
end
|
@ -33,10 +33,12 @@ function Initialize(Plugin)
|
||||
PM:AddHook(cPluginManager.HOOK_PROJECTILE_HIT_BLOCK, OnProjectileHitBlock);
|
||||
PM:AddHook(cPluginManager.HOOK_CHUNK_UNLOADING, OnChunkUnloading);
|
||||
PM:AddHook(cPluginManager.HOOK_WORLD_STARTED, OnWorldStarted);
|
||||
PM:AddHook(cPluginManager.HOOK_PROJECTILE_HIT_BLOCK, OnProjectileHitBlock);
|
||||
|
||||
-- _X: Disabled so that the normal operation doesn't interfere with anything
|
||||
-- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated);
|
||||
|
||||
PM:BindCommand("/nick", "debuggers", HandleNickCmd, "- Gives you a custom name");
|
||||
PM:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "- Shows a list of all the loaded entities");
|
||||
PM:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "- Kills all the loaded entities");
|
||||
PM:BindCommand("/wool", "debuggers", HandleWoolCmd, "- Sets all your armor to blue wool");
|
||||
@ -64,6 +66,8 @@ function Initialize(Plugin)
|
||||
PM:BindCommand("/sb", "debuggers", HandleSetBiome, "- Sets the biome around you to the specified one");
|
||||
PM:BindCommand("/wesel", "debuggers", HandleWESel, "- Expands the current WE selection by 1 block in X/Z");
|
||||
PM:BindCommand("/rmitem", "debuggers", HandleRMItem, "- Remove the specified item from the inventory.");
|
||||
PM:BindCommand("/pickups", "debuggers", HandlePickups, "- Spawns random pickups around you");
|
||||
PM:BindCommand("/poof", "debuggers", HandlePoof, "- Nudges pickups close to you away from you");
|
||||
|
||||
Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers)
|
||||
Plugin:AddWebTab("StressTest", HandleRequest_StressTest)
|
||||
@ -80,6 +84,8 @@ function Initialize(Plugin)
|
||||
|
||||
TestBlockAreasString()
|
||||
TestStringBase64()
|
||||
-- TestUUIDFromName()
|
||||
-- TestRankMgr()
|
||||
|
||||
--[[
|
||||
-- Test cCompositeChat usage in console-logging:
|
||||
@ -275,6 +281,94 @@ end
|
||||
|
||||
|
||||
|
||||
function TestUUIDFromName()
|
||||
LOG("Testing UUID-from-Name resolution...")
|
||||
|
||||
-- Test by querying a few existing names, along with a non-existent one:
|
||||
local PlayerNames =
|
||||
{
|
||||
"xoft",
|
||||
"aloe_vera",
|
||||
"nonexistent_player",
|
||||
}
|
||||
-- WARNING: Blocking operation! DO NOT USE IN TICK THREAD!
|
||||
local UUIDs = cMojangAPI:GetUUIDsFromPlayerNames(PlayerNames)
|
||||
|
||||
-- Log the results:
|
||||
for _, name in ipairs(PlayerNames) do
|
||||
local UUID = UUIDs[name]
|
||||
if (UUID == nil) then
|
||||
LOG(" UUID(" .. name .. ") not found.")
|
||||
else
|
||||
LOG(" UUID(" .. name .. ") = \"" .. UUID .. "\"")
|
||||
end
|
||||
end
|
||||
|
||||
-- Test once more with the same players, valid-only. This should go directly from cache, so fast.
|
||||
LOG("Testing again with the same valid players...")
|
||||
local ValidPlayerNames =
|
||||
{
|
||||
"xoft",
|
||||
"aloe_vera",
|
||||
}
|
||||
UUIDs = cMojangAPI:GetUUIDsFromPlayerNames(ValidPlayerNames);
|
||||
|
||||
-- Log the results:
|
||||
for _, name in ipairs(ValidPlayerNames) do
|
||||
local UUID = UUIDs[name]
|
||||
if (UUID == nil) then
|
||||
LOG(" UUID(" .. name .. ") not found.")
|
||||
else
|
||||
LOG(" UUID(" .. name .. ") = \"" .. UUID .. "\"")
|
||||
end
|
||||
end
|
||||
|
||||
-- Test yet again, cache-only:
|
||||
LOG("Testing once more, cache only...")
|
||||
local PlayerNames3 =
|
||||
{
|
||||
"xoft",
|
||||
"aloe_vera",
|
||||
"notch", -- Valid player name, but not cached (most likely :)
|
||||
}
|
||||
UUIDs = cMojangAPI:GetUUIDsFromPlayerNames(PlayerNames3, true)
|
||||
|
||||
-- Log the results:
|
||||
for _, name in ipairs(PlayerNames3) do
|
||||
local UUID = UUIDs[name]
|
||||
if (UUID == nil) then
|
||||
LOG(" UUID(" .. name .. ") not found.")
|
||||
else
|
||||
LOG(" UUID(" .. name .. ") = \"" .. UUID .. "\"")
|
||||
end
|
||||
end
|
||||
|
||||
LOG("UUID-from-Name resolution tests finished.")
|
||||
|
||||
LOG("Performing a Name-from-UUID test...")
|
||||
-- local NameToTest = "aloe_vera"
|
||||
local NameToTest = "xoft"
|
||||
local Name = cMojangAPI:GetPlayerNameFromUUID(UUIDs[NameToTest])
|
||||
LOG("Name(" .. UUIDs[NameToTest] .. ") = '" .. Name .. "', expected '" .. NameToTest .. "'.")
|
||||
LOG("Name-from-UUID test finished.")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function TestRankMgr()
|
||||
LOG("Testing the rank manager")
|
||||
cRankManager:AddRank("LuaRank")
|
||||
cRankManager:AddGroup("LuaTestGroup")
|
||||
cRankManager:AddGroupToRank("LuaTestGroup", "LuaRank")
|
||||
cRankManager:AddPermissionToGroup("luaperm", "LuaTestGroup")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function TestSQLiteBindings()
|
||||
LOG("Testing SQLite bindings...");
|
||||
|
||||
@ -677,6 +771,21 @@ end
|
||||
|
||||
|
||||
|
||||
function HandleNickCmd(Split, Player)
|
||||
if (Split[2] == nil) then
|
||||
Player:SendMessage("Usage: /nick [CustomName]");
|
||||
return true;
|
||||
end
|
||||
|
||||
Player:SetCustomName(Split[2]);
|
||||
Player:SendMessageSuccess("Custom name setted to " .. Player:GetCustomName() .. "!")
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleListEntitiesCmd(Split, Player)
|
||||
local NumEntities = 0;
|
||||
|
||||
@ -1409,7 +1518,7 @@ function OnPlayerJoined(a_Player)
|
||||
-- Test composite chat chaining:
|
||||
a_Player:SendMessage(cCompositeChat()
|
||||
:AddTextPart("Hello, ")
|
||||
:AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2")
|
||||
:AddUrlPart(a_Player:GetName(), "http://www.mc-server.org", "u@2")
|
||||
:AddSuggestCommandPart(", and welcome.", "/help", "u")
|
||||
:AddRunCommandPart(" SetDay", "/time set 0")
|
||||
)
|
||||
@ -1455,3 +1564,69 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
function OnProjectileHitBlock(a_ProjectileEntity, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockHitPos)
|
||||
-- This simple test is for testing issue #1326 - simply declaring this hook would crash the server upon call
|
||||
LOG("Projectile hit block")
|
||||
LOG(" Projectile EntityID: " .. a_ProjectileEntity:GetUniqueID())
|
||||
LOG(" Block: {" .. a_BlockX .. ", " .. a_BlockY .. ", " .. a_BlockZ .. "}, face " .. a_BlockFace)
|
||||
LOG(" HitPos: {" .. a_BlockHitPos.x .. ", " .. a_BlockHitPos.y .. ", " .. a_BlockHitPos.z .. "}")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
local PossibleItems =
|
||||
{
|
||||
cItem(E_ITEM_DIAMOND),
|
||||
cItem(E_ITEM_GOLD),
|
||||
cItem(E_ITEM_IRON),
|
||||
cItem(E_ITEM_DYE, 1, E_META_DYE_BLUE), -- Lapis lazuli
|
||||
cItem(E_ITEM_COAL),
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandlePickups(a_Split, a_Player)
|
||||
local PlayerX = a_Player:GetPosX()
|
||||
local PlayerY = a_Player:GetPosY()
|
||||
local PlayerZ = a_Player:GetPosZ()
|
||||
local World = a_Player:GetWorld()
|
||||
local Range = 12
|
||||
for x = 0, Range do for z = 0, Range do
|
||||
local px = PlayerX + x - Range / 2
|
||||
local pz = PlayerZ + z - Range / 2
|
||||
local Items = cItems()
|
||||
Items:Add(PossibleItems[math.random(#PossibleItems)])
|
||||
World:SpawnItemPickups(Items, px, PlayerY, pz, 0)
|
||||
end end -- for z, for x
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function HandlePoof(a_Split, a_Player)
|
||||
local PlayerPos = Vector3d(a_Player:GetPosition()) -- Create a copy of the position
|
||||
PlayerPos.y = PlayerPos.y - 1
|
||||
local Box = cBoundingBox(PlayerPos, 4, 2)
|
||||
local NumEntities = 0
|
||||
a_Player:GetWorld():ForEachEntityInBox(Box,
|
||||
function (a_Entity)
|
||||
if not(a_Entity:IsPlayer()) then
|
||||
local AddSpeed = a_Entity:GetPosition() - PlayerPos -- Speed away from the player
|
||||
a_Entity:AddSpeed(AddSpeed * 32 / (AddSpeed:SqrLength() + 1)) -- The further away, the less speed to add
|
||||
NumEntities = NumEntities + 1
|
||||
end
|
||||
end
|
||||
)
|
||||
a_Player:SendMessage("Poof! (" .. NumEntities .. " entities)")
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
1
MCServer/Plugins/Handy
Submodule
1
MCServer/Plugins/Handy
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit e64a04be39ac7790abcb09de3d4c7d8fc2a2a1e2
|
@ -1,28 +0,0 @@
|
||||
-- Global variables
|
||||
PLUGIN = {} -- Reference to own plugin object
|
||||
CHEST_WIDTH = 9
|
||||
HANDY_VERSION = 2
|
||||
--[[
|
||||
|
||||
Handy is a plugin for other plugins. It contain no commands, no hooks, but functions to ease plugins developers' life.
|
||||
|
||||
API:
|
||||
|
||||
|
||||
TODO:
|
||||
1. GetChestSlot wrapper, so it will detect double chest neighbour chest and will be able to access it.
|
||||
]]
|
||||
|
||||
function Initialize(Plugin)
|
||||
PLUGIN = Plugin
|
||||
PLUGIN:SetName("Handy")
|
||||
PLUGIN:SetVersion(HANDY_VERSION)
|
||||
|
||||
PluginManager = cRoot:Get():GetPluginManager()
|
||||
LOG("Initialized " .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion())
|
||||
return true
|
||||
end
|
||||
|
||||
function OnDisable()
|
||||
LOG(PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. " is shutting down...")
|
||||
end
|
@ -1,216 +0,0 @@
|
||||
--[[
|
||||
General stuff
|
||||
]]
|
||||
-- Returns Handy plugin version number
|
||||
function GetHandyVersion()
|
||||
return HANDY_VERSION
|
||||
end
|
||||
-- Checks if handy is in proper version
|
||||
function CheckForRequiredVersion( inVersion )
|
||||
if( inVersion > HANDY_VERSION ) then return false end
|
||||
return true
|
||||
end
|
||||
--[[
|
||||
MCS-specific _functions and nasty hacks :D
|
||||
]]
|
||||
function GetChestHeightCheat( inChest )
|
||||
local chestGrid = inChest:GetContents()
|
||||
LOGINFO( "This function serves no purpose now! You should consider chest:GetContents():GetHeight() now!" )
|
||||
LOGINFO( "Also, you might find Handy's new 'IsChestDouble()' useful for your case" )
|
||||
return chestGrid:GetHeight()
|
||||
end
|
||||
function IsChestDouble( inChest )
|
||||
local chestHeight = inChest:GetContents():GetHeight()
|
||||
if( chestHeight == 3 ) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
-- Those two checks how many items of given inItemID chest and player have, and how much they could fit inside them
|
||||
function ReadChestForItem( inChest, inItemID )
|
||||
return ReadGridForItems( inChest:GetContents(), inItemID )
|
||||
end
|
||||
function ReadPlayerForItem( inPlayer, inItemID )
|
||||
local inventoryFound, inventoryFree = ReadGridForItems( inPlayer:GetInventory():GetInventoryGrid(), inItemID )
|
||||
local hotbarFound, hotbarFree = ReadGridForItems( inPlayer:GetInventory():GetHotbarGrid(), inItemID )
|
||||
local itemsFound = inventoryFound + hotbarFound
|
||||
local freeSpace = inventoryFree + hotbarFree
|
||||
return itemsFound, freeSpace
|
||||
end
|
||||
-- Following functions are for chest-related operations
|
||||
-- BEWARE! Those assume you did checked if chest has items/space in it!
|
||||
function ReadGridForItems( inGrid, inItemID )
|
||||
local itemsFound = 0
|
||||
local freeSpace = 0
|
||||
local slotsCount = inGrid:GetNumSlots()
|
||||
local testerItem = cItem( inItemID )
|
||||
local maxStackSize = testerItem:GetMaxStackSize()
|
||||
for index = 0, (slotsCount - 1) do
|
||||
slotItem = inGrid:GetSlot( index )
|
||||
if( slotItem:IsEmpty() ) then
|
||||
freeSpace = freeSpace + maxStackSize
|
||||
else
|
||||
if( slotItem:IsStackableWith( testerItem ) ) then
|
||||
itemsFound = itemsFound + slotItem.m_ItemCount
|
||||
freeSpace = maxStackSize - slotItem.m_ItemCount
|
||||
end
|
||||
end
|
||||
end
|
||||
return itemsFound, freeSpace
|
||||
end
|
||||
|
||||
function TakeItemsFromGrid( inGrid, inItem )
|
||||
local slotsCount = inGrid:GetNumSlots()
|
||||
local removedItem = cItem( inItem )
|
||||
for index = 0, (slotsCount - 1) do
|
||||
slotItem = inGrid:GetSlot( index )
|
||||
if( slotItem:IsSameType( removedItem ) ) then
|
||||
if( slotItem.m_ItemCount <= removedItem.m_ItemCount ) then
|
||||
removedItem.m_ItemCount = removedItem.m_ItemCount - slotItem.m_ItemCount
|
||||
inGrid:EmptySlot( index )
|
||||
else
|
||||
removedItem.m_ItemCount = slotItem.m_ItemCount - removedItem.m_ItemCount
|
||||
inGrid:SetSlot( index, removedItem )
|
||||
removedItem.m_ItemCount = 0
|
||||
end
|
||||
if( removedItem.m_ItemCount <= 0 ) then break end
|
||||
end
|
||||
end
|
||||
return removedItem.m_ItemCount
|
||||
end
|
||||
--------------
|
||||
function TakeItemsFromChest( inChest, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FOR ITEMS FIRST!!
|
||||
local chestGrid = inChest:GetContents()
|
||||
local removedItem = cItem( inItemID, inAmount )
|
||||
TakeItemsFromGrid( chestGrid, removedItem )
|
||||
end
|
||||
function PutItemsToChest( inChest, inItemID, inAmount )
|
||||
local chestGrid = inChest:GetContents()
|
||||
local addedItem = cItem( inItemID, inAmount )
|
||||
chestGrid:AddItem( addedItem )
|
||||
end
|
||||
-- Similar to chest-related.
|
||||
function TakeItemsFromPlayer( inPlayer, inItemID, inAmount ) -- MIGHT BE UNSAFE! CHECK FIRST!
|
||||
local removedItem = cItem( inItemID, inAmount )
|
||||
local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid()
|
||||
local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid()
|
||||
local itemsLeft = TakeItemsFromGrid( inventoryGrid, removedItem )
|
||||
if( itemsLeft > 0 ) then
|
||||
removedItem = cItem( inItemID, itemsLeft )
|
||||
TakeItemsFromGrid( hotbarGrid, removedItem )
|
||||
end
|
||||
end
|
||||
function GiveItemsToPlayer( inPlayer, inItemID, inAmount )
|
||||
local addedItem = cItem( inItemID, inAmount )
|
||||
local inventoryGrid = inPlayer:GetInventory():GetInventoryGrid()
|
||||
local hotbarGrid = inPlayer:GetInventory():GetHotbarGrid()
|
||||
local itemsAdded = inventoryGrid:AddItem( addedItem )
|
||||
if( itemsAdded < inAmount ) then
|
||||
addedItem.m_ItemCount = addedItem.m_ItemCount - itemsAdded
|
||||
hotbarGrid:AddItem( addedItem )
|
||||
end
|
||||
end
|
||||
-- This function returns item max stack for a given itemID. It uses vanilla max stack size, and uses several non-common items notations;
|
||||
-- Those are:
|
||||
-- oneonerecord( because aparently 11record wasn't the best idea in lua scripting application )
|
||||
-- carrotonastick( because it wasn't added to items.txt yet )
|
||||
-- waitrecord( for same reason )
|
||||
-- Feel free to ignore the difference, or to add those to items.txt
|
||||
function GetItemMaxStack( inItemID )
|
||||
local testerItem = cItem( inItemID )
|
||||
LOGINFO( "This function serves no real purpose now, maybe consider using cItem:GetMaxStackSize()?" )
|
||||
return testerItem:GetMaxStackSize()
|
||||
end
|
||||
function ItemIsArmor( inItemID, inCheckForHorseArmor )
|
||||
inCheckForHorseArmor = inCheckForHorseArmor or false
|
||||
if( inItemID == E_ITEM_LEATHER_CAP ) then return true end
|
||||
if( inItemID == E_ITEM_LEATHER_TUNIC ) then return true end
|
||||
if( inItemID == E_ITEM_LEATHER_PANTS ) then return true end
|
||||
if( inItemID == E_ITEM_LEATHER_BOOTS ) then return true end
|
||||
|
||||
if( inItemID == E_ITEM_CHAIN_HELMET ) then return true end
|
||||
if( inItemID == E_ITEM_CHAIN_CHESTPLATE ) then return true end
|
||||
if( inItemID == E_ITEM_CHAIN_LEGGINGS ) then return true end
|
||||
if( inItemID == E_ITEM_CHAIN_BOOTS ) then return true end
|
||||
|
||||
if( inItemID == E_ITEM_IRON_HELMET ) then return true end
|
||||
if( inItemID == E_ITEM_IRON_CHESTPLATE ) then return true end
|
||||
if( inItemID == E_ITEM_IRON_LEGGINGS ) then return true end
|
||||
if( inItemID == E_ITEM_IRON_BOOTS ) then return true end
|
||||
|
||||
if( inItemID == E_ITEM_DIAMOND_HELMET ) then return true end
|
||||
if( inItemID == E_ITEM_DIAMOND_CHESTPLATE ) then return true end
|
||||
if( inItemID == E_ITEM_DIAMOND_LEGGINGS ) then return true end
|
||||
if( inItemID == E_ITEM_DIAMOND_BOOTS ) then return true end
|
||||
|
||||
if( inItemID == E_ITEM_GOLD_HELMET ) then return true end
|
||||
if( inItemID == E_ITEM_GOLD_CHESTPLATE ) then return true end
|
||||
if( inItemID == E_ITEM_GOLD_LEGGINGS ) then return true end
|
||||
if( inItemID == E_ITEM_GOLD_BOOTS ) then return true end
|
||||
|
||||
if( inCheckForHorseArmor ) then
|
||||
if( inItemID == E_ITEM_IRON_HORSE_ARMOR ) then return true end
|
||||
if( inItemID == E_ITEM_GOLD_HORSE_ARMOR ) then return true end
|
||||
if( inItemID == E_ITEM_DIAMOND_HORSE_ARMOR ) then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
-- Returns full-length playername for a short name( usefull for parsing commands )
|
||||
function GetExactPlayername( inPlayerName )
|
||||
local _result = inPlayerName
|
||||
local function SetProcessingPlayername( inPlayer )
|
||||
_result = inPlayer:GetName()
|
||||
end
|
||||
cRoot:Get():FindAndDoWithPlayer( inPlayerName, SetProcessingPlayername )
|
||||
return _result
|
||||
end
|
||||
function GetPlayerByName( inPlayerName )
|
||||
local _player
|
||||
local PlayerSetter = function( Player )
|
||||
_player = Player
|
||||
end
|
||||
cRoot:Get():FindAndDoWithPlayer( inPlayerName, PlayerSetter )
|
||||
return _player
|
||||
end
|
||||
--[[
|
||||
Not-so-usual math _functions
|
||||
]]
|
||||
-- Rounds floating point number. Because lua guys think this function doesn't deserve to be presented in lua's math
|
||||
function round( inX )
|
||||
if( inX%2 ~= 0.5 ) then
|
||||
return math.floor( inX + 0.5 )
|
||||
end
|
||||
return inX - 0.5
|
||||
end
|
||||
--[[
|
||||
Functions I use for filework and stringswork
|
||||
]]
|
||||
function PluralString( inValue, inSingularString, inPluralString )
|
||||
local _value_string = tostring( inValue )
|
||||
if( _value_string[#_value_string] == "1" ) then
|
||||
return inSingularString
|
||||
end
|
||||
return inPluralString
|
||||
end
|
||||
function PluralItemName( inItemID, inAmount ) -- BEWARE! TEMPORAL SOLUTION THERE! :D
|
||||
local _value_string = tostring( inValue )
|
||||
local _name = ""
|
||||
if( _value_string[#_value_string] == "1" ) then
|
||||
-- singular names
|
||||
_name = ItemTypeToString( inItemID )
|
||||
else
|
||||
-- plural names
|
||||
_name = ItemTypeToString( inItemID ).."s"
|
||||
end
|
||||
return _name
|
||||
end
|
||||
-- for filewriting purposes. 0 = false, 1 = true
|
||||
function StringToBool( inValue )
|
||||
if( inValue == "1" ) then return true end
|
||||
return false
|
||||
end
|
||||
-- same, but reversal
|
||||
function BoolToString( inValue )
|
||||
if( inValue == true ) then return 1 end
|
||||
return 0
|
||||
end
|
1
MCServer/Plugins/MagicCarpet
Submodule
1
MCServer/Plugins/MagicCarpet
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 493f2dfa6d39f134e37c4c614cf8d6ffd10c825f
|
@ -1,97 +0,0 @@
|
||||
-- Location object
|
||||
cLocation = {}
|
||||
function cLocation:new( x, y, z )
|
||||
local object = { x = x, y = y, z = z }
|
||||
setmetatable(object, { __index = cLocation })
|
||||
return object
|
||||
end
|
||||
|
||||
-- Offsets
|
||||
cFibers = { }
|
||||
function cFibers:new()
|
||||
local object = {
|
||||
cLocation:new( 2, -1, 2 ),
|
||||
cLocation:new( 2, -1, 1 ),
|
||||
cLocation:new( 2, -1, 0 ),
|
||||
cLocation:new( 2, -1, -1 ),
|
||||
cLocation:new( 2, -1, -2 ),
|
||||
cLocation:new( 1, -1, 2 ),
|
||||
cLocation:new( 1, -1, 1 ),
|
||||
cLocation:new( 1, -1, 0 ),
|
||||
cLocation:new( 1, -1, -1 ),
|
||||
cLocation:new( 1, -1, -2 ),
|
||||
cLocation:new( 0, -1, 2 ),
|
||||
cLocation:new( 0, -1, 1 ),
|
||||
cLocation:new( 0, -1, 0 ),
|
||||
cLocation:new( 0, -1, -1 ),
|
||||
cLocation:new( 0, -1, -2 ),
|
||||
cLocation:new( -1, -1, 2 ),
|
||||
cLocation:new( -1, -1, 1 ),
|
||||
cLocation:new( -1, -1, 0 ),
|
||||
cLocation:new( -1, -1, -1 ),
|
||||
cLocation:new( -1, -1, -2 ),
|
||||
cLocation:new( -2, -1, 2 ),
|
||||
cLocation:new( -2, -1, 1 ),
|
||||
cLocation:new( -2, -1, 0 ),
|
||||
cLocation:new( -2, -1, -1 ),
|
||||
cLocation:new( -2, -1, -2 ),
|
||||
imadeit = false,
|
||||
}
|
||||
setmetatable(object, { __index = cFibers })
|
||||
return object;
|
||||
end
|
||||
|
||||
-- Carpet object
|
||||
cCarpet = {}
|
||||
function cCarpet:new()
|
||||
local object = { Location = cLocation:new(0,0,0),
|
||||
Fibers = cFibers:new(),
|
||||
}
|
||||
setmetatable(object, { __index = cCarpet })
|
||||
return object
|
||||
end
|
||||
|
||||
function cCarpet:remove()
|
||||
local World = cRoot:Get():GetDefaultWorld()
|
||||
for i, fib in ipairs( self.Fibers ) do
|
||||
local x = self.Location.x + fib.x
|
||||
local y = self.Location.y + fib.y
|
||||
local z = self.Location.z + fib.z
|
||||
local BlockID = World:GetBlock( x, y, z )
|
||||
if( fib.imadeit == true and BlockID == E_BLOCK_GLASS ) then
|
||||
World:SetBlock( x, y, z, 0, 0 )
|
||||
fib.imadeit = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:draw()
|
||||
local World = cRoot:Get():GetDefaultWorld()
|
||||
for i, fib in ipairs( self.Fibers ) do
|
||||
local x = self.Location.x + fib.x
|
||||
local y = self.Location.y + fib.y
|
||||
local z = self.Location.z + fib.z
|
||||
local BlockID = World:GetBlock( x, y, z )
|
||||
if( BlockID == 0 ) then
|
||||
fib.imadeit = true
|
||||
World:SetBlock( x, y, z, E_BLOCK_GLASS, 0 )
|
||||
else
|
||||
fib.imadeit = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:moveTo( NewPos )
|
||||
local x = math.floor( NewPos.x )
|
||||
local y = math.floor( NewPos.y )
|
||||
local z = math.floor( NewPos.z )
|
||||
if( self.Location.x ~= x or self.Location.y ~= y or self.Location.z ~= z ) then
|
||||
self:remove()
|
||||
self.Location = cLocation:new( x, y, z )
|
||||
self:draw()
|
||||
end
|
||||
end
|
||||
|
||||
function cCarpet:getY()
|
||||
return self.Location.y
|
||||
end
|
@ -1,81 +0,0 @@
|
||||
local Carpets = {}
|
||||
local PLUGIN
|
||||
|
||||
function Initialize( Plugin )
|
||||
Plugin:SetName( "MagicCarpet" )
|
||||
Plugin:SetVersion( 2 )
|
||||
|
||||
cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_MOVING, OnPlayerMoving)
|
||||
cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_DESTROYED, OnDisconnect)
|
||||
|
||||
local PluginManager = cPluginManager:Get()
|
||||
PluginManager:BindCommand("/mc", "magiccarpet", HandleCarpetCommand, " - Spawns a magical carpet");
|
||||
|
||||
PLUGIN = Plugin
|
||||
|
||||
LOG( "Initialised " .. Plugin:GetName() .. " v." .. Plugin:GetVersion() )
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnDisable()
|
||||
LOG( PLUGIN:GetName() .. " v." .. PLUGIN:GetVersion() .. " is shutting down..." )
|
||||
for i, Carpet in pairs( Carpets ) do
|
||||
Carpet:remove()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleCarpetCommand( Split, Player )
|
||||
Carpet = Carpets[ Player ]
|
||||
|
||||
if( Carpet == nil ) then
|
||||
Carpets[ Player ] = cCarpet:new()
|
||||
Player:SendMessageSuccess("You're on a magic carpet!")
|
||||
Player:SendMessageInfo("Look straight down to descend. Jump to ascend.")
|
||||
else
|
||||
Carpet:remove()
|
||||
Carpets[ Player ] = nil
|
||||
Player:SendMessageSuccess("The carpet vanished!")
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnDisconnect( Reason, Player )
|
||||
local Carpet = Carpets[ Player ]
|
||||
if( Carpet ~= nil ) then
|
||||
Carpet:remove()
|
||||
end
|
||||
Carpets[ Player ] = nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function OnPlayerMoving(Player)
|
||||
local Carpet = Carpets[ Player ]
|
||||
if( Carpet == nil ) then
|
||||
return
|
||||
end
|
||||
|
||||
if( Player:GetPitch() == 90 ) then
|
||||
Carpet:moveTo( cLocation:new( Player:GetPosX(), Player:GetPosY() - 1, Player:GetPosZ() ) )
|
||||
else
|
||||
if( Player:GetPosY() < Carpet:getY() ) then
|
||||
Player:TeleportToCoords(Player:GetPosX(), Carpet:getY() + 0.2, Player:GetPosZ())
|
||||
end
|
||||
Carpet:moveTo( cLocation:new( Player:GetPosX(), Player:GetPosY(), Player:GetPosZ() ) )
|
||||
end
|
||||
end
|
@ -1 +1 @@
|
||||
Subproject commit 9edfee93048f214175cbed7eb2a3f77f7ac4abb2
|
||||
Subproject commit 7765048fa740b8f119db72a4ccc546504f86b2ab
|
@ -40,10 +40,12 @@
|
||||
|
||||
# Need to list each of the four log types, otherwise all logs would get converted into apple planks (^0)
|
||||
|
||||
ApplePlanks, 4 = AppleLog, *
|
||||
ConiferPlanks, 4 = ConiferLog, *
|
||||
OakPlanks, 4 = OakLog, *
|
||||
SprucePlanks, 4 = SpruceLog, *
|
||||
BirchPlanks, 4 = BirchLog, *
|
||||
JunglePlanks, 4 = JungleLog, *
|
||||
AcaciaPlanks, 4 = AcaciaLog, *
|
||||
DarkOakPlanks, 4 = DarkOakLog, *
|
||||
Stick, 4 = Planks, 2:2, 2:3
|
||||
Torch, 4 = Stick, 1:2 | Coal, 1:1
|
||||
Workbench = Planks, 1:1, 1:2, 2:1, 2:2
|
||||
@ -65,6 +67,7 @@ DiamondBlock = Diamond, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
LapisBlock = LapisLazuli, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EmeraldBlock = Emerald, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
RedstoneBlock = RedstoneDust, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
CoalBlock = Coal, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
QuartzBlock = NetherQuartz, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
NetherBrick = netherbrickitem, 1:1, 1:2, 2:1, 2:2
|
||||
Glowstone = GlowstoneDust, 1:1, 1:2, 2:1, 2:2
|
||||
@ -74,21 +77,62 @@ PillarQuartzBlock = QuartzSlab, 1:1, 1:2
|
||||
ChiseledQuartzBlock, 2 = QuartzBlock, 1:1, 1:2
|
||||
CoalBlock = Coal, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
HayBale = Wheat, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
||||
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
||||
BrickBlock = Brick, 1:1, 1:2, 2:1, 2:2
|
||||
StoneBrick, 4 = Stone, 1:1, 1:2, 2:1, 2:2
|
||||
BookShelf = Planks, 1:1, 2:1, 3:1, 1:3, 2:3, 3:3 | Book, 1:2, 2:2, 3:2
|
||||
Sandstone, 4 = Sand, 1:1, 1:2, 2:1, 2:2
|
||||
SmoothSandstone, 4 = Sandstone, 1:1, 1:2, 2:1, 2:2
|
||||
OrnamentSandstone = SandstoneSlab, 1:1, 1:2
|
||||
JackOLantern = Pumpkin, 1:1 | Torch, 1:2
|
||||
PolishedGranite, 4 = Granite, 1:1, 1:2, 2:1, 2:2
|
||||
PolishedDiorite, 4 = Diorite, 1:1, 1:2, 2:1, 2:2
|
||||
PolishedAndesite, 4 = Andesite, 1:1, 1:2, 2:1, 2:2
|
||||
CoarsedDirt, 4 = Dirt, 1:1, 2:2 | Gravel, 1:2, 2:1
|
||||
CoarsedDirt, 4 = Gravel, 1:1, 2:2 | Dirt, 1:2, 2:1
|
||||
SlimeBlock = Slimeball, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
Prismarine = PrismarineShard, 1:1, 1:2, 2:1, 2:2
|
||||
PrismarineBricks = PrismarineShard, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
DarkPrismarine = PrismarineShard, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Inksac, 2:2
|
||||
SeaLantern = PrismarineShard, 1:1, 1:3, 3:1, 3:3 | PrismarineCrystals, 1:2, 2:1, 2:2, 2:3, 3:2
|
||||
RedSandstone, 4 = RedSand, 1:1, 1:2, 2:1, 2:2
|
||||
ChiseledRedSandstone, 4 = RedSandstoneSlab, 1:1, 1:2
|
||||
SmoothRedSandstone, 4 = RedSand, 1:1, 1:2, 2:1, 2:2
|
||||
MossyStoneBrick = Stonebrick, * | Vines, *
|
||||
Leather = RabbitHide, 1:1, 1:2, 2:1, 2:2
|
||||
|
||||
# Slabs:
|
||||
StoneSlab, 6 = Stone, 1:1, 2:1, 3:1
|
||||
SandstoneSlab, 6 = Sandstone, 1:1, 2:1, 3:1
|
||||
WoodSlab, 6 = Planks, 1:1, 2:1, 3:1
|
||||
SpruceWoodSlab, 6 = SprucePlanks, 1:1, 2:1, 3:1
|
||||
BirchWoodSlab, 6 = BirchPlanks, 1:1, 2:1, 3:1
|
||||
JungleWoodSlab, 6 = JunglePlanks, 1:1, 2:1, 3:1
|
||||
AcaciaWoodSlab, 6 = AcaciaPlanks, 1:1, 2:1, 3:1
|
||||
DarkOakWoodSlab, 6 = DarkOakPlanks, 1:1, 2:1, 3:1
|
||||
OakWoodSlab, 6 = OakPlanks, 1:1, 2:1, 3:1
|
||||
CobblestoneSlab, 6 = Cobblestone, 1:1, 2:1, 3:1
|
||||
BrickSlab, 6 = BrickBlock, 1:1, 2:1, 3:1
|
||||
StonebrickSlab, 6 = StoneBrick, 1:1, 2:1, 3:1
|
||||
NetherbrickSlab, 6 = NetherBrick, 1:1, 2:1, 3:1
|
||||
Quartzslab, 6 = QuartzBlock, 1:1, 2:1, 3:1
|
||||
snow, 6 = SnowBlock, 1:1, 2:1, 3:1
|
||||
RedSandstoneSlab, 6 = RedSandstone, 1:1, 2:1, 3:1
|
||||
|
||||
|
||||
# Stairs:
|
||||
WoodStairs, 4 = Planks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
WoodStairs, 4 = Planks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
SpruceWoodStairs, 4 = SprucePlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
SpruceWoodStairs, 4 = SprucePlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
BirchWoodStairs, 4 = BirchPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
BirchWoodStairs, 4 = BirchPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
JungleWoodStairs, 4 = JunglePlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
JungleWoodStairs, 4 = JunglePlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
AcaciaWoodStairs, 4 = AcaciaPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
AcaciaWoodStairs, 4 = AcaciaPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
DarkOakWoodStairs, 4 = DarkOakPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
DarkOakWoodStairs, 4 = DarkOakPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
WoodStairs, 4 = OakPlanks, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
WoodStairs, 4 = OakPlanks, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
cobblestoneStairs, 4 = Cobblestone, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
cobblestoneStairs, 4 = Cobblestone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
BrickStairs, 4 = BrickBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
@ -101,18 +145,8 @@ quartzstairs, 4 = QuartzBlock, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
quartzstairs, 4 = QuartzBlock, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
StoneBrickStairs, 4 = StoneBrick, 1:1, 1:2, 2:2, 1:3, 2:3, 3:3
|
||||
StoneBrickStairs, 4 = StoneBrick, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
SnowBlock = SnowBall, 1:1, 1:2, 2:1, 2:2
|
||||
ClayBlock = Clay, 1:1, 1:2, 2:1, 2:2
|
||||
BrickBlock = Brick, 1:1, 1:2, 2:1, 2:2
|
||||
StoneBrick, 4 = Stone, 1:1, 1:2, 2:1, 2:2
|
||||
BookShelf = Planks, 1:1, 2:1, 3:1, 1:3, 2:3, 3:3 | Book, 1:2, 2:2, 3:2
|
||||
Sandstone, 4 = Sand, 1:1, 1:2, 2:1, 2:2
|
||||
SmoothSandstone, 4 = Sandstone, 1:1, 1:2, 2:1, 2:2
|
||||
OrnamentSandstone = SandstoneSlab, 1:1, 1:2
|
||||
JackOLantern = Pumpkin, 1:1 | Torch, 1:2
|
||||
|
||||
# Other
|
||||
Carpet = Wool, 1:3, 2:3
|
||||
RedSandstoneStairs, 4 = RedSandstone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
RedSandstoneStairs, 4 = RedSandstone, 3:1, 2:2, 3:2, 1:3, 2:3, 3:3
|
||||
|
||||
|
||||
|
||||
@ -244,11 +278,19 @@ ActivatorRail, 6 = IronIngot, 1:1, 1:2, 1:3, 3:1, 3:2, 3:3 | Stick, 2:1, 2:3 | R
|
||||
#******************************************************#
|
||||
# Mechanisms
|
||||
#
|
||||
WoodenDoor = Planks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
IronDoor = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
WoodenDoor, 3 = OakPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
SpruceDoor, 3 = SprucePlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
BirchDoor, 3 = BirchPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
JungleDoor, 3 = JunglePlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
AcaciaDoor, 3 = AcaciaPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
DarkOakDoor, 3 = DarkOakPlanks, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
IronDoor, 3 = IronIngot, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3
|
||||
TrapDoor, 2 = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
IronTrapDoor = IronIngot, 1:1, 1:2, 2:1, 2:2
|
||||
WoodPlate = Planks, 1:1, 2:1
|
||||
StonePlate = Stone, 1:1, 2:1
|
||||
lightweightedpressureplate = IronIngot, 1:1, 2:1
|
||||
heavyweightedpressureplate = GoldIngot, 1:1, 2:1
|
||||
StoneButton = Stone, 1:1
|
||||
WoodenButton = Planks, 1:1
|
||||
RedstoneTorchOn = Stick, 1:2 | RedstoneDust, 1:1
|
||||
@ -286,6 +328,8 @@ MelonSeeds = MelonSlice, *
|
||||
PumpkinSeeds, 4 = Pumpkin, *
|
||||
PumpkinPie = Pumpkin, * | Sugar, * | egg, *
|
||||
Wheat, 9 = Haybale, *
|
||||
RabbitStew = Cooked Rabbit, 2:1 | Carrot, 1:2 | BakedPotato, 2:2 | BrownMushroom, 3:2 | Bowl, 2:3
|
||||
RabbitStew = Cooked Rabbit, 2:1 | Carrot, 1:2 | BakedPotato, 2:2 | RedMushroom, 3:2 | Bowl, 2:3
|
||||
|
||||
|
||||
|
||||
@ -304,27 +348,60 @@ Emerald, 9 = EmeraldBlock, *
|
||||
RedstoneDust, 9 = RedstoneBlock, *
|
||||
Coal, 9 = CoalBlock, *
|
||||
Clay, 4 = ClayBlock, *
|
||||
SlimeBall, 9 = SlimeBlock, *
|
||||
|
||||
Painting = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Wool, 2:2
|
||||
ItemFrame = Stick, 1:1, 1:2, 1:3, 2:1, 2:3, 3:1, 3:2, 3:3 | Leather, 2:2
|
||||
Sign = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2 | Stick, 2:3
|
||||
Sign, 3 = Planks, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2 | Stick, 2:3
|
||||
Ladder, 3 = Stick, 1:1, 3:1, 1:2, 2:2, 3:2, 1:3, 3:3
|
||||
GlassPane, 16 = Glass, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
IronBars, 16 = IronIngot, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
Paper, 3 = Sugarcane, 1:1, 2:1, 3:1
|
||||
Book = Paper, *, *, * | leather, *
|
||||
Bookandquill = Book, * | feather, * | inksac, *
|
||||
Fence, 2 = Stick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
Fence, 3 = OakPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
SpruceFence, 3 = SprucePlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
BirchFence, 3 = BirchPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
JungleFence, 3 = JunglePlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
DarkOakFence, 3 = DarkOakPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
AcaciaFence, 3 = AcaciaPlanks, 1:1, 1:2, 3:1, 3:2 | Stick, 2:1, 2:2
|
||||
Cobblestonewall, 6 = cobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
mossycobblestonewall, 6 = mossycobblestone, 1:2, 1:3, 2:2, 2:3, 3:2, 3:3
|
||||
NetherBrickFence, 6 = NetherBrick, 1:1, 2:1, 3:1, 1:2, 2:2, 3:2
|
||||
FenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | Planks, 2:1, 2:2
|
||||
FenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | OakPlanks, 2:1, 2:2
|
||||
SpruceFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | SprucePlanks, 2:1, 2:2
|
||||
BirchFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | BirchPlanks, 2:1, 2:2
|
||||
JungleFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | JunglePlanks, 2:1, 2:2
|
||||
DarkOakFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | DarkOakPlanks, 2:1, 2:2
|
||||
AcaciaFenceGate = Stick, 1:1, 1:2, 3:1, 3:2 | AcaciaPlanks, 2:1, 2:2
|
||||
Bed = Planks, 1:2, 2:2, 3:2 | Wool, 1:1, 2:1, 3:1
|
||||
GoldIngot = GoldNugget, 1:1, 1:2, 1:3, 2:1, 2:2, 2:3, 3:1, 3:2, 3:3
|
||||
EyeOfEnder = EnderPearl, * | BlazePowder, *
|
||||
Beacon = Glass, 1:1, 1:2, 2:1, 3:1, 3:2 | Obsidian, 1:3, 2:3, 3:3 | NetherStar, 2:2
|
||||
Anvil = IronBlock, 1:1, 2:1, 3:1 | IronIngot, 2:2, 1:3, 2:3, 3:3
|
||||
FlowerPot = Brick, 1:2, 2:3, 3:2
|
||||
ArmorStand = Stick, 1:1, 1:3, 2:1, 2:2, 3:1, 3:3 | StoneSlab, 2:3
|
||||
|
||||
# These are just the basic ones, you can add various shapes and stuff to each of them
|
||||
# ToDo: Add the various shapes (saved in NBT-Tags, not in meta)
|
||||
# Banners:
|
||||
|
||||
WhiteBanner = Stick, 2:3 | WhiteWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
OrangeBanner = Stick, 2:3 | OrangeWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
MagentaBanner = Stick, 2:3 | MagentaWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
LightBlueBanner = Stick, 2:3 | LightBlueWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
YellowBanner = Stick, 2:3 | YellowWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
LimeBanner = Stick, 2:3 | LimeWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
PinkBanner = Stick, 2:3 | PinkWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
GrayBanner = Stick, 2:3 | GrayWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
LightGrayBanner = Stick, 2:3 | LightGrayWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
CyanBanner = Stick, 2:3 | CyanWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
PurpleBanner = Stick, 2:3 | PurpleWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
BlueBanner = Stick, 2:3 | BlueWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
BrownBanner = Stick, 2:3 | BrownWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
GreenBanner = Stick, 2:3 | GreenWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
RedBanner = Stick, 2:3 | RedWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
BlackBanner = Stick, 2:3 | BlackWool, 1:1, 1:2, 2:1, 2:2, 2:1, 2:2
|
||||
|
||||
|
||||
|
||||
@ -373,13 +450,30 @@ PinkWool = Wool, * | PinkDye, *
|
||||
GrayWool = Wool, * | GrayDye, *
|
||||
LightGrayWool = Wool, * | LightGrayDye, *
|
||||
CyanWool = Wool, * | CyanDye, *
|
||||
VioletWool = Wool, * | VioletDye, *
|
||||
PurpleWool = Wool, * | PurpleDye, *
|
||||
BlueWool = Wool, * | BlueDye, *
|
||||
BrownWool = Wool, * | BrownDye, *
|
||||
GreenWool = Wool, * | GreenDye, *
|
||||
RedWool = Wool, * | RedDye, *
|
||||
BlackWool = Wool, * | BlackDye, *
|
||||
|
||||
WhiteCarpet, 3 = WhiteWool, 1:1, 2:1
|
||||
OrangeCarpet, 3 = OrangeWool, 1:1, 2:1
|
||||
MagentaCarpet, 3 = MagentaWool, 1:1, 2:1
|
||||
LightBlueCarpet, 3 = LightBlueWool, 1:1, 2:1
|
||||
YellowCarpet, 3 = YellowWool, 1:1, 2:1
|
||||
LimeCarpet, 3 = LimeWool, 1:1, 2:1
|
||||
PinkCarpet, 3 = PinkWool, 1:1, 2:1
|
||||
GrayCarpet, 3 = GrayWool, 1:1, 2:1
|
||||
LightGrayCarpet, 3 = LightGrayWool, 1:1, 2:1
|
||||
CyanCarpet, 3 = CyanWool, 1:1, 2:1
|
||||
PurpleCarpet, 3 = PurpleWool, 1:1, 2:1
|
||||
BlueCarpet, 3 = BlueWool, 1:1, 2:1
|
||||
BrownCarpet, 3 = BrownWool, 1:1, 2:1
|
||||
GreenCarpet, 3 = GreenWool, 1:1, 2:1
|
||||
RedCarpet, 3 = RedWool, 1:1, 2:2
|
||||
BlackCarpet, 3 = BlackWool, 1:1, 2:1
|
||||
|
||||
#******************************************************#
|
||||
# Stained Glass:
|
||||
#
|
||||
|
@ -10,25 +10,28 @@
|
||||
# An Item is defined by an Item Type, an amount (and damage)
|
||||
# The damage is optional, and if not specified it's assumed to be 0
|
||||
#
|
||||
# -Cactus Green:
|
||||
# 351 : 1 ( : 2 )
|
||||
# ItemType : Amount ( : Damage )
|
||||
# Cactus Green example:
|
||||
# 351 : 2 ( , 1 )
|
||||
# ItemType : Damage ( , Amount )
|
||||
# or simple use the item name (marked in items.ini):
|
||||
# CactusGreen ( , 1 )
|
||||
#
|
||||
#
|
||||
# **** Recipe and result ****
|
||||
#
|
||||
# 4:1@200=1:1 -> Produces 1 smooth stone from 1 cobblestone in 200 ticks (10 seconds)
|
||||
# Cobble @ 200 = Stone -> Produces 1 smooth stone from 1 cobblestone in 200 ticks (10 seconds)
|
||||
#
|
||||
# 4 : 1 @ 200 = 1 : 1
|
||||
# ItemType : Amount @ ticks = ItemID : Amount
|
||||
# Write in full:
|
||||
# Cobble : 0 , 1 @ 200 = 1 : 1 , 1
|
||||
# ItemType : Damage , Amount @ ticks = ItemType : Damage , Amount
|
||||
#
|
||||
#
|
||||
# **** Fuel ****
|
||||
#
|
||||
# !17:1 = 300 -> 1 Wood burns for 300 ticks (15 s)
|
||||
#
|
||||
# ! 17 : 1 = 300
|
||||
# Fuel ItemType : Amount = ticks
|
||||
# ! Wood , 1 = 300
|
||||
# Fuel ItemType , Amount = ticks
|
||||
#
|
||||
#******************************************************#
|
||||
|
||||
@ -39,20 +42,24 @@
|
||||
#--------------------------
|
||||
# Smelting recipes
|
||||
|
||||
4:1 @ 200 = 1:1 # 1 Cobblestone -> 1 Rock
|
||||
15:1 @ 200 = 265:1 # 1 Iron Ore -> 1 Iron Ingot
|
||||
14:1 @ 200 = 266:1 # 1 Gold Ore -> 1 Gold Ingot
|
||||
153:1 @ 200 = 406:1 # 1 Quartz Ore -> 1 Quartz
|
||||
12:1 @ 200 = 20:1 # 1 Sand -> 1 Glass
|
||||
319:1 @ 200 = 320:1 # 1 Raw Pork -> 1 Cooked Pork
|
||||
363:1 @ 200 = 364:1 # 1 Raw Beef -> 1 Cooked Beef (steak)
|
||||
365:1 @ 200 = 366:1 # 1 Raw Chicken -> 1 Cooked Chicken
|
||||
337:1 @ 200 = 336:1 # 1 Clay -> 1 Clay Brick
|
||||
82:1 @ 200 = 172:1 # 1 Clay Block -> 1 Hardened Clay
|
||||
87:1 @ 200 = 405:1 # 1 NetherRack -> 1 NetherBrick
|
||||
349:1 @ 200 = 350:1 # 1 Raw Fish -> 1 Cooked Fish
|
||||
17:1 @ 200 = 263:1:1 # 1 Log -> 1 Charcoal
|
||||
81:1 @ 200 = 351:1:2 # 1 Cactus -> 1 Green Dye
|
||||
Cobble = Stone
|
||||
IronOre = IronIngot
|
||||
GoldOre = GoldIngot
|
||||
NetherQuartzOre = NetherQuartz
|
||||
Sand = Glass
|
||||
Pork = CookedPork
|
||||
RawBeef = Steak
|
||||
RawChicken = CookedChicken
|
||||
Clay = Brick
|
||||
ClayBlock = HardenedClay
|
||||
TallGrass = NetherBrickItem
|
||||
RawFish = CookedFish
|
||||
Log = CharCoal
|
||||
Cactus = GreenDye
|
||||
WetSponge = Sponge
|
||||
Stonebrick = CrackedStonebrick
|
||||
RawRabbit = CookedRabbit
|
||||
RawMutton = CookedMutton
|
||||
|
||||
|
||||
|
||||
@ -61,31 +68,41 @@
|
||||
#--------------------------
|
||||
# Fuels
|
||||
|
||||
! 263:1 = 1600 # 1 Coal -> 80 sec
|
||||
! 263:1:1 = 1600 # 1 Charcoal -> 80 sec
|
||||
! 126:1 = 15 # 1 Halfslab -> 7.5 sec
|
||||
! 5:1 = 300 # 1 Planks -> 15 sec
|
||||
! 280:1 = 100 # 1 Stick -> 5 sec
|
||||
! 85:1 = 300 # 1 Fence -> 15 sec
|
||||
! 53:1 = 300 # 1 Wooden Stairs -> 15 sec
|
||||
! 58:1 = 300 # 1 Crafting Table -> 15 sec
|
||||
! 47:1 = 300 # 1 Bookshelf -> 15 sec
|
||||
! 54:1 = 300 # 1 Chest -> 15 sec
|
||||
! 84:1 = 300 # 1 Jukebox -> 15 sec
|
||||
! 327:1 = 20000 # 1 Lava Bucket -> 1000 sec
|
||||
! 17:1 = 300 # 1 Wood -> 15 sec
|
||||
! 6:1 = 100 # 1 Sapling -> 5 sec
|
||||
! 173:1 = 16000 # 1 Coal Block -> 800 sec
|
||||
! 369:1 = 2400 # 1 Blaze Rod -> 120 sec
|
||||
! 25:1 = 300 # 1 Note Block -> 15 sec
|
||||
! 151:1 = 300 # 1 Daylight Sensor -> 15 sec
|
||||
! 107:1 = 300 # 1 Fence Gate -> 15 sec
|
||||
! 167:1 = 300 # 1 Trapdoor -> 15 sec
|
||||
! 146:1 = 300 # 1 Trapped Chest -> 15 sec
|
||||
! 72:1 = 300 # 1 Pressure Plate -> 15 sec
|
||||
! 270:1 = 200 # 1 Wooden Pickaxe -> 10 sec
|
||||
! 271:1 = 200 # 1 Wooden Axe -> 10 sec
|
||||
! 269:1 = 200 # 1 Wooden Shovel -> 10 sec
|
||||
! 290:1 = 200 # 1 Wooden Hoe -> 10 sec
|
||||
! 268:1 = 200 # 1 Wooden Sword -> 10 sec
|
||||
! CharCoal = 1600 # -> 80 sec
|
||||
! Coal = 1600 # -> 80 sec
|
||||
! WoodenSlab = 15 # -> 7.5 sec
|
||||
! Planks = 300 # -> 15 sec
|
||||
! Stick = 100 # -> 5 sec
|
||||
! Fence = 300 # -> 15 sec
|
||||
! SpruceFence = 300 # -> 15 sec
|
||||
! BirchFence = 300 # -> 15 sec
|
||||
! JungleFence = 300 # -> 15 sec
|
||||
! DarkOakFence = 300 # -> 15 sec
|
||||
! AcaciaFence = 300 # -> 15 sec
|
||||
! WoodStairs = 300 # -> 15 sec
|
||||
! Workbench = 300 # -> 15 sec
|
||||
! Bookshelf = 300 # -> 15 sec
|
||||
! Chest = 300 # -> 15 sec
|
||||
! Jukebox = 300 # -> 15 sec
|
||||
! Lavabucket = 20000 # -> 1000 sec
|
||||
! Log = 300 # -> 15 sec
|
||||
! Sapling = 100 # -> 5 sec
|
||||
! CoalBlock = 16000 # -> 800 sec
|
||||
! BlazeRod = 2400 # -> 120 sec
|
||||
! NoteBlock = 300 # -> 15 sec
|
||||
! DaylightSensor = 300 # -> 15 sec
|
||||
! FenceGate = 300 # -> 15 sec
|
||||
! SpruceFenceGate = 300 # -> 15 sec
|
||||
! BirchFenceGate = 300 # -> 15 sec
|
||||
! JungleFenceGate = 300 # -> 15 sec
|
||||
! DarkOakFenceGate = 300 # -> 15 sec
|
||||
! Trapdoor = 300 # -> 15 sec
|
||||
! TrappedChest = 300 # -> 15 sec
|
||||
! WoodPlate = 300 # -> 15 sec
|
||||
! WoodPickaxe = 200 # -> 10 sec
|
||||
! WoodAxe = 200 # -> 10 sec
|
||||
! WoodShovel = 200 # -> 10 sec
|
||||
! WoodHoe = 200 # -> 10 sec
|
||||
! WoodSword = 200 # -> 10 sec
|
||||
|
||||
|
||||
|
@ -1,77 +1,99 @@
|
||||
[Items]
|
||||
air=0
|
||||
rock=1
|
||||
stone=1
|
||||
rock=1
|
||||
granite=1:1
|
||||
polishedgranite=1:2
|
||||
diorite=1:3
|
||||
polisheddiorite=1:4
|
||||
andesite=1:5
|
||||
polishedandesite=1:6
|
||||
grass=2
|
||||
dirt=3
|
||||
coarseddirt=3:1
|
||||
podzol=3:2
|
||||
cobblestone=4
|
||||
cobble=4
|
||||
planks=5
|
||||
appleplanks=5:0
|
||||
oakplanks=5:0
|
||||
appleplanks=5:0
|
||||
spruceplanks=5:1
|
||||
coniferplanks=5:1
|
||||
pineplanks=5:1
|
||||
spruceplanks=5:1
|
||||
darkplanks=5:1
|
||||
birchplanks=5:2
|
||||
lightplanks=5:2
|
||||
jungleplanks=5:3
|
||||
redplanks=5:3
|
||||
|
||||
; Obsolete: do not use "wood", as its meaning is not clear - wiki uses log as wood, we use planks as wood.
|
||||
wood=5
|
||||
|
||||
acaciaplanks=5:4
|
||||
darkoakplanks=5:5
|
||||
bigoakplanks=5:5
|
||||
roofedoakplanks=5:5
|
||||
sapling=6
|
||||
applesapling=6:0
|
||||
oaksapling=6:0
|
||||
applesapling=6:0
|
||||
sprucesapling=6:1
|
||||
conifersapling=6:1
|
||||
pinesapling=6:1
|
||||
sprucesapling=6:1
|
||||
darkplanks=6:1
|
||||
birchsapling=6:2
|
||||
whitesapling=6:2
|
||||
junglesapling=6:3
|
||||
adminium=7
|
||||
redsapling=6:3
|
||||
acaciasapling=6:4
|
||||
darkoaksapling=6:5
|
||||
bigoaksapling=6:5
|
||||
roofedoaksapling=6:5
|
||||
bedrock=7
|
||||
adminium=7
|
||||
water=8
|
||||
flowingwater=8
|
||||
stationarywater=9
|
||||
stillwater=9
|
||||
swater=9
|
||||
stationarywater=9
|
||||
lava=10
|
||||
flowinglava=10
|
||||
stationarylava=11
|
||||
stilllava=11
|
||||
slava=11
|
||||
stationarylava=11
|
||||
sand=12
|
||||
redsand=12:1
|
||||
gravel=13
|
||||
goldore=14
|
||||
ironore=15
|
||||
coalore=16
|
||||
tree=17
|
||||
log=17
|
||||
applelog=17:0
|
||||
tree=17
|
||||
oaklog=17:0
|
||||
applelog=17:0
|
||||
sprucelog=17:1
|
||||
coniferlog=17:1
|
||||
pinelog=17:1
|
||||
sprucelog=17:1
|
||||
darklog=17:1
|
||||
birchlog=17:2
|
||||
whitelog=17:2
|
||||
junglelog=17:3
|
||||
leaves=18
|
||||
appleleaves=18:0
|
||||
oakleaves=18:0
|
||||
appleleaves=18:0
|
||||
spruceleaves=18:1
|
||||
coniferleaves=18:1
|
||||
pineleaves=18:1
|
||||
spruceleaves=18:1
|
||||
darkleaves=18:1
|
||||
birchleaves=18:2
|
||||
whiteleaves=18:2
|
||||
jungleleaves=18:3
|
||||
sponge=19
|
||||
wetsponge=19:1
|
||||
glass=20
|
||||
lapisore=21
|
||||
lapisblock=22
|
||||
dispenser=23
|
||||
sandstone=24
|
||||
normalsandstone=24:0
|
||||
ornamentsandstone=24:1
|
||||
chiseledsandstone=24:1
|
||||
decorativesandstone=24:1
|
||||
ornamentsandstone=24:1
|
||||
smoothsandstone=24:2
|
||||
noteblock=25
|
||||
bedblock=26
|
||||
@ -86,14 +108,16 @@ deadbush=32
|
||||
piston=33
|
||||
pistonextension=34
|
||||
pistonhead=34
|
||||
cloth=35
|
||||
wool=35
|
||||
cloth=35
|
||||
whitewool=35:0
|
||||
orangewool=35:1
|
||||
magentawool=35:2
|
||||
lightbluewool=35:3
|
||||
ltbluewool=35:3
|
||||
yellowwool=35:4
|
||||
limewool=35:5
|
||||
ltbluewool=35:3
|
||||
lightgreenwool=35:5
|
||||
ltgreenwool=35:5
|
||||
pinkwool=35:6
|
||||
@ -107,11 +131,13 @@ lightgraywool=35:8
|
||||
lightgreywool=35:8
|
||||
ltgraywool=35:8
|
||||
ltgreywool=35:8
|
||||
silverwool=35:8
|
||||
cyanwool=35:9
|
||||
purplewool=35:10
|
||||
violetwool=35:10
|
||||
bluewool=35:11
|
||||
darkbluewool=35:11
|
||||
dkbluewool=35:11
|
||||
brownwool=35:12
|
||||
greenwool=35:13
|
||||
darkgreenwool=35:13
|
||||
@ -119,14 +145,12 @@ dkgreenwool=35:13
|
||||
redwool=35:14
|
||||
blackwool=35:15
|
||||
dandelion=37
|
||||
|
||||
; Renamed in 1.7, use "poppy" instead; kept for compatibility reasons, will be removed later on.
|
||||
rose=38
|
||||
|
||||
flower=38
|
||||
poppy=38
|
||||
rose=38
|
||||
flower=38
|
||||
blueorchid=38:1
|
||||
allium=38:2
|
||||
azurebluet=38:3
|
||||
redtulip=38:4
|
||||
orangetulip=38:5
|
||||
whitetulip=38:6
|
||||
@ -134,11 +158,12 @@ pinktulip=38:7
|
||||
oxeyedaisy=38:8
|
||||
brownmushroom=39
|
||||
redmushroom=40
|
||||
gold=41
|
||||
goldblock=41
|
||||
iron=42
|
||||
gold=41
|
||||
ironblock=42
|
||||
iron=42
|
||||
doubleslab=43
|
||||
doublestep=43
|
||||
stonedoubleslab=43:0
|
||||
sandstonedoubleslab=43:1
|
||||
wooddoubleslab=43:2
|
||||
@ -168,18 +193,19 @@ obsidian=49
|
||||
torch=50
|
||||
fire=51
|
||||
mobspawner=52
|
||||
oakwoodstairs=53
|
||||
woodstairs=53
|
||||
chest=54
|
||||
redstonedust=55
|
||||
redstonewire=55
|
||||
redstonedust=55
|
||||
diamondore=56
|
||||
diamondblock=57
|
||||
workbench=58
|
||||
crop=59
|
||||
crops=59
|
||||
soil=60
|
||||
farmland=60
|
||||
tilleddirt=60
|
||||
soil=60
|
||||
furnace=61
|
||||
litfurnace=62
|
||||
signblock=63
|
||||
@ -191,11 +217,11 @@ track=66
|
||||
tracks=66
|
||||
cobblestonestairs=67
|
||||
stairs=67
|
||||
signblocktop=68
|
||||
wallsign=68
|
||||
signblocktop=68
|
||||
lever=69
|
||||
rockplate=70
|
||||
stoneplate=70
|
||||
rockplate=70
|
||||
irondoorblock=71
|
||||
woodplate=72
|
||||
redstoneore=73
|
||||
@ -212,13 +238,13 @@ reedblock=83
|
||||
jukebox=84
|
||||
fence=85
|
||||
pumpkin=86
|
||||
netherstone=87
|
||||
netherrack=87
|
||||
hellrock=87
|
||||
slowsand=88
|
||||
netherstone=87
|
||||
soulsand=88
|
||||
lightstone=89
|
||||
slowsand=88
|
||||
glowstone=89
|
||||
lightstone=89
|
||||
portal=90
|
||||
jackolantern=91
|
||||
jacko=91
|
||||
@ -227,22 +253,39 @@ whitestainedglass=95
|
||||
orangestainedglass=95:1
|
||||
magentastainedglass=95:2
|
||||
lightbluestainedglass=95:3
|
||||
ltbluestainedglass=95:3
|
||||
yellowstainedglass=95:4
|
||||
limestainedglass=95:5
|
||||
lightgreenstainedglass=95:5
|
||||
ltgreenstainedglass=95:5
|
||||
pinkstainedglass=95:6
|
||||
graystainedglass=95:7
|
||||
greystainedglass=95:7
|
||||
darkgraystainedglass=95:7
|
||||
darkgreystainedglass=95:7
|
||||
dkgraystainedglass=95:7
|
||||
dkgreystainedglass=95:7
|
||||
lightgraystainedglass=95:8
|
||||
lightgreystainedglass=95:8
|
||||
ltgraystainedglass=95:8
|
||||
ltgreystainedglass=95:8
|
||||
silverstainedglass=95:8
|
||||
cyanstainedglass=95:9
|
||||
purplestainedglass=95:10
|
||||
violetstainedglass=95:10
|
||||
bluestainedglass=95:11
|
||||
darkbluestainedglass=95:11
|
||||
dkbluestainedglass=95:11
|
||||
brownstainedglass=95:12
|
||||
greenstainedglass=95:13
|
||||
darkgreenstainedglass=95:13
|
||||
dkgreenstainedglass=95:13
|
||||
redstainedglass=95:14
|
||||
blackstainedglass=95:15
|
||||
trapdoor=96
|
||||
silverfishblock=97
|
||||
stonebricks=98
|
||||
stonebrick=98
|
||||
stonebricks=98
|
||||
mossystonebrick=98:1
|
||||
crackedstonebrick=98:2
|
||||
chiseledstonebrick=98:3
|
||||
@ -272,15 +315,50 @@ endstone=121
|
||||
dragonegg=122
|
||||
redstonelamp=123
|
||||
redstonelampoff=123
|
||||
litredstonelamp=124
|
||||
redstonelampon=124
|
||||
woodendoubleslab=125
|
||||
oakwooddoubleslab=125:0
|
||||
appledoublewoodslab=125:0
|
||||
sprucewooddoubleslab=125:1
|
||||
coniferwooddoubleslab=125:1
|
||||
pinewooddoubleslab=125:1
|
||||
darkwooddoubleslab=125:1
|
||||
birchwooddoubleslab=125:2
|
||||
whitewooddoubleslab=125:2
|
||||
junglewooddoubleslab=125:3
|
||||
acaciawooddoubleslab=125:4
|
||||
darkoakwooddoubleslab=125:5
|
||||
bigoakwooddoubleslab=125:5
|
||||
roofedwooddoubleslab=125:5
|
||||
woodenslab=126
|
||||
oakwoodslab=126:0
|
||||
applewoodslab=126:0
|
||||
sprucewoodslab=126:1
|
||||
coniferwoodslab=126:1
|
||||
pinewoodslab=126:1
|
||||
darkwoodslab=126:1
|
||||
birchwoodslab=126:2
|
||||
whitewoodslab=126:2
|
||||
junglewoodslab=126:3
|
||||
acaciawoodslab=126:4
|
||||
darkoakwoodslab=126:5
|
||||
roofedwoodslab=126:5
|
||||
bigoakwoodslab=126:5
|
||||
cocoabeans=127
|
||||
sandstonestairs=128
|
||||
emeraldore=129
|
||||
enderchest=130
|
||||
tripwirehook=131
|
||||
tripwire=132
|
||||
emeraldblock=133
|
||||
sprucewoodstairs=134
|
||||
coniferwoodstairs=134
|
||||
pinewoodstairs=134
|
||||
darkwoodstairs=134
|
||||
birchwoodstairs=135
|
||||
whitewoodstairs=135
|
||||
junglewoodstairs=136
|
||||
commandblock=137
|
||||
beacon=138
|
||||
cobblestonewall=139
|
||||
@ -292,6 +370,7 @@ woodenbutton=143
|
||||
skeletonhead=144
|
||||
witherhead=144:1
|
||||
zombiehead=144:2
|
||||
playerhead=144:3
|
||||
humanhead=144:3
|
||||
stevehead=144:3
|
||||
creeperhead=144:4
|
||||
@ -315,40 +394,162 @@ whitestainedclay=159
|
||||
orangestainedclay=159:1
|
||||
magentastainedclay=159:2
|
||||
lightbluestainedclay=159:3
|
||||
ltbluestainedclay=159:3
|
||||
yellowstainedclay=159:4
|
||||
limestainedclay=159:5
|
||||
lightgreenstainedclay=159:5
|
||||
ltgreenstainedclay=159:5
|
||||
pinkstainedclay=159:6
|
||||
graystainedclay=159:7
|
||||
greystainedclay=159:7
|
||||
darkgraystainedclay=159:7
|
||||
darkgreystainedclay=159:7
|
||||
dkgraystainedclay=159:7
|
||||
dkgreystainedclay=159:7
|
||||
lightgraystainedclay=159:8
|
||||
lightgreystainedclay=159:8
|
||||
ltgraystainedclay=159:8
|
||||
ltgreystainedclay=159:8
|
||||
silverstainedclay=159:8
|
||||
cyanstainedclay=159:9
|
||||
purplestainedclay=159:10
|
||||
violetstainedclay=159:10
|
||||
bluestainedclay=159:11
|
||||
darkbluestainedclay=159:11
|
||||
dkbluestainedclay=159:11
|
||||
brownstainedclay=159:12
|
||||
greenstainedclay=159:13
|
||||
darkgreenstainedclay=159:13
|
||||
dkgreenstainedclay=159:13
|
||||
redstainedclay=159:14
|
||||
blackstainedclay=159:15
|
||||
whitestainedglasspane=160
|
||||
orangestainedglasspane=160:1
|
||||
magentastainedglasspane=160:2
|
||||
lightbluestainedglasspane=160:3
|
||||
ltbluestainedglasspane=160:3
|
||||
yellowstainedglasspane=160:4
|
||||
limestainedglasspane=160:5
|
||||
lightgreenstainedglasspane=160:5
|
||||
ltgreenstainedglasspane=160:5
|
||||
pinkstainedglasspane=160:6
|
||||
graystainedglasspane=160:7
|
||||
greystainedglasspane=160:7
|
||||
darkgraystainedglasspane=160:7
|
||||
darkgreystainedglasspane=160:7
|
||||
dkgraystainedglasspane=160:7
|
||||
dkgreystainedglasspane=160:7
|
||||
lightgraystainedglasspane=160:8
|
||||
lightgreystainedglasspane=160:8
|
||||
ltgraystainedglasspane=160:8
|
||||
ltgreystainedglasspane=160:8
|
||||
silverstainedglasspane=160:8
|
||||
cyanstainedglasspane=160:9
|
||||
purplestainedglasspane=160:10
|
||||
violetstainedglasspane=160:10
|
||||
bluestainedglasspane=160:11
|
||||
darkbluestainedglasspane=160:11
|
||||
dkbluestainedglasspane=160:11
|
||||
brownstainedglasspane=160:12
|
||||
greenstainedglasspane=160:13
|
||||
darkgreenstainedglasspane=160:13
|
||||
dkgreenstainedglasspane=160:13
|
||||
redstainedglasspane=160:14
|
||||
blackstainedglasspane=160:15
|
||||
acaciawood=162
|
||||
darkoakwood=162:1
|
||||
acaciawoodenstairs=163
|
||||
darkoakwoodenstairs=164
|
||||
newleaves=161
|
||||
acacialeaves=161:0
|
||||
darkoakleaves=161:1
|
||||
bigoakleaves=161:1
|
||||
roofedoakleaves=161:1
|
||||
newlog=162
|
||||
acacialog=162:0
|
||||
darkoaklog=162:1
|
||||
bigoaklog=162:1
|
||||
roofedoaklog=162:1
|
||||
acaciawoodstairs=163
|
||||
darkoakwoodstairs=164
|
||||
bigoakwoodstiars=164
|
||||
roofedoakwoodstairs=164
|
||||
slimeblock=165
|
||||
barrier=166
|
||||
irontrapdoor=167
|
||||
prismarine=168
|
||||
prismarinebricks=168:1
|
||||
darkprismarine=168:2
|
||||
sealantern=169
|
||||
haybale=170
|
||||
carpet=171
|
||||
whitecarpet=171:0
|
||||
orangecarpet=171:1
|
||||
magentacarpet=171:2
|
||||
lightbluecarpet=171:3
|
||||
ltbluecarpet=171:3
|
||||
yellowcarpet=171:4
|
||||
limecarpet=171:5
|
||||
lightgreencarpet=171:5
|
||||
ltgreencarpet=171:5
|
||||
pinkcarpet=171:6
|
||||
graycarpet=171:7
|
||||
greycarpet=171:7
|
||||
darkgraycarpet=171:7
|
||||
darkgreycarpet=171:7
|
||||
dkgraycarpet=171:7
|
||||
dkgreycarpet=171:7
|
||||
lightgraycarpet=171:8
|
||||
lightgreycarpet=171:8
|
||||
ltgraycarpet=171:8
|
||||
ltgreycarpet=171:8
|
||||
silvercarpet=171:8
|
||||
cyancarpet=171:9
|
||||
purplecarpet=171:10
|
||||
violetcarpet=171:10
|
||||
bluecarpet=171:11
|
||||
darkbluecarpet=171:11
|
||||
dkbluecarpet=171:11
|
||||
browncarpet=171:12
|
||||
greencarpet=171:13
|
||||
darkgreencarpet=171:13
|
||||
dkgreencarpet=171:13
|
||||
redcarpet=171:14
|
||||
blackcarpet=171:15
|
||||
hardenedclay=172
|
||||
coalblock=173
|
||||
packedice=174
|
||||
doubleplant=175
|
||||
sunflower=175:0
|
||||
lilac=175:1
|
||||
doubletallgrass=175:2
|
||||
doubletallfern=175:3
|
||||
rosebush=175:4
|
||||
peony=175:5
|
||||
redsandstone=179
|
||||
chiseledredsandstone=179:1
|
||||
smoothredsandstone=179:2
|
||||
redsandstonestairs=180
|
||||
newstoneslab=182
|
||||
redsandstoneslab=182:0
|
||||
sprucefencegate=183
|
||||
coniferfencegate=183
|
||||
pinefencegate=183
|
||||
darkfencegate=183
|
||||
birchfencegate=184
|
||||
whitefencegate=184
|
||||
junglefencegate=185
|
||||
darkoakfencegate=186
|
||||
bigoakfencegate=186
|
||||
roofedoakfencegate=186
|
||||
acaciafencegate=187
|
||||
sprucefence=188
|
||||
coniferfence=188
|
||||
pinefence=188
|
||||
darkfence=188
|
||||
birchfence=189
|
||||
whitefence=189
|
||||
junglefence=190
|
||||
darkoakfence=191
|
||||
bigoakfence=191
|
||||
roofedoakfence=191
|
||||
acaciafence=192
|
||||
ironshovel=256
|
||||
ironspade=256
|
||||
ironpickaxe=257
|
||||
@ -361,7 +562,6 @@ redapple=260
|
||||
bow=261
|
||||
arrow=262
|
||||
coal=263
|
||||
coalblock=173
|
||||
charcoal=263:1
|
||||
diamond=264
|
||||
ironingot=265
|
||||
@ -374,9 +574,9 @@ ironsword=267
|
||||
woodensword=268
|
||||
woodsword=268
|
||||
woodenshovel=269
|
||||
woodspade=269
|
||||
woodshovel=269
|
||||
woodenspade=269
|
||||
woodspade=269
|
||||
woodenpickaxe=270
|
||||
woodpickaxe=270
|
||||
woodenpick=270
|
||||
@ -404,8 +604,8 @@ soup=282
|
||||
goldensword=283
|
||||
goldsword=283
|
||||
goldenshovel=284
|
||||
goldshovel=284
|
||||
goldenspade=284
|
||||
goldshovel=284
|
||||
goldspade=284
|
||||
goldenpickaxe=285
|
||||
goldpickaxe=285
|
||||
@ -416,13 +616,13 @@ goldaxe=286
|
||||
string=287
|
||||
feather=288
|
||||
gunpowder=289
|
||||
woodhoe=290
|
||||
woodenhoe=290
|
||||
woodhoe=290
|
||||
stonehoe=291
|
||||
ironhoe=292
|
||||
diamondhoe=293
|
||||
goldhoe=294
|
||||
goldenhoe=294
|
||||
goldhoe=294
|
||||
seeds=295
|
||||
wheat=296
|
||||
bread=297
|
||||
@ -451,19 +651,24 @@ goldpants=316
|
||||
goldenboots=317
|
||||
goldboots=317
|
||||
flint=318
|
||||
porkchop=319
|
||||
meat=319
|
||||
pork=319
|
||||
cookedporkchop=320
|
||||
cookedmeat=320
|
||||
cookedpork=320
|
||||
painting=321
|
||||
paintings=321
|
||||
goldenapple=322
|
||||
goldapple=322
|
||||
notchapple=322:1
|
||||
enchantedgoldenapple=322:1
|
||||
enchantedgoldapple=322:1
|
||||
sign=323
|
||||
wooddoor=324
|
||||
oakdoor=324
|
||||
appledoor=324
|
||||
woodendoor=324
|
||||
wooddoor=324
|
||||
bucket=325
|
||||
waterbucket=326
|
||||
lavabucket=327
|
||||
@ -477,32 +682,38 @@ leather=334
|
||||
milkbucket=335
|
||||
brick=336
|
||||
clay=337
|
||||
reed=338
|
||||
sugarcane=338
|
||||
reed=338
|
||||
paper=339
|
||||
book=340
|
||||
slimeorb=341
|
||||
slimeball=341
|
||||
slimeorb=341
|
||||
storageminecart=342
|
||||
poweredminecart=343
|
||||
egg=344
|
||||
compass=345
|
||||
fishingrod=346
|
||||
watch=347
|
||||
glowstonedust=348
|
||||
lightstonedust=348
|
||||
lightdust=348
|
||||
glowstonedust=348
|
||||
glowdust=348
|
||||
rawfish=349
|
||||
fish=349
|
||||
rawfish=349
|
||||
rawsalmon=349:1
|
||||
clownfish=349:2
|
||||
pufferfish=349:3
|
||||
cookedfish=350
|
||||
cookedsalmon=350:1
|
||||
dye=351
|
||||
inksac=351:0
|
||||
blackdye=351:0
|
||||
reddye=351:1
|
||||
rosered=351:1
|
||||
greendye=351:2
|
||||
reddye=351:1
|
||||
cactusgreen=351:2
|
||||
greendye=351:2
|
||||
darkgreendye=351:2
|
||||
dkgreendye=351:2
|
||||
cocoabeans=351:3
|
||||
browndye=351:3
|
||||
lapislazuli=351:4
|
||||
@ -512,12 +723,13 @@ dkbluedye=351:4
|
||||
purpledye=351:5
|
||||
violetdye=351:5
|
||||
cyandye=351:6
|
||||
lightgreydye=351:7
|
||||
lightgraydye=351:7
|
||||
ltgreydye=351:7
|
||||
lightgreydye=351:7
|
||||
ltgraydye=351:7
|
||||
greydye=351:8
|
||||
ltgreydye=351:7
|
||||
silverdye=351:7
|
||||
graydye=351:8
|
||||
greydye=351:8
|
||||
darkgreydye=351:8
|
||||
darkgraydye=351:8
|
||||
dkgreydye=351:8
|
||||
@ -583,6 +795,7 @@ goldencarrot=396
|
||||
skeletonhead=397
|
||||
witherhead=397:1
|
||||
zombiehead=397:2
|
||||
playerhead=397:3
|
||||
stevehead=397:3
|
||||
creeperhead=397:4
|
||||
carrotonastick=398
|
||||
@ -596,13 +809,68 @@ netherbrickitem=405
|
||||
netherquartz=406
|
||||
tntminecart=407
|
||||
hopperminecart=408
|
||||
prismarineshard=409
|
||||
prismarinecrystals=410
|
||||
rawrabbit=411
|
||||
cookedrabbit=412
|
||||
rabbitstew=413
|
||||
rabbitsoup=413
|
||||
rabbitsfood=414
|
||||
rabbithide=415
|
||||
armorstand=416
|
||||
ironhorsearmor=417
|
||||
goldhorsearmor=418
|
||||
diamondhorsearmor=419
|
||||
lead=420
|
||||
nametag=421
|
||||
commandblockminecart=422
|
||||
|
||||
rawmutton=423
|
||||
cookedmutton=424
|
||||
banner=425
|
||||
blackbanner=415:0
|
||||
redbanner=415:1
|
||||
greenbanner=415:2
|
||||
darkgreenbanner=415:2
|
||||
dkgreenbanner=415:2
|
||||
brownbanner=415:3
|
||||
bluebanner=415:4
|
||||
darkbluebanner=415:4
|
||||
dkbluebanner=415:4
|
||||
purplebanner=415:5
|
||||
violetbanner=415:5
|
||||
cyanbanner=415:6
|
||||
lightgraybanner=415:7
|
||||
lightgreybanner=415:7
|
||||
ltgraybanner=415:7
|
||||
ltgreybanner=415:7
|
||||
silverbanner=415:7
|
||||
graybanner=415:8
|
||||
greybanner=415:8
|
||||
darkgraybanner=415:8
|
||||
darkgreybanner=415:8
|
||||
dkgraybanner=415:8
|
||||
dkgreybanner=415:8
|
||||
pinkbanner=415:9
|
||||
limebanner=415:10
|
||||
lightgreenbanner=415:10
|
||||
ltgreenbanner=415:10
|
||||
yellowbanner=415:11
|
||||
lightbluebanner=415:12
|
||||
ltbluebanner=415:12
|
||||
magentabanner=415:13
|
||||
orangebanner=415:14
|
||||
whitebanner=415:15
|
||||
sprucedoor=427
|
||||
coniferdoor=427
|
||||
pinedoor=427
|
||||
darkdoor=427
|
||||
birchdoor=428
|
||||
whitedoor=428
|
||||
jungledoor=429
|
||||
acaciadoor=430
|
||||
darkoakdoor=431
|
||||
bigoakdoor=431
|
||||
roofedoakdoor=431
|
||||
goldrecord=2256
|
||||
greenrecord=2257
|
||||
blocksrecord=2258
|
||||
@ -617,4 +885,3 @@ wardrecord=2265
|
||||
|
||||
|
||||
|
||||
|
||||
|
603
MCServer/lang/items_de.ini
Normal file
603
MCServer/lang/items_de.ini
Normal file
@ -0,0 +1,603 @@
|
||||
[Items]
|
||||
luft=0
|
||||
stein=1
|
||||
granit=1:1
|
||||
poliertergranit=1:2
|
||||
diorit=1:3
|
||||
polierterdiorit=1:4
|
||||
andesit=1:5
|
||||
polierterandesit=1:6
|
||||
grasblock=2
|
||||
erde=3
|
||||
grobeerde=3:1
|
||||
podsol=3:2
|
||||
bruchstein=4
|
||||
holzbretter=5
|
||||
eichenholzbretter=5:0
|
||||
fichtenholzbretter=5:1
|
||||
birkenholzbretter=5:2
|
||||
tropenholzbretter=5:3
|
||||
akazienholzbretter=5:4
|
||||
schwarzeichenholzbretter=5:5
|
||||
setzling=6
|
||||
eichensetzling=6:0
|
||||
fichtensetzling=6:1
|
||||
birkensetzling=6:2
|
||||
tropensetzling=6:3
|
||||
akaziensetzling=6:4
|
||||
schwarzeichensetzling=6:5
|
||||
grundgestein=7
|
||||
wasser=8
|
||||
fliessendeswasser=8
|
||||
stehendeswasser=9
|
||||
stilleswasser=9
|
||||
swasser=9
|
||||
lava=10
|
||||
fliessendelava=10
|
||||
stehendelava=11
|
||||
stillelava=11
|
||||
slava=11
|
||||
sand=12
|
||||
rotersand=12:1
|
||||
kies=13
|
||||
golderz=14
|
||||
eisenerz=15
|
||||
kohleerz=16
|
||||
stamm=17
|
||||
eichenholz=17:0
|
||||
fichtenholz=17:1
|
||||
birkenholz=17:2
|
||||
tropenholz=17:3
|
||||
laub=18
|
||||
eichenlaub=18:0
|
||||
fichtenlaub=18:1
|
||||
birkenlaub=18:2
|
||||
tropenlaub=18:3
|
||||
schwamm=19
|
||||
nasserschwamm=19:1
|
||||
glas=20
|
||||
lapislazulierz=21
|
||||
lapislazuliblock=22
|
||||
werfer=23
|
||||
sandstein=24
|
||||
normalersandstein=24:0
|
||||
gemeisseltersandstein=24:1
|
||||
glattersandstein=24:2
|
||||
notenblock=25
|
||||
bettblock=26
|
||||
antriebsschiene=27
|
||||
sensorschiene=28
|
||||
klebrigerkolben=29
|
||||
spinnenweben=30
|
||||
gras=31
|
||||
gras=31:1
|
||||
farn=31:2
|
||||
toterbusch=32
|
||||
kolben=33
|
||||
kolbenkopf=34
|
||||
wolle=35
|
||||
weissewolle=35:0
|
||||
orangenewolle=35:1
|
||||
magentawolle=35:2
|
||||
hellblauewolle=35:3
|
||||
gelbewolle=35:4
|
||||
hellgruene=35:5
|
||||
rosawolle=35:6
|
||||
grauwool=35:7
|
||||
greywool=35:7
|
||||
grauewolle=35:7
|
||||
hellgrauewolle=35:8
|
||||
tuerkisewolle=35:9
|
||||
violettewolle=35:10
|
||||
blauewolle=35:11
|
||||
braunewolle=35:12
|
||||
gruenewolle=35:13
|
||||
rotewolle=35:14
|
||||
schwarzewolle=35:15
|
||||
loewenzahn=37
|
||||
blume=38
|
||||
mohn=38:0
|
||||
blaueorchidee=38:1
|
||||
sternlauch=38:2
|
||||
porzellansternchen=38:3
|
||||
rotetulpe=38:4
|
||||
orangenetulpe=38:5
|
||||
weissetulpe=38:6
|
||||
rosatulpe=38:7
|
||||
margerite=38:8
|
||||
braunerpilz=39
|
||||
roterpilz=40
|
||||
goldblock=41
|
||||
eisenblock=42
|
||||
doppelstufe=43
|
||||
doppelsteinstufe=43:0
|
||||
doppelsandsteinstufe=43:1
|
||||
doppelholzstufe=43:2
|
||||
doppelbruchsteinstufe=43:3
|
||||
doppelziegelstufe=43:4
|
||||
doppelsteinziegelstufe=43:5
|
||||
doppelnetherziegelstufe=43:6
|
||||
doppelquarzstufe=43:7
|
||||
stufe=44
|
||||
steinstufe=44:0
|
||||
sandsteinstufe=44:1
|
||||
holzstufe=44:2
|
||||
bruchsteinstufe=44:3
|
||||
ziegelstufe=44:4
|
||||
steinziegelstufe=44:5
|
||||
netherziegelstufe=44:6
|
||||
quarzstufe=44:7
|
||||
ziegelsteine=45
|
||||
tnt=46
|
||||
buecherregal=47
|
||||
bemoosterbruchstein=48
|
||||
obsidian=49
|
||||
fackel=50
|
||||
feuer=51
|
||||
monsterspawner=52
|
||||
eichenholztreppe=53
|
||||
kiste=54
|
||||
rotstonekabel=55
|
||||
diamanterz=56
|
||||
diamantblock=57
|
||||
werkbank=58
|
||||
ernte=59
|
||||
farmland=60
|
||||
ofen=61
|
||||
brennenderofen=62
|
||||
schildblock=63
|
||||
holztuerblock=64
|
||||
leiter=65
|
||||
schiene=66
|
||||
bruchsteintreppe=67
|
||||
wandschild=68
|
||||
schalter=69
|
||||
steindruckplatte=70
|
||||
eisentuerblock=71
|
||||
holzdruckplatte=72
|
||||
rotstoneerz=73
|
||||
leuchtendesrotstoneerz=74
|
||||
erloschenerotstonefackel=75
|
||||
rotstonefackel=76
|
||||
setinknopf=77
|
||||
schnee=78
|
||||
eis=79
|
||||
schneeblock=80
|
||||
kaktus=81
|
||||
ton=82
|
||||
zuckerrohrblock=83
|
||||
plattenspieler=84
|
||||
eichenholzzaun=85
|
||||
kuerbis=86
|
||||
netherstein=87
|
||||
selensand=88
|
||||
leuchtstein=89
|
||||
portal=90
|
||||
kürbislaterne=91
|
||||
kuchenlock=92
|
||||
weissesglas=95
|
||||
orangenesglas=95:1
|
||||
magentaglas=95:2
|
||||
hellblauesglas=95:3
|
||||
gelbesglas=95:4
|
||||
hellgruenesglas=95:5
|
||||
rosagerfaerbtglas=95:6
|
||||
grauesglas=95:7
|
||||
hellgrauesglas=95:8
|
||||
tuerkisesglas=95:9
|
||||
violettesglas=95:10
|
||||
blauesglas=95:11
|
||||
braunesglas=95:12
|
||||
gruenesglas=95:13
|
||||
rotesglas=95:14
|
||||
schwarzesglas=95:15
|
||||
falltuer=96
|
||||
silberfischblock=97
|
||||
steinziegel=98
|
||||
bemoostesteinziegel=98:1
|
||||
rissigesteinziegel=98:2
|
||||
gemeisseltesteinziegel=98:3
|
||||
braunerpilzblock=99
|
||||
roterpilzblock=100
|
||||
eisengitter=101
|
||||
glasscheibe=102
|
||||
melone=103
|
||||
kuerbispflanze=104
|
||||
melonenpflanze=105
|
||||
ranken=106
|
||||
eichenholzzauntor=107
|
||||
ziegeltreppe=108
|
||||
steinziegeltreppe=109
|
||||
myzel=110
|
||||
seerosenblatt=111
|
||||
netherziegel=112
|
||||
netherziegelzaun=113
|
||||
netherziegeltreppe=114
|
||||
netherwarzenblock=115
|
||||
zaubertisch=116
|
||||
braustandblock=117
|
||||
kesselblock=118
|
||||
endportal=119
|
||||
endportalrahmen=120
|
||||
endstein=121
|
||||
drachenei=122
|
||||
redstonelampe=123
|
||||
erlosscheneredstonelampe=124
|
||||
doppelholzstufe=125
|
||||
doppeleichenholzstufe=125:0
|
||||
doppelfichtenholzstufe=125:1
|
||||
doppelbirkenholzstufe=125:2
|
||||
doppeltropenholzstufe=125:3
|
||||
doppelakazienholzstufe=125:4
|
||||
doppelschwarzeichenstufe=125:5
|
||||
holzstufe=126
|
||||
eichenholzstufe=126:0
|
||||
fichtenholzstufe=126:1
|
||||
birkenholzstufe=126:2
|
||||
tropenholzstufe=126:3
|
||||
akazienholzstufe=126:4
|
||||
schwarzeichenholzstufe=126:5
|
||||
kakaobohnen=127
|
||||
sandsteintreppe=128
|
||||
smaragderz=129
|
||||
endertruhe=130
|
||||
haken=131
|
||||
stolperdraht=132
|
||||
smaragdblock=133
|
||||
fichtenholztreppe=134
|
||||
birkenholztreppe=135
|
||||
tropenholztreppe=136
|
||||
kommandoblock=137
|
||||
leuchtfeuer=138
|
||||
bruchsteinmauer=139
|
||||
bemoostebruchsteinmauer=139:1
|
||||
blumentopfblock=140
|
||||
karottenpflanze=141
|
||||
kartoffelpflanze=142
|
||||
knopf=143
|
||||
skelettschaedel=144
|
||||
witherskelettschaedel=144:1
|
||||
zombieschaedel=144:2
|
||||
schaedel=144:3
|
||||
creeperschaedel=144:4
|
||||
amboss=145
|
||||
redstonetruhe=146
|
||||
waegeplatteniedrigegewichte=147 # WTF, that names are so stupid...
|
||||
waegeplattehohegewichte=148
|
||||
inaktiverkomparator=149
|
||||
aktiverkomparator=150
|
||||
tageslichtsensor=151
|
||||
redstoneblock=152
|
||||
netherquarzerz=153
|
||||
trichter=154
|
||||
quarzblock=155
|
||||
gemeisselterquarzblock=155:1
|
||||
quarzsaeule=155:2
|
||||
quarztreppe=156
|
||||
aktivierungsschiene=157
|
||||
spender=158
|
||||
weissgerfaerbterton=159
|
||||
orangegerfaerbterton=159:1
|
||||
magentagerfaerbterton=159:2
|
||||
hellblaugerfaerbterton=159:3
|
||||
gelbgerfaerbterton=159:4
|
||||
hellgruengerfaerbterton=159:5
|
||||
rosagerfaerbterton=159:6
|
||||
graugerfaerbterton=159:7
|
||||
hellgraugefaerbterton=159:8
|
||||
tuerkisgerfaerbterton=159:9
|
||||
purplegerfaerbterton=159:10
|
||||
violettegerfaerbterton=159:10
|
||||
blaugerfaerbterton=159:11
|
||||
braungerfaerbterton=159:12
|
||||
gruengerfaerbterton=159:13
|
||||
rotgerfaerbterton=159:14
|
||||
schwarzgerfaerbterton=159:15
|
||||
weisseglasscheibe=160
|
||||
orangeneglasscheibe=160:1
|
||||
magentaglasscheibe=160:2
|
||||
hellblaueglasscheibe=160:3
|
||||
gelbeglasscheibe=160:4
|
||||
hellgrueneglasscheibe=160:5
|
||||
rosaglasscheibe=160:6
|
||||
graueglasscheibe=160:7
|
||||
hellgraueglasscheibe=160:8
|
||||
tuerkiseglasscheibe=160:9
|
||||
violetteglasscheibe=160:10
|
||||
blaueglasscheibe=160:11
|
||||
brauneglasscheibe=160:12
|
||||
grueneglasscheibe=160:13
|
||||
roteglasscheibe=160:14
|
||||
schwarzeglasscheibe=160:15
|
||||
neueslaub=161
|
||||
akazienlaub=161:0
|
||||
schwarzeichenlaub=161:1
|
||||
neuestaemme=162
|
||||
akazienholz=162:0
|
||||
schwarzeichenholz=162:1
|
||||
akazientreppe=163
|
||||
schwarzeichentreppe=164
|
||||
schleimblock=165
|
||||
bartriere=166
|
||||
eisenfalltür=167
|
||||
prismarin=168
|
||||
prismarinziegel=168:1
|
||||
dunklerprismarin=168:2
|
||||
seelaterne=169
|
||||
strohballen=170
|
||||
teppich=171
|
||||
weisserteppich=171:0
|
||||
orangenerteppich=171:1
|
||||
magentateppich=171:2
|
||||
hellblauerteppich=171:3
|
||||
gelberteppich=171:4
|
||||
hellgruenerteppich=171:5
|
||||
rosateppich=171:6
|
||||
grauerteppich=171:7
|
||||
hellgrauerteppich=171:8
|
||||
tuerkiserteppich=171:9
|
||||
violetterteppich=171:10
|
||||
blauerteppich=171:11
|
||||
braunerteppich=171:12
|
||||
gruenerteppich=171:13
|
||||
roterteppich=171:14
|
||||
schwarzerteppich=171:15
|
||||
gebrannterton=172
|
||||
kohleblock=173
|
||||
packeis=174
|
||||
doppelpflanze=175
|
||||
sonnenblume=175:0
|
||||
Flieder=175:1
|
||||
hohesgras=175:2
|
||||
grosserfarn=175:3
|
||||
rosenstrauch=175:4
|
||||
pfingstrose=175:5
|
||||
rotersandstein=179
|
||||
gemeisselterrotersandstein=179:1
|
||||
glatterrotersandstein=179:2
|
||||
rotesandsteintreppe=180
|
||||
neuesteinstufe=182
|
||||
rotesandsteinstufe=182:0
|
||||
fichtenzauntor=183
|
||||
birkenzauntor=184
|
||||
tropenzauntor=185
|
||||
schwarzeichenzauntor=186
|
||||
akazienzauntor=187
|
||||
fichtenzaun=188
|
||||
birkenzaun=189
|
||||
tropenzaun=190
|
||||
schwarzeichenzaun=191
|
||||
akazienzaun=192
|
||||
eisenschaufel=256
|
||||
eisenspitzhacke=257
|
||||
eisenaxt=258
|
||||
feuerzeug=259
|
||||
apfel=260
|
||||
bogen=261
|
||||
pfeil=262
|
||||
kohle=263
|
||||
holzkohle=263:1
|
||||
diamant=264
|
||||
eisenbarren=265
|
||||
goldbarren=266
|
||||
eisenschwert=267
|
||||
holzschwert=268
|
||||
holzschaufel=269
|
||||
holzspitzhacke=270
|
||||
holzaxt=271
|
||||
steinschwert=272
|
||||
steinschaufel=273
|
||||
steinspitzhacke=274
|
||||
steinaxt=275
|
||||
diamantschwert=276
|
||||
diamantschaufel=277
|
||||
diamantspitzhacke=278
|
||||
diamantaxt=279
|
||||
stock=280
|
||||
schuessel=281
|
||||
pilzsuppe=282
|
||||
goldschwert=283
|
||||
goldschaufel=284
|
||||
goldspitzhacke=285
|
||||
goldaxt=286
|
||||
faden=287
|
||||
feder=288
|
||||
schwarzpulver=289
|
||||
holzhacke=290
|
||||
steinhacke=291
|
||||
eisenhacke=292
|
||||
diamanthacke=293
|
||||
goldhacke=294
|
||||
samen=295
|
||||
weizen=296
|
||||
brot=297
|
||||
lederkappe=298
|
||||
lederjacke=299
|
||||
lederhose=300
|
||||
lederstiefel=301
|
||||
kettenhaube=302
|
||||
kettenhemd=303
|
||||
kettenhose=304
|
||||
kettenstiefel=305
|
||||
eisenhelm=306
|
||||
eisenbrustplatte=307
|
||||
eisenbeinschutz=308
|
||||
eisenstiefel=309
|
||||
diamanthelm=310
|
||||
diamantbrustplatte=311
|
||||
diamantbeinschutz=312
|
||||
diamantstiefel=313
|
||||
goldhelm=314
|
||||
goldharnisch=315
|
||||
goldbeinschutz=316
|
||||
goldstiefel=317
|
||||
goldboots=317
|
||||
feuerstein=318
|
||||
rohesschweinefleisch=319
|
||||
gebratenesschweinefleisch=320
|
||||
gemaelde=321
|
||||
goldenerapfel=322
|
||||
goldenerapfel=322:1
|
||||
schild=323
|
||||
eichenholztuer=324
|
||||
eimer=325
|
||||
wassereimer=326
|
||||
lavaeimer=327
|
||||
lore=328
|
||||
sattel=329
|
||||
eisentuer=330
|
||||
redstone=331
|
||||
schneeballl=332
|
||||
boot=333
|
||||
leder=334
|
||||
milcht=335
|
||||
ziegel=336
|
||||
ton=337
|
||||
zuckercane=338
|
||||
papier=339
|
||||
buch=340
|
||||
schleimball=341
|
||||
gueterlore=342
|
||||
angetriebenelore=343
|
||||
ei=344
|
||||
kompass=345
|
||||
angel=346
|
||||
uhr=347
|
||||
glowstonestaub=348
|
||||
fisch=349
|
||||
roherfisch=349
|
||||
roherlachs=349:1
|
||||
clownfisch=349:2
|
||||
kugelfisch=349:3
|
||||
gebratenerfisch=350
|
||||
gebratenerlachs=350:1
|
||||
farbe=351
|
||||
tintenbeutel=351:0
|
||||
rosenrot=351:1
|
||||
kaktusgruen=351:2
|
||||
kakaobohnen=351:3
|
||||
lapislazuli=351:4
|
||||
violetterfarbstoff=351:5
|
||||
tuerkiserfarbstoff=351:6
|
||||
hellgrauerfarbstoff=351:7
|
||||
grauerfarbstoff=351:8
|
||||
rosafarbstoff=351:9
|
||||
hellgruenerfarbstoff=351:10
|
||||
gelberfarbstoff=351:11
|
||||
hellblauerfarbstoff=351:12
|
||||
magentafarbstoff=351:13
|
||||
orangenerfarbstoff=351:14
|
||||
knochenmehl=351:15
|
||||
knochen=352
|
||||
zucker=353
|
||||
kuchen=354
|
||||
bett=355
|
||||
redstoneverstaerker=356
|
||||
keks=357
|
||||
karte=358
|
||||
schere=359
|
||||
melone=360
|
||||
kürbiskerne=361
|
||||
melonenkerne=362
|
||||
rohesrindfleisch=363
|
||||
steak=364
|
||||
roheshühnchen=365
|
||||
gebrateneshühnchen=366
|
||||
verrottetesfleisch=367
|
||||
enderperle=368
|
||||
lohenrute=369
|
||||
ghasttraene=370
|
||||
goldnugget=371
|
||||
netherwarze=372
|
||||
trank=373
|
||||
glasflasche=374
|
||||
spinnenauge=375
|
||||
fermentiertesspinnenauge=376
|
||||
lohenstaub=377
|
||||
magmacreme=378
|
||||
braustand=379
|
||||
kessel=380
|
||||
enderauge=381
|
||||
glitzerndemelone=382
|
||||
spawnei=383
|
||||
erfahrungsfläschchen=384
|
||||
feuerkugel=385
|
||||
buchundfeder=386
|
||||
beschriebenesbuch=387
|
||||
smaragd=388
|
||||
rahmen=389
|
||||
blumentopf=390
|
||||
karotte=391
|
||||
kartoffel=392
|
||||
ofenkartoffel=393
|
||||
giftigekartoffel=394
|
||||
leerekarte=395
|
||||
goldenekarotte=396
|
||||
skelettschaedel=397
|
||||
witherschaedel=397:1
|
||||
zombieschaedel=397:2
|
||||
kopf=397:3
|
||||
creeperschaedel=397:4
|
||||
karottenrute=398
|
||||
netherstern=399
|
||||
kuerbiskuchen=400
|
||||
feuerwerksrakete=401
|
||||
feuerwerksstern=402
|
||||
verzauberungsbuch=403
|
||||
redstonekomparator=404
|
||||
netherziegelitem=405
|
||||
netherquarz=406
|
||||
tntlore=407
|
||||
trichterlore=408
|
||||
prismarinscherbe=409
|
||||
prismarinkristalle=410
|
||||
roheskaninchen=411
|
||||
gebrateneskaninchen=412
|
||||
kaninchenragout=413
|
||||
hasenpfote=414
|
||||
kaninchenfell=415
|
||||
ruestungsstaender=416
|
||||
eisernepferderuestung=417
|
||||
goldenepferderuestung=418
|
||||
diamantenepferderuestung=419
|
||||
leine=420
|
||||
namensschild=421
|
||||
kommandoblocklore=422
|
||||
roheshammelfleisch=423
|
||||
gebrateneshammelfleisch=424
|
||||
banner=425
|
||||
schwarzesbanner=415:0
|
||||
rotesbanner=415:1
|
||||
gruenesbanner=415:2
|
||||
braunbanner=415:3
|
||||
blauesbanner=415:4
|
||||
violettesbanner=415:5
|
||||
tuerkisesbanner=415:6
|
||||
hellgrauesbanner=415:7
|
||||
grauesbanner=415:8
|
||||
rosabanner=415:9
|
||||
hellgruenesbanner=415:10
|
||||
gelbesbanner=415:11
|
||||
hellblauesbanner=415:12
|
||||
magentabanner=415:13
|
||||
orangenesbanner=415:14
|
||||
weissesbanner=415:15
|
||||
fichtenholztuer=427
|
||||
birkenholztuer=428
|
||||
tropentuer=429
|
||||
akazientuer=430
|
||||
schwarzeichentuer=431
|
||||
goldeneschallplatte=2256
|
||||
grueneschallplatte=2257
|
||||
blocksschallplatte=2258
|
||||
chirpschallplatte=2259
|
||||
farschallplatte=2260
|
||||
mallschallplatte=2261
|
||||
mellohischallplatte=2262
|
||||
stalschallplatte=2263
|
||||
stradschallplatte=2264
|
||||
wardschallplatte=2265
|
||||
11schallplatte=2266
|
||||
|
||||
|
||||
|
@ -44,7 +44,7 @@ MaxHealth=10
|
||||
AttackRange=2.0
|
||||
AttackRate=1
|
||||
AttackDamage=4.0
|
||||
SightDistance=25.0
|
||||
SightDistance=64.0
|
||||
MaxHealth=40
|
||||
|
||||
[ZombiePigman]
|
||||
@ -185,4 +185,10 @@ AttackDamage=6.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=100
|
||||
|
||||
[Bat]
|
||||
AttackRange=2.0
|
||||
AttackRate=1
|
||||
AttackDamage=0.0
|
||||
SightDistance=25.0
|
||||
MaxHealth=6
|
||||
|
||||
|
@ -12,7 +12,8 @@
|
||||
:: It expects the MS Performance tools installed in C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools
|
||||
:: You can override this path by setting the pt environment variable prior to launching this script
|
||||
::
|
||||
:: By default it will launch the release version of MCServer; set the app environment variable to another executable to run that instead.
|
||||
:: By default it will launch the 32-bit release version of MCServer; set the app environment variable to another executable to run that instead.
|
||||
:: Set the IsExecutablex64 env variable to \x64 to profile a 64-bit executable instead (available as the profile_run_x64.cmd script)
|
||||
:: Note that the app needs to be compiled with the "/PROFILE" flag in order for the profiling to work
|
||||
|
||||
|
||||
@ -55,15 +56,15 @@ mkdir %outputdir%
|
||||
:: Start the profiler
|
||||
set outputname=profile.vsp
|
||||
set output=%outputdir%\%outputname%
|
||||
%pt%\vsperfcmd /start:sample /output:%output%
|
||||
%pt%%IsExecutablex64%\vsperfcmd /start:sample /output:%output%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Launch the application via the profiler
|
||||
%pt%\vsperfcmd /launch:%app%
|
||||
if errorlevel 1 goto haderror
|
||||
%pt%%IsExecutablex64%\vsperfcmd /launch:%app%
|
||||
if errorlevel 1 goto haderrorshutdown
|
||||
|
||||
:: Shut down the profiler (this command waits, until the application is terminated)
|
||||
%pt%\vsperfcmd /shutdown
|
||||
%pt%%IsExecutablex64%\vsperfcmd /shutdown
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
@ -86,6 +87,10 @@ goto finished
|
||||
|
||||
|
||||
|
||||
:haderrorshutdown
|
||||
echo An error was encountered, shutting down the profiler
|
||||
%pt%%IsExecutablex64%\vsperfcmd /shutdown
|
||||
|
||||
:haderror
|
||||
echo An error was encountered
|
||||
pause
|
||||
|
5
MCServer/profile_run_x64.cmd
Normal file
5
MCServer/profile_run_x64.cmd
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
:: This script uses the profile_run.cmd script to run profiling on a x64 release executable
|
||||
|
||||
set IsExecutablex64=\x64
|
||||
call profile_run.cmd
|
BIN
MCServer/webadmin/files/background.gif
Normal file
BIN
MCServer/webadmin/files/background.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 57 B |
BIN
MCServer/webadmin/files/favicon.ico
Normal file
BIN
MCServer/webadmin/files/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
MCServer/webadmin/files/logo.png
Normal file
BIN
MCServer/webadmin/files/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
MCServer/webadmin/files/mc-logo.png
Normal file
BIN
MCServer/webadmin/files/mc-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
353
MCServer/webadmin/files/style.css
Normal file
353
MCServer/webadmin/files/style.css
Normal file
@ -0,0 +1,353 @@
|
||||
body, html
|
||||
{
|
||||
font-family: "Open Sans", Tahoma, sans-serif;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-weight: 400;
|
||||
background-color: #fbe9e7;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.light { font-weight: 300; }
|
||||
.bold { font-weight: 600; }
|
||||
|
||||
#wrapper
|
||||
{
|
||||
background-color: #ff5722;
|
||||
margin: 40px auto;
|
||||
width: 99%;
|
||||
max-width: 1200px;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-shadow: 0px 4px 5px rgba(0, 0, 0, 0.15);
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.title
|
||||
{
|
||||
font-size: 30pt;
|
||||
padding: 10px 40px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.3);
|
||||
display: block;
|
||||
}
|
||||
|
||||
#sidebar
|
||||
{
|
||||
float: left;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.sideNav
|
||||
{
|
||||
list-style: none;
|
||||
background-color: #fafafa;
|
||||
margin: 20px 0;
|
||||
padding: 5px 0;
|
||||
width: 100%;
|
||||
box-shadow: 1px 0px 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.sideNav li
|
||||
{
|
||||
padding: 10px;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.sideNav li.link
|
||||
{
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.sideNav li.link a
|
||||
{
|
||||
text-decoration: none;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
#container
|
||||
{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
#main
|
||||
{
|
||||
float: right;
|
||||
width: 80%;
|
||||
padding: 0 15px 20px 15px;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.clear
|
||||
{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table td
|
||||
{
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table th
|
||||
{
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table tr:nth-child(odd)
|
||||
{
|
||||
background-color: rgba(0, 0, 0, 0.015);
|
||||
}
|
||||
|
||||
p
|
||||
{
|
||||
margin: 8px 0;
|
||||
padding: 8px 3px;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #0277bd;
|
||||
-webkit-transition: color 0.1s linear;
|
||||
-moz-transition: color 0.1s linear;
|
||||
transition: color 0.1s linear;
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
color: #01579b;
|
||||
}
|
||||
|
||||
.welcome-msg
|
||||
{
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.username
|
||||
{
|
||||
text-transform: capitalize;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
color: black;
|
||||
}
|
||||
|
||||
input, select
|
||||
{
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
form
|
||||
{
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.info input[type="submit"], .info button, .info input[type="button"],
|
||||
.warn input[type="submit"], .warn button, .warn input[type="button"],
|
||||
.err input[type="submit"], .err button, .err input[type="button"]
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
|
||||
.err
|
||||
{
|
||||
color: white;
|
||||
display: block;
|
||||
background-color: #e51c23 !important;
|
||||
padding: 15px;
|
||||
line-height: 30px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.err:before
|
||||
{
|
||||
content: "ERROR: ";
|
||||
}
|
||||
|
||||
.warn
|
||||
{
|
||||
color: white;
|
||||
display: block;
|
||||
background-color: #ff5722 !important;
|
||||
padding: 15px;
|
||||
line-height: 30px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.warn:before
|
||||
{
|
||||
content: "WARNING: ";
|
||||
}
|
||||
|
||||
.info
|
||||
{
|
||||
color: white;
|
||||
display: block;
|
||||
background-color: #5677fc !important;
|
||||
padding: 15px;
|
||||
line-height: 30px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.info:before
|
||||
{
|
||||
content: "INFORMATION: ";
|
||||
}
|
||||
|
||||
#footer .fleft
|
||||
{
|
||||
float: left;
|
||||
}
|
||||
|
||||
#footer .fright
|
||||
{
|
||||
float: right;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#footer
|
||||
{
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
font-size: 9pt;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.2) inset;
|
||||
}
|
||||
|
||||
#footer a
|
||||
{
|
||||
text-transform: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
input[type="submit"], button, input[type="button"]
|
||||
{
|
||||
background-color: #ffc107;
|
||||
padding: 8px 15px 8px 15px;
|
||||
margin: 0 2px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
color: black;
|
||||
box-shadow: 0px 2px 3px rgba(0,0,0,0.2);
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="submit"]:hover, button:hover, input[type="button"]:hover
|
||||
{
|
||||
background-color: #ffca28;
|
||||
}
|
||||
|
||||
input[type="submit"]:active, button:active, input[type="button"]:active
|
||||
{
|
||||
background-color: #ffd54f;
|
||||
-webkit-transform: translateY(1px);
|
||||
-moz-transform: translateY(1px);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: none;
|
||||
height: 1px;
|
||||
background-color: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
h4
|
||||
{
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 12px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
|
||||
/**** PAGE SPECIFIC CSS ****/
|
||||
|
||||
/* remove the * for disabling: */
|
||||
|
||||
.page-core-server-settings table td
|
||||
{
|
||||
text-align: center;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.page-core-server-settings.no-param table td:nth-child(1) a,
|
||||
.page-core-server-settings.param-tab-general table td:nth-child(1) a
|
||||
{
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.page-core-server-settings.param-tab-monsters table td:nth-child(2) a
|
||||
{
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.page-core-server-settings.param-tab-worlds table td:nth-child(3) a
|
||||
{
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.page-core-server-settings.param-tab-world table td:nth-child(4) a
|
||||
{
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
.page-core-permissions form table tr,
|
||||
.page-core-permissions form table td,
|
||||
.page-core-permissions form table th
|
||||
{
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.page-core-permissions form table tr:nth-child(1) th
|
||||
{
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.page-core-permissions form table tr:nth-child(1) td
|
||||
{
|
||||
width: 65%;
|
||||
}
|
||||
|
||||
.page-core-permissions form table td input
|
||||
{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#ChatDiv
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#ChatMessage
|
||||
{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
/**/
|
25
MCServer/webadmin/login_template.html
Normal file
25
MCServer/webadmin/login_template.html
Normal file
@ -0,0 +1,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>MCServer WebAdmin - Login</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="favicon.ico">
|
||||
<style type="text/css">
|
||||
header {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<img src="mc-logo.png" alt="MCServer Logo" class="logo">
|
||||
<h1>MCServer - WebAdmin</h1>
|
||||
<form method="get" action="webadmin/">
|
||||
<input type="submit" value="Log in">
|
||||
</form>
|
||||
</header>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -71,17 +71,23 @@
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#main table tr.odd td {
|
||||
background: #fbfbfb;
|
||||
}
|
||||
|
||||
table tr:hover td { background: #fdfcf6; }
|
||||
table tr:hover td {
|
||||
background: #fdfcf6;
|
||||
}
|
||||
|
||||
table .action {
|
||||
text-align: right;
|
||||
padding: 0 20px 0 10px;
|
||||
}
|
||||
|
||||
table tr .action a { color: #9b9b9b; }
|
||||
table tr .action a {
|
||||
color: #9b9b9b;
|
||||
}
|
||||
|
||||
#cssmenu{ height:10px; display:table; padding:0; margin: 0 auto; border:1px #707070 solid; border-radius:5px; }
|
||||
#cssmenu > ul {list-style:inside none; padding:0; margin:0;}
|
||||
|
File diff suppressed because one or more lines are too long
137
MCServer/webadmin/template_orig.lua
Normal file
137
MCServer/webadmin/template_orig.lua
Normal file
@ -0,0 +1,137 @@
|
||||
-- Use a table for fast concatenation of strings
|
||||
local SiteContent = {}
|
||||
function Output(String)
|
||||
table.insert(SiteContent, String)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function GetTableSize(Table)
|
||||
local Size = 0
|
||||
for key,value in pairs(Table) do
|
||||
Size = Size + 1
|
||||
end
|
||||
return Size
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function GetDefaultPage()
|
||||
local PM = cRoot:Get():GetPluginManager()
|
||||
|
||||
local SubTitle = "Current Game"
|
||||
local Content = ""
|
||||
|
||||
Content = Content .. "<h4>Server Name:</h4>"
|
||||
Content = Content .. "<p>" .. cRoot:Get():GetServer():GetServerID() .. "</p>"
|
||||
|
||||
Content = Content .. "<h4>Plugins:</h4><ul>"
|
||||
local AllPlugins = PM:GetAllPlugins()
|
||||
for key,value in pairs(AllPlugins) do
|
||||
if( value ~= nil and value ~= false ) then
|
||||
Content = Content .. "<li>" .. key .. " V." .. value:GetVersion() .. "</li>"
|
||||
end
|
||||
end
|
||||
|
||||
Content = Content .. "</ul>"
|
||||
Content = Content .. "<h4>Players:</h4><ul>"
|
||||
|
||||
local AddPlayerToTable = function( Player )
|
||||
Content = Content .. "<li>" .. Player:GetName() .. "</li>"
|
||||
end
|
||||
cRoot:Get():ForEachPlayer( AddPlayerToTable )
|
||||
|
||||
Content = Content .. "</ul><br>";
|
||||
|
||||
return Content, SubTitle
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function ShowPage(WebAdmin, TemplateRequest)
|
||||
SiteContent = {}
|
||||
local BaseURL = WebAdmin:GetBaseURL(TemplateRequest.Request.Path)
|
||||
local Title = "MCServer WebAdmin"
|
||||
local MemoryUsageKiB = cRoot:GetPhysicalRAMUsage()
|
||||
local NumChunks = cRoot:Get():GetTotalChunkCount()
|
||||
local PluginPage = WebAdmin:GetPage(TemplateRequest.Request)
|
||||
local PageContent = PluginPage.Content
|
||||
local SubTitle = PluginPage.PluginName
|
||||
if (PluginPage.TabName ~= "") then
|
||||
SubTitle = PluginPage.PluginName .. " - " .. PluginPage.TabName
|
||||
end
|
||||
if (PageContent == "") then
|
||||
PageContent, SubTitle = GetDefaultPage()
|
||||
end
|
||||
|
||||
Output([[
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<title>]] .. Title .. [[</title>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<!-- h1 tag stays for the logo, you can use the a tag for linking the index page -->
|
||||
<h1>
|
||||
<a href="]] .. BaseURL .. [["><span>MCServer</span></a>
|
||||
</h1>
|
||||
<div id="containerHolder">
|
||||
<div id="container">
|
||||
<div id="sidebar">
|
||||
<ul class="sideNav">
|
||||
]])
|
||||
|
||||
|
||||
local AllPlugins = WebAdmin:GetPlugins()
|
||||
for key,value in pairs(AllPlugins) do
|
||||
local PluginWebTitle = value:GetWebTitle()
|
||||
local TabNames = value:GetTabNames()
|
||||
if (GetTableSize(TabNames) > 0) then
|
||||
Output("<li>"..PluginWebTitle.."</li>\n");
|
||||
|
||||
for webname,prettyname in pairs(TabNames) do
|
||||
Output("<li><a href='" .. BaseURL .. PluginWebTitle .. "/" .. webname .. "'>" .. prettyname .. "</a></li>\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Output([[
|
||||
</ul>
|
||||
<!-- // .sideNav -->
|
||||
</div>
|
||||
<!-- // #sidebar -->
|
||||
<!-- h2 stays for breadcrumbs -->
|
||||
<h2>Welcome ]] .. TemplateRequest.Request.Username .. [[</h2>
|
||||
<div id="main">
|
||||
<h3>]] .. SubTitle .. [[</h3>
|
||||
]] .. PageContent .. [[
|
||||
</div>
|
||||
<!-- // #main -->
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
</div>
|
||||
<!-- // #container -->
|
||||
</div>
|
||||
<!-- // #containerHolder -->
|
||||
|
||||
<p id="footer">MCServer is using: ]] .. MemoryUsageKiB / 1024 .. [[ MiB of memory; Current chunk count: ]] .. NumChunks .. [[ </p>
|
||||
</div>
|
||||
<!-- // #wrapper -->
|
||||
</body>
|
||||
</html>
|
||||
]])
|
||||
|
||||
return table.concat(SiteContent)
|
||||
end
|
@ -1,209 +0,0 @@
|
||||
@echo off
|
||||
:: Nightbbuild2008.cmd
|
||||
:: This script is run every night to produce a new version of MCServer, backup its PDB files and upload the packages to web.
|
||||
:: When run without parameters, this script pauses at the end and waits for a keypress.
|
||||
:: To run in an automated scheduler, add any parameter to disable waiting for a keystroke
|
||||
::
|
||||
:: The sript creates a symbol store (a database of PDB files) that can be used as a single entry in MSVC's symbol path,
|
||||
:: then any executable / crashdump built by this script can be debugged and its symbols will be found automatically by MSVC,
|
||||
:: without the users needing to specify the build version or anything.
|
||||
:: In order to support pruning the symstore, a per-month store is created, so that old months can be removed when no longer needed.
|
||||
::
|
||||
:: This script expects a few tools on specific paths, you can pass the correct paths for your system as env vars "zip" and "vc"
|
||||
:: This script assumes that "git", "symstore" and "touch" are available on PATH.
|
||||
:: git comes from msysgit
|
||||
:: symstore comes from Microsoft's Debugging Tools for Windows
|
||||
:: touch comes from unxtools
|
||||
:: This script is locale-dependent, because it parses the output of "time" and "date" shell commands
|
||||
|
||||
|
||||
:: 7-zip executable (by default it should be on PATH):
|
||||
if %zip%a == a set zip=7z
|
||||
|
||||
:: Visual C++ compiler executable name:
|
||||
if %vc%a == a set vc="vcbuild.exe"
|
||||
|
||||
|
||||
|
||||
|
||||
:: Check that the required environment vars are available:
|
||||
if "a%ftppass%" == "a" (
|
||||
echo You need to set FTP password in the ftppass environment variable to upload the files
|
||||
goto haderror
|
||||
)
|
||||
if "a%ftpuser%" == "a" (
|
||||
echo You need to set FTP username in the ftpuser environment variable to upload the files
|
||||
goto haderror
|
||||
)
|
||||
if "a%ftpsite%" == "a" (
|
||||
echo You need to set FTP server in the ftpsite environment variable to upload the files
|
||||
goto haderror
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
:: Get the date and time into vars:
|
||||
:: This is locale-dependent!
|
||||
For /f "tokens=2-4 delims=/. " %%a in ('date /t') do (
|
||||
set MYYEAR=%%c
|
||||
set MYMONTH=%%b
|
||||
set MYDAY=%%a
|
||||
)
|
||||
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set MYTIME=%%a_%%b)
|
||||
|
||||
echo Performing nightbuild of MC-Server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
set DONOTPAUSE=y
|
||||
|
||||
:: Update the sources to the latest revision:
|
||||
git pull
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
:: Update the external plugins to the latest revision:
|
||||
git submodule update
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
:: Get the Git commit ID into an environment var
|
||||
For /f "tokens=1 delims=/. " %%a in ('git log -1 --oneline --no-abbrev-commit') do (set COMMITID=%%a)
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
:: Test if the version is already present, using a "tagfile" that we create upon successful build
|
||||
set TAGFOLDER=Install\%MYYEAR%_%MYMONTH%\
|
||||
set TAGFILE=%TAGFOLDER%built_%COMMITID%.tag
|
||||
echo Tag file: %TAGFILE%
|
||||
if exist %TAGFILE% (
|
||||
echo Latest version already present, bailing out
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Configure the sources to use the MSVC2008 compiler:
|
||||
cmake -G "Visual Studio 9 2008" .
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Update the Bindings:
|
||||
echo Updating Lua bindings
|
||||
del src\Bindings\Bindings.cpp
|
||||
del src\Bindings\Bindings.h
|
||||
set ALLTOLUA_WAIT=N
|
||||
cd src\Bindings
|
||||
call AllToLua.bat
|
||||
cd ..\..
|
||||
|
||||
|
||||
|
||||
|
||||
:: Compile using VC2008 Express. Do a full rebuild.
|
||||
echo Setting up VS environment...
|
||||
call "%VS90COMNTOOLS%\vsvars32.bat"
|
||||
echo Compiling MCServer...
|
||||
title MCS Nightbuild
|
||||
start "vc" /b /wait /low /min %vc% /r MCServer.sln "Release|Win32"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
:: Generate the .example.ini files by running the server without any ini files:
|
||||
cd MCServer
|
||||
del groups.ini
|
||||
del settings.ini
|
||||
del webadmin.ini
|
||||
echo stop | MCServer
|
||||
cd ..
|
||||
|
||||
|
||||
|
||||
:: Copy all the example ini files into the Install folder for zipping:
|
||||
copy MCServer\groups.ini Install\groups.example.ini
|
||||
copy MCServer\settings.ini Install\settings.example.ini
|
||||
copy MCServer\webadmin.ini Install\webadmin.example.ini
|
||||
|
||||
|
||||
|
||||
|
||||
:: Use 7-zip to compress the resulting files into a single file:
|
||||
set FILESUFFIX=%MYYEAR%_%MYMONTH%_%MYDAY%_%MYTIME%_%COMMITID%
|
||||
echo FILESUFFIX=%FILESUFFIX%
|
||||
copy MCServer\MCServer.exe Install\MCServer.exe
|
||||
cd Install
|
||||
%zip% a -mx9 -y MCServer_Win_%FILESUFFIX%.7z -scsWIN -i@Zip2008.list -xr!*.git*
|
||||
if errorlevel 1 goto haderror
|
||||
cd ..
|
||||
|
||||
:: Also pack PDBs into a separate archive:
|
||||
%zip% a -mx9 -y Install\PDBs_%FILESUFFIX%.7z -scsWIN @Install\Zip2008_PDBs.list
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: upload to the FTP:
|
||||
:upload
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% / Install\MCServer_Win_%FILESUFFIX%.7z
|
||||
if errorlevel 1 goto haderror
|
||||
ncftpput -p %ftppass% -u %ftpuser% -T temp_ %ftpsite% /PDBs Install\PDBs_%FILESUFFIX%.7z
|
||||
if errorlevel 1 goto haderror
|
||||
echo Upload finished.
|
||||
|
||||
|
||||
|
||||
|
||||
:: Create the tagfile so that we know that this CommitID has been built already
|
||||
mkdir %TAGFOLDER%
|
||||
touch %TAGFILE%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Add the symbols to a global symbol cache
|
||||
:: We want per-month symbol caches, so that the old ones can be easily deleted
|
||||
set SYMBOLS=Symbols\%MYYEAR%_%MYMONTH%\
|
||||
echo Storing symbols in %SYMBOLS%
|
||||
|
||||
symstore add /f MCServer\MCServer.* /s %SYMBOLS% /t MCServer
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
goto end
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo an error was encountered, check command output above
|
||||
pause
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:end
|
||||
if "a%1" == "a" pause
|
||||
|
||||
|
||||
|
||||
:finished
|
@ -5,15 +5,15 @@ MCServer is a Minecraft server that is written in C++ and designed to be efficie
|
||||
|
||||
MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis.
|
||||
|
||||
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.7.10.
|
||||
We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.8.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Normally, you will want to download a pre-compiled version of MCServer from one of the buildservers:
|
||||
|
||||
* [Linux and Raspberry Pi](http://ci.bearbin.net) (Bearbin's CI Server)
|
||||
* [Windows](http://mc-server.xoft.cz) (xoft's nightly build service)
|
||||
* [Windows and Linux](http://builds.cuberite.org)
|
||||
* [Raspberry Pi](http://builds.cuberite.org)
|
||||
|
||||
You simply need to download and extract these files before you can use the server.
|
||||
|
||||
@ -33,7 +33,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for
|
||||
|
||||
Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
|
||||
|
||||
Support Us on Gittip: [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team)
|
||||
Support Us on Gratipay: [![Support via Gratipay](http://img.shields.io/gittip/cuberite_team.svg)](https://www.gratipay.com/cuberite_team)
|
||||
|
||||
Travis CI: [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer)
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
macro (add_flags_lnk FLAGS)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
|
||||
@ -57,12 +59,25 @@ macro(set_flags)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
elseif(APPLE)
|
||||
#on os x clang adds pthread for us but we need to add it for gcc
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (NOT GCC_VERSION VERSION_GREATER 4.6))
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
||||
endif()
|
||||
#on os x clang adds pthread for us but we need to add it for gcc
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
add_flags_cxx("-stdlib=libc++")
|
||||
add_flags_lnk("-stdlib=libc++")
|
||||
else()
|
||||
@ -75,8 +90,17 @@ macro(set_flags)
|
||||
add_flags_cxx("-pthread")
|
||||
endif()
|
||||
|
||||
# Make CLang use C++11, otherwise MSVC2008-supported extensions don't work ("override" keyword etc.):
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND (NOT GCC_VERSION VERSION_GREATER 4.6))
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++0x")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11")
|
||||
@ -203,6 +227,15 @@ macro(enable_profile)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
#this is a hack because we can't use cmake 2.8.10 because of travis
|
||||
macro(get_clang_version)
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_CXX_COMPILER}" "--version"
|
||||
OUTPUT_VARIABLE CLANG_VERSION_OUTPUT)
|
||||
string(REGEX MATCH "version ([0-9]\\.[0-9])" x ${CLANG_VERSION_OUTPUT})
|
||||
set(CLANG_VERSION ${CMAKE_MATCH_1})
|
||||
endmacro()
|
||||
|
||||
macro(set_exe_flags)
|
||||
# Remove disabling the maximum warning level:
|
||||
# clang does not like a command line that reads -Wall -Wextra -w -Wall -Wextra and does not output any warnings
|
||||
@ -221,17 +254,28 @@ macro(set_exe_flags)
|
||||
add_flags_cxx("-ffast-math")
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
get_clang_version()
|
||||
if ("${CLANG_VERSION}" VERSION_LESS 3.0)
|
||||
message(FATAL_ERROR "MCServer requires clang version 3.0 or higher, version is ${CLANG_VERSION}")
|
||||
endif()
|
||||
# clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math
|
||||
add_flags_cxx("-D__extern_always_inline=inline")
|
||||
add_flags_cxx("-Werror -Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion")
|
||||
add_flags_cxx("-Wno-error=switch-enum -Wno-documentation -Wno-exit-time-destructors")
|
||||
add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-padded")
|
||||
add_flags_cxx("-Wno-error=deprecated -Wno-error=weak-vtables -Wno-error=float-equal")
|
||||
add_flags_cxx("-Wno-error=missing-prototypes -Wno-error=non-virtual-dtor")
|
||||
add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow -Wno-error=old-style-cast")
|
||||
add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations")
|
||||
add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough")
|
||||
add_flags_cxx("-Wno-error=extra-semi -Wno-weak-vtables -Wno-switch-enum")
|
||||
add_flags_cxx("-Wno-exit-time-destructors -Wno-padded")
|
||||
add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-error=deprecated")
|
||||
add_flags_cxx("-Wno-error=missing-prototypes")
|
||||
add_flags_cxx("-Wno-error=shadow -Wno-error=old-style-cast -Wno-error=global-constructors")
|
||||
add_flags_cxx("-Wno-error=float-equal")
|
||||
add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum")
|
||||
if ("${CLANG_VERSION}" VERSION_GREATER 3.0)
|
||||
# flags that are not present in 3.0
|
||||
add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=missing-variable-declarations")
|
||||
add_flags_cxx("-Wno-implicit-fallthrough -Wno-error=extra-semi")
|
||||
endif()
|
||||
if ("${CLANG_VERSION}" VERSION_GREATER 3.1)
|
||||
# flags introduced in 3.2
|
||||
add_flags_cxx("-Wno-documentation")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
1
Tools/.gitignore
vendored
Normal file
1
Tools/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
Debug/
|
5
Tools/AnvilStats/.gitignore
vendored
5
Tools/AnvilStats/.gitignore
vendored
@ -1,3 +1,7 @@
|
||||
*.vcproj
|
||||
*.vcxproj
|
||||
*.sln
|
||||
*.user
|
||||
.xls
|
||||
Statistics.txt
|
||||
*.bmp
|
||||
@ -7,3 +11,4 @@ Profiling
|
||||
*.png
|
||||
world/
|
||||
*.html
|
||||
*.xls
|
||||
|
@ -1,55 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Express 2013 for Windows Desktop
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcxproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821} = {B61007AC-B557-4B67-A765-E468C0C3A821}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\lib\zlib\zlib.vcxproj", "{B61007AC-B557-4B67-A765-E468C0C3A821}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
DebugProfile|Win32 = DebugProfile|Win32
|
||||
MinSizeRel|Win32 = MinSizeRel|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
ReleaseProfile|Win32 = ReleaseProfile|Win32
|
||||
RelWithDebInfo|Win32 = RelWithDebInfo|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.ActiveCfg = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.Build.0 = Debug|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.Build.0 = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.Build.0 = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.Build.0 = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32
|
||||
{CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.Build.0 = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.ActiveCfg = DebugProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.Build.0 = DebugProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.ActiveCfg = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.Build.0 = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.Build.0 = Release|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.ActiveCfg = ReleaseProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.Build.0 = ReleaseProfile|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32
|
||||
{B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,468 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="AnvilStats"
|
||||
ProjectGUID="{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
|
||||
RootNamespace="AnvilStats"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""..\..\lib""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\lib""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release profiled|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories=""..\..\lib""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
StackReserveSize="16777216"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
Profile="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Callback.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ChunkExtract.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightBiomeMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightBiomeMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\HeightMap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ImageComposingCallback.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ImageComposingCallback.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Processor.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SpringStats.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Statistics.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Utils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Endianness.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="NBT_RESERVE_SIZE=10000"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\GZipFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\GZipFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\AnvilStats.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
144
Tools/AnvilStats/CMakeLists.txt
Normal file
144
Tools/AnvilStats/CMakeLists.txt
Normal file
@ -0,0 +1,144 @@
|
||||
|
||||
cmake_minimum_required (VERSION 2.8.3)
|
||||
|
||||
project (AnvilStats)
|
||||
|
||||
include(../../SetFlags.cmake)
|
||||
|
||||
set_flags()
|
||||
set_lib_flags()
|
||||
|
||||
|
||||
# Set include paths to the used libraries:
|
||||
include_directories("../../lib")
|
||||
include_directories("../../src")
|
||||
|
||||
|
||||
|
||||
function(flatten_files arg1)
|
||||
set(res "")
|
||||
foreach(f ${${arg1}})
|
||||
get_filename_component(f ${f} ABSOLUTE)
|
||||
list(APPEND res ${f})
|
||||
endforeach()
|
||||
set(${arg1} "${res}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib)
|
||||
|
||||
set_exe_flags()
|
||||
|
||||
# Include the shared files:
|
||||
set(SHARED_SRC
|
||||
../../src/ByteBuffer.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/LoggerListeners.cpp
|
||||
../../src/Logger.cpp
|
||||
../../src/WorldStorage/FastNBT.cpp
|
||||
../BiomeVisualiser/BiomeColors.cpp
|
||||
)
|
||||
|
||||
set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/LoggerListeners.h
|
||||
../../src/Logger.h
|
||||
../../src/WorldStorage/FastNBT.h
|
||||
../BiomeVisualiser/BiomeColors.h
|
||||
)
|
||||
|
||||
set(SHARED_OSS_SRC
|
||||
../../src/OSSupport/CriticalSection.cpp
|
||||
../../src/OSSupport/Event.cpp
|
||||
../../src/OSSupport/File.cpp
|
||||
../../src/OSSupport/GZipFile.cpp
|
||||
../../src/OSSupport/IsThread.cpp
|
||||
../../src/OSSupport/Timer.cpp
|
||||
)
|
||||
|
||||
set(SHARED_OSS_HDR
|
||||
../../src/OSSupport/CriticalSection.h
|
||||
../../src/OSSupport/Event.h
|
||||
../../src/OSSupport/File.h
|
||||
../../src/OSSupport/GZipFile.h
|
||||
../../src/OSSupport/IsThread.h
|
||||
../../src/OSSupport/Timer.h
|
||||
)
|
||||
|
||||
flatten_files(SHARED_SRC)
|
||||
flatten_files(SHARED_HDR)
|
||||
flatten_files(SHARED_OSS_SRC)
|
||||
flatten_files(SHARED_OSS_HDR)
|
||||
source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR})
|
||||
source_group("Shared\\OSSupport" FILES ${SHARED_OSS_SRC} ${SHARED_OSS_HDR})
|
||||
|
||||
|
||||
|
||||
# Include the main source files:
|
||||
set(SOURCES
|
||||
AnvilStats.cpp
|
||||
BiomeMap.cpp
|
||||
ChunkExtract.cpp
|
||||
Globals.cpp
|
||||
HeightBiomeMap.cpp
|
||||
HeightMap.cpp
|
||||
ImageComposingCallback.cpp
|
||||
Processor.cpp
|
||||
SpringStats.cpp
|
||||
Statistics.cpp
|
||||
Utils.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
BiomeMap.h
|
||||
Callback.h
|
||||
ChunkExtract.h
|
||||
Globals.h
|
||||
HeightBiomeMap.h
|
||||
HeightMap.h
|
||||
ImageComposingCallback.h
|
||||
Processor.h
|
||||
SpringStats.h
|
||||
Statistics.h
|
||||
Utils.h
|
||||
|
||||
AnvilStats.txt
|
||||
)
|
||||
|
||||
source_group("" FILES ${SOURCES} ${HEADERS})
|
||||
|
||||
add_definitions(-DNBT_RESERVE_SIZE=10000)
|
||||
|
||||
add_executable(AnvilStats
|
||||
${SOURCES}
|
||||
${HEADERS}
|
||||
${SHARED_SRC}
|
||||
${SHARED_HDR}
|
||||
${SHARED_OSS_SRC}
|
||||
${SHARED_OSS_HDR}
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(AnvilStats zlib)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Under MSVC we need to enlarge the default stack size for the executable:
|
||||
if (MSVC)
|
||||
get_target_property(TEMP AnvilStats LINK_FLAGS)
|
||||
if (TEMP STREQUAL "TEMP-NOTFOUND")
|
||||
SET(TEMP "") # set to empty string
|
||||
message("LINKER_FLAGS not found")
|
||||
else ()
|
||||
SET(TEMP "${TEMP} ") # a space to cleanly separate from existing content
|
||||
message("LINKER_FLAGS: ${LINKER_FLAGS}")
|
||||
endif ()
|
||||
# append our values
|
||||
SET(TEMP "${TEMP}/STACK:16777216")
|
||||
set_target_properties(AnvilStats PROPERTIES LINK_FLAGS ${TEMP})
|
||||
endif ()
|
||||
|
||||
|
||||
|
@ -241,6 +241,17 @@ public:
|
||||
|
||||
|
||||
|
||||
/** Clamp value to the specified range. */
|
||||
template <typename T>
|
||||
T Clamp(T a_Value, T a_Min, T a_Max)
|
||||
{
|
||||
return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 2, with macros):
|
||||
#include "../../src/ChunkDef.h"
|
||||
#include "../../src/BlockID.h"
|
||||
|
@ -28,6 +28,7 @@ cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProces
|
||||
m_Callback(a_Callback),
|
||||
m_ParentProcessor(a_ParentProcessor)
|
||||
{
|
||||
LOG("Created a new thread: %p", this);
|
||||
super::Start();
|
||||
}
|
||||
|
||||
@ -35,11 +36,20 @@ cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProces
|
||||
|
||||
|
||||
|
||||
void cProcessor::cThread::WaitForStart(void)
|
||||
{
|
||||
m_HasStarted.Wait();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProcessor::cThread::Execute(void)
|
||||
{
|
||||
LOG("Started a new thread: %d", cIsThread::GetCurrentID());
|
||||
LOG("Started a new thread: %p, ID %d", this, cIsThread::GetCurrentID());
|
||||
|
||||
m_ParentProcessor.m_ThreadsHaveStarted.Set();
|
||||
m_HasStarted.Set();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -52,7 +62,7 @@ void cProcessor::cThread::Execute(void)
|
||||
ProcessFile(FileName);
|
||||
} // for-ever
|
||||
|
||||
LOG("Thread %d terminated", cIsThread::GetCurrentID());
|
||||
LOG("Thread %p (ID %d) terminated", this, cIsThread::GetCurrentID());
|
||||
}
|
||||
|
||||
|
||||
@ -522,20 +532,18 @@ void cProcessor::ProcessWorld(const AString & a_WorldFolder, cCallbackFactory &
|
||||
#endif // _DEBUG
|
||||
//*/
|
||||
|
||||
// Start all the threads:
|
||||
for (int i = 0; i < NumThreads; i++)
|
||||
{
|
||||
cCallback * Callback = a_CallbackFactory.GetNewCallback();
|
||||
m_Threads.push_back(new cThread(*Callback, *this));
|
||||
}
|
||||
|
||||
// Wait for the first thread to start processing:
|
||||
m_ThreadsHaveStarted.Wait();
|
||||
|
||||
// Wait for all threads to finish
|
||||
// simply by calling each thread's destructor sequentially
|
||||
// Wait for all threads to finish:
|
||||
LOG("Waiting for threads to finish");
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
(*itr)->WaitForStart();
|
||||
delete *itr;
|
||||
} // for itr - m_Threads[]
|
||||
LOG("Processor finished");
|
||||
|
@ -30,6 +30,7 @@ class cProcessor
|
||||
|
||||
cCallback & m_Callback;
|
||||
cProcessor & m_ParentProcessor;
|
||||
cEvent m_HasStarted;
|
||||
|
||||
// cIsThread override:
|
||||
virtual void Execute(void) override;
|
||||
@ -48,6 +49,9 @@ class cProcessor
|
||||
|
||||
public:
|
||||
cThread(cCallback & a_Callback, cProcessor & a_ParentProcessor);
|
||||
|
||||
/** Waits until the thread starts processing the callback code. */
|
||||
void WaitForStart(void);
|
||||
} ;
|
||||
|
||||
typedef std::vector<cThread *> cThreads;
|
||||
@ -65,10 +69,12 @@ protected:
|
||||
AStringList m_FileQueue;
|
||||
|
||||
cThreads m_Threads;
|
||||
cEvent m_ThreadsHaveStarted; // This is signalled by each thread to notify the parent thread that it can start waiting for those threads
|
||||
|
||||
|
||||
/** Populates m_FileQueue with Anvil files from the specified folder. */
|
||||
void PopulateFileQueue(const AString & a_WorldFolder);
|
||||
|
||||
/** Returns one filename from m_FileQueue, and removes the name from the queue. */
|
||||
AString GetOneFileName(void);
|
||||
} ;
|
||||
|
||||
|
@ -28,6 +28,8 @@ cStatistics::cStats::cStats(void) :
|
||||
{
|
||||
memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts));
|
||||
memset(m_BlockCounts, 0, sizeof(m_BlockCounts));
|
||||
memset(m_PerHeightBlockCounts, 0, sizeof(m_PerHeightBlockCounts));
|
||||
memset(m_PerHeightSpawners, 0, sizeof(m_PerHeightSpawners));
|
||||
memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity));
|
||||
}
|
||||
|
||||
@ -46,6 +48,11 @@ void cStatistics::cStats::Add(const cStatistics::cStats & a_Stats)
|
||||
for (int j = 0; j <= 255; j++)
|
||||
{
|
||||
m_BlockCounts[i][j] += a_Stats.m_BlockCounts[i][j];
|
||||
m_PerHeightBlockCounts[i][j] += a_Stats.m_PerHeightBlockCounts[i][j];
|
||||
}
|
||||
for (int j = 0; j < ARRAYCOUNT(m_PerHeightSpawners[0]); j++)
|
||||
{
|
||||
m_PerHeightSpawners[i][j] += a_Stats.m_PerHeightSpawners[i][j];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ARRAYCOUNT(m_SpawnerEntity); i++)
|
||||
@ -149,6 +156,7 @@ bool cStatistics::OnSection
|
||||
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
int Height = (int)a_Y * 16 + y;
|
||||
for (int z = 0; z < 16; z++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
@ -156,6 +164,7 @@ bool cStatistics::OnSection
|
||||
unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype
|
||||
unsigned char BlockType = cChunkDef::GetBlock(a_BlockTypes, x, y, z);
|
||||
m_Stats.m_BlockCounts[Biome][BlockType] += 1;
|
||||
m_Stats.m_PerHeightBlockCounts[Height][BlockType] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,16 +268,27 @@ bool cStatistics::OnTileTick(
|
||||
|
||||
void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag)
|
||||
{
|
||||
// Get the spawned entity type:
|
||||
int EntityIDTag = a_NBT.FindChildByName(a_TileEntityTag, "EntityId");
|
||||
if ((EntityIDTag < 0) || (a_NBT.GetType(EntityIDTag) != TAG_String))
|
||||
{
|
||||
return;
|
||||
}
|
||||
eEntityType Ent = GetEntityType(a_NBT.GetString(EntityIDTag));
|
||||
if (Ent < ARRAYCOUNT(m_Stats.m_SpawnerEntity))
|
||||
if (Ent >= ARRAYCOUNT(m_Stats.m_SpawnerEntity))
|
||||
{
|
||||
m_Stats.m_SpawnerEntity[Ent] += 1;
|
||||
return;
|
||||
}
|
||||
m_Stats.m_SpawnerEntity[Ent] += 1;
|
||||
|
||||
// Get the spawner pos:
|
||||
int PosYTag = a_NBT.FindChildByName(a_TileEntityTag, "y");
|
||||
if ((PosYTag < 0) || (a_NBT.GetType(PosYTag) != TAG_Int))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int BlockY = Clamp(a_NBT.GetInt(PosYTag), 0, 255);
|
||||
m_Stats.m_PerHeightSpawners[BlockY][Ent] += 1;
|
||||
}
|
||||
|
||||
|
||||
@ -316,10 +336,14 @@ cStatisticsFactory::~cStatisticsFactory()
|
||||
SaveBiomes();
|
||||
LOG(" BlockTypes.xls");
|
||||
SaveBlockTypes();
|
||||
LOG(" PerHeightBlockTypes.xls");
|
||||
SavePerHeightBlockTypes();
|
||||
LOG(" BiomeBlockTypes.xls");
|
||||
SaveBiomeBlockTypes();
|
||||
LOG(" Spawners.xls");
|
||||
SaveSpawners();
|
||||
LOG(" PerHeightSpawners.xls");
|
||||
SavePerHeightSpawners();
|
||||
}
|
||||
|
||||
|
||||
@ -395,6 +419,61 @@ void cStatisticsFactory::SaveBlockTypes(void)
|
||||
|
||||
|
||||
|
||||
void cStatisticsFactory::SavePerHeightBlockTypes(void)
|
||||
{
|
||||
// Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns
|
||||
|
||||
cFile f;
|
||||
if (!f.Open("PerHeightBlockTypes.xls", cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot write to file PerHeightBlockTypes.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Write header:
|
||||
f.Printf("Blocks 0 - 127:\nHeight");
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
// Write first half:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
f.Printf("%d", y);
|
||||
for (int BlockType = 0; BlockType < 128; BlockType++)
|
||||
{
|
||||
f.Printf("\t%llu", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]);
|
||||
} // for BlockType
|
||||
f.Printf("\n");
|
||||
} // for y - height (0 - 127)
|
||||
f.Printf("\n");
|
||||
|
||||
// Write second header:
|
||||
f.Printf("Blocks 128 - 255:\nHeight");
|
||||
for (int i = 128; i < 256; i++)
|
||||
{
|
||||
f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
// Write second half:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
f.Printf("%d", y);
|
||||
for (int BlockType = 128; BlockType < 256; BlockType++)
|
||||
{
|
||||
f.Printf("\t%llu", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]);
|
||||
} // for BlockType
|
||||
f.Printf("\n");
|
||||
} // for y - height (0 - 127)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cStatisticsFactory::SaveBiomeBlockTypes(void)
|
||||
{
|
||||
// Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns
|
||||
@ -521,3 +600,41 @@ void cStatisticsFactory::SaveSpawners(void)
|
||||
|
||||
|
||||
|
||||
|
||||
void cStatisticsFactory::SavePerHeightSpawners(void)
|
||||
{
|
||||
cFile f;
|
||||
if (!f.Open("PerHeightSpawners.xls", cFile::fmWrite))
|
||||
{
|
||||
LOG("Cannot write to file PerHeightSpawners.xls. Statistics not written.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Write header:
|
||||
f.Printf("Height\tTotal");
|
||||
for (int i = 0; i < entMax; i++)
|
||||
{
|
||||
f.Printf("\t%s", GetEntityTypeString((eEntityType)i));
|
||||
}
|
||||
f.Printf("\n");
|
||||
|
||||
// Write individual lines:
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
UInt64 Total = 0;
|
||||
for (int i = 0; i < entMax; i++)
|
||||
{
|
||||
Total += m_CombinedStats.m_PerHeightSpawners[y][i];
|
||||
}
|
||||
f.Printf("%d\t%llu", y, Total);
|
||||
for (int i = 0; i < entMax; i++)
|
||||
{
|
||||
f.Printf("\t%llu", m_CombinedStats.m_PerHeightSpawners[y][i]);
|
||||
}
|
||||
f.Printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -31,6 +31,8 @@ public:
|
||||
UInt64 m_NumEntities;
|
||||
UInt64 m_NumTileEntities;
|
||||
UInt64 m_NumTileTicks;
|
||||
UInt64 m_PerHeightBlockCounts[256][256]; // First dimension is the height, second dimension is BlockType
|
||||
UInt64 m_PerHeightSpawners[256][entMax + 1]; // First dimension is the height, second dimension is spawned entity type
|
||||
int m_MinChunkX, m_MaxChunkX; // X coords range
|
||||
int m_MinChunkZ, m_MaxChunkZ; // Z coords range
|
||||
|
||||
@ -74,6 +76,8 @@ protected:
|
||||
|
||||
virtual bool OnEmptySection(unsigned char a_Y) override;
|
||||
|
||||
virtual bool OnSectionsFinished(void) override { return false; } // continue processing
|
||||
|
||||
virtual bool OnEntity(
|
||||
const AString & a_EntityType,
|
||||
double a_PosX, double a_PosY, double a_PosZ,
|
||||
@ -128,9 +132,11 @@ protected:
|
||||
void JoinResults(void);
|
||||
void SaveBiomes(void);
|
||||
void SaveBlockTypes(void);
|
||||
void SavePerHeightBlockTypes(void);
|
||||
void SaveBiomeBlockTypes(void);
|
||||
void SaveStatistics(void);
|
||||
void SaveSpawners(void);
|
||||
void SavePerHeightSpawners(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -272,7 +272,7 @@ extern const char * GetEntityTypeString(eEntityType a_EntityType)
|
||||
int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask (Windows-specific)
|
||||
DWORD Affinity, ProcAffinity;
|
||||
DWORD_PTR Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
|
4
Tools/BiomeVisualiser/.gitignore
vendored
4
Tools/BiomeVisualiser/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
Debug/
|
||||
logs/
|
||||
Release/
|
||||
Release profiled/
|
@ -1,338 +0,0 @@
|
||||
|
||||
// BiomeCache.cpp
|
||||
|
||||
// Implements the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int GetNumCores(void)
|
||||
{
|
||||
// Get number of cores by querying the system process affinity mask
|
||||
DWORD Affinity, ProcAffinity;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity);
|
||||
int NumCores = 0;
|
||||
while (Affinity > 0)
|
||||
{
|
||||
if ((Affinity & 1) == 1)
|
||||
{
|
||||
NumCores++;
|
||||
}
|
||||
Affinity >>= 1;
|
||||
} // while (Affinity > 0)
|
||||
return NumCores;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::cBiomeCache(void) :
|
||||
m_Source(NULL),
|
||||
m_BaseX(-100000),
|
||||
m_BaseZ(-100000),
|
||||
m_Available(NULL),
|
||||
m_IsTerminatingThreads(false)
|
||||
{
|
||||
int NumThreads = GetNumCores();
|
||||
NumThreads--; // One core should be left for the system to run on ;)
|
||||
for (int i = NumThreads; i > 0; i--)
|
||||
{
|
||||
cThread * Thread = new cThread(*this);
|
||||
m_Threads.push_back(Thread);
|
||||
Thread->Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeCache::~cBiomeCache()
|
||||
{
|
||||
m_IsTerminatingThreads = true;
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
m_evtQueued.Set();
|
||||
}
|
||||
for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr)
|
||||
{
|
||||
delete *itr;
|
||||
}
|
||||
m_Threads.clear();
|
||||
|
||||
SetSource(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeSource::eAvailability cBiomeCache::GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes)
|
||||
{
|
||||
if (m_Source == NULL)
|
||||
{
|
||||
return baNever;
|
||||
}
|
||||
|
||||
// Look up using the cache:
|
||||
int x = a_ChunkX - m_BaseX;
|
||||
int z = a_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// Outside the cached region
|
||||
return baNever;
|
||||
}
|
||||
|
||||
cCSLock Lock(m_CS);
|
||||
cItem * Item = m_Available[x + m_Width * z];
|
||||
if (Item == NULL)
|
||||
{
|
||||
// Item hasn't been processed yet
|
||||
return baLater;
|
||||
}
|
||||
if (Item->m_IsValid)
|
||||
{
|
||||
memcpy(a_Biomes, Item->m_Biomes, sizeof(a_Biomes));
|
||||
return baNow;
|
||||
}
|
||||
|
||||
// Item has been processed, but the underlying source refused to give the data to us
|
||||
return baNever;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
cTimer Timer("Cache: HintViewArea");
|
||||
|
||||
if (
|
||||
(a_MinChunkX == m_BaseX) &&
|
||||
(a_MaxChunkX == m_BaseX + m_Width - 1) &&
|
||||
(a_MinChunkZ == m_BaseZ) &&
|
||||
(a_MaxChunkZ == m_BaseZ + m_Height - 1)
|
||||
)
|
||||
{
|
||||
// The same set of parameters, bail out
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Source != NULL)
|
||||
{
|
||||
m_Source->HintViewArea(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
}
|
||||
|
||||
int NewWidth = a_MaxChunkX - a_MinChunkX + 1;
|
||||
int NewHeight = a_MaxChunkZ - a_MinChunkZ + 1;
|
||||
|
||||
// Make a new empty cache table:
|
||||
pItem * NewAvailable = new pItem[NewWidth * NewHeight];
|
||||
for (int i = NewWidth * NewHeight - 1; i >= 0; --i)
|
||||
{
|
||||
NewAvailable[i] = NULL;
|
||||
}
|
||||
|
||||
// Move the common contents of the old table into the new table:
|
||||
cCSLock Lock(m_CS);
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
int OldZ = z + a_MinChunkZ - m_BaseZ;
|
||||
if ((OldZ < 0) || (OldZ >= m_Height))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
int OldX = x + a_MinChunkX - m_BaseX;
|
||||
if ((OldX < 0) || (OldX >= m_Width))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NewAvailable[x + NewWidth * z] = m_Available[OldX + m_Width * OldZ];
|
||||
m_Available[OldX + m_Width * OldZ] = NULL;
|
||||
} // for x
|
||||
} // for z
|
||||
|
||||
// All items that aren't common go into the pool:
|
||||
for (int idx = 0, z = 0; z < m_Height; z++)
|
||||
{
|
||||
for (int x = 0; x < m_Width; ++x, ++idx)
|
||||
{
|
||||
if (m_Available[idx] != NULL)
|
||||
{
|
||||
m_Pool.push_back(m_Available[idx]);
|
||||
m_Available[idx] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the cache table:
|
||||
delete m_Available;
|
||||
m_Available = NewAvailable;
|
||||
m_Width = NewWidth;
|
||||
m_Height = NewHeight;
|
||||
m_BaseX = a_MinChunkX;
|
||||
m_BaseZ = a_MinChunkZ;
|
||||
|
||||
// Remove all items outside the coords:
|
||||
FilterOutItems(m_Queue, a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ);
|
||||
|
||||
// Queue all items from inside the coords into m_Queue:
|
||||
for (int z = 0; z < NewHeight; z++)
|
||||
{
|
||||
for (int x = 0; x < NewWidth; x++)
|
||||
{
|
||||
if (m_Available[x + m_Width * z] != NULL)
|
||||
{
|
||||
// Already calculated, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_Pool.empty())
|
||||
{
|
||||
m_Pool.push_back(new cItem(x + a_MinChunkX, z + a_MinChunkZ));
|
||||
}
|
||||
ASSERT(!m_Pool.empty());
|
||||
m_Pool.back()->m_ChunkX = x + a_MinChunkX;
|
||||
m_Pool.back()->m_ChunkZ = z + a_MinChunkZ;
|
||||
m_Queue.push_back(m_Pool.back());
|
||||
m_Pool.pop_back();
|
||||
m_evtQueued.Set();
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
// TODO: Stop all threads, so that they don't use the source anymore!
|
||||
|
||||
delete m_Source;
|
||||
m_Source = a_Source;
|
||||
|
||||
// Invalidate cache contents:
|
||||
cCSLock Lock(m_CS);
|
||||
m_BaseX = -10000;
|
||||
m_BaseZ = -10000;
|
||||
m_Pool.splice(m_Pool.end(), m_Queue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ)
|
||||
{
|
||||
for (cItems::iterator itr = a_Items.begin(); itr != a_Items.end();)
|
||||
{
|
||||
if (
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX) ||
|
||||
((*itr)->m_ChunkX < a_MinChunkX) ||
|
||||
((*itr)->m_ChunkX > a_MaxChunkX)
|
||||
)
|
||||
{
|
||||
m_Pool.push_back(*itr);
|
||||
itr = a_Items.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::thrProcessQueueItem(void)
|
||||
{
|
||||
if (m_Source == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cItem * Item = NULL;
|
||||
{
|
||||
cCSLock Lock(m_CS);
|
||||
if (m_Queue.empty())
|
||||
{
|
||||
cCSUnlock Unlock(Lock);
|
||||
m_evtQueued.Wait();
|
||||
}
|
||||
if (m_IsTerminatingThreads || m_Queue.empty())
|
||||
{
|
||||
// We've been woken up only to die / spurious wakeup
|
||||
return;
|
||||
}
|
||||
Item = m_Queue.back();
|
||||
m_Queue.pop_back();
|
||||
}
|
||||
|
||||
// Process the item:
|
||||
Item->m_IsValid = (m_Source->GetBiome(Item->m_ChunkX, Item->m_ChunkZ, Item->m_Biomes) == baNow);
|
||||
|
||||
// Store result:
|
||||
cCSLock Lock(m_CS);
|
||||
int x = Item->m_ChunkX - m_BaseX;
|
||||
int z = Item->m_ChunkZ - m_BaseZ;
|
||||
if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height))
|
||||
{
|
||||
// The cache rectangle has changed under our fingers, drop this chunk
|
||||
return;
|
||||
}
|
||||
m_Available[x + m_Width * z] = Item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cItem:
|
||||
|
||||
cBiomeCache::cItem::cItem(int a_ChunkX, int a_ChunkZ) :
|
||||
m_ChunkX(a_ChunkX),
|
||||
m_ChunkZ(a_ChunkZ)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cBiomeCache::cThread:
|
||||
|
||||
cBiomeCache::cThread::cThread(cBiomeCache & a_Parent) :
|
||||
super("Biome cache thread"),
|
||||
m_Parent(a_Parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeCache::cThread::Execute(void)
|
||||
{
|
||||
while (!m_ShouldTerminate && !m_Parent.m_IsTerminatingThreads)
|
||||
{
|
||||
m_Parent.thrProcessQueueItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,96 +0,0 @@
|
||||
|
||||
// BiomeCache.h
|
||||
|
||||
// Declares the cBiomeCache class representing a biome source that caches data from the underlying biome source
|
||||
|
||||
/*
|
||||
This cache works a bit differently than regular caches.
|
||||
It first receives the hint of area that it will need to provide.
|
||||
The Cache uses several threads to request biomes from the underlying source to fill that area.
|
||||
While the area is being filled, requests for biomes may already come, such requests are answered with baLater if no data yet.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeSource.h"
|
||||
#include "../src/OSSupport/IsThread.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeCache :
|
||||
public cBiomeSource
|
||||
{
|
||||
public:
|
||||
cBiomeCache(void);
|
||||
~cBiomeCache();
|
||||
|
||||
// cBiomeSource overrides:
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override;
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override;
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source ptr
|
||||
|
||||
protected:
|
||||
class cItem
|
||||
{
|
||||
public:
|
||||
cItem(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
int m_ChunkX;
|
||||
int m_ChunkZ;
|
||||
bool m_IsValid;
|
||||
cChunkDef::BiomeMap m_Biomes;
|
||||
} ;
|
||||
|
||||
typedef cItem * pItem;
|
||||
typedef std::list<pItem> cItems;
|
||||
|
||||
class cThread :
|
||||
public cIsThread
|
||||
{
|
||||
typedef cIsThread super;
|
||||
|
||||
public:
|
||||
cThread(cBiomeCache & a_Parent);
|
||||
|
||||
// cIsThread overrides:
|
||||
virtual void Execute(void) override;
|
||||
|
||||
protected:
|
||||
cBiomeCache & m_Parent;
|
||||
} ;
|
||||
|
||||
typedef std::list<cThread *> cThreads;
|
||||
|
||||
cBiomeSource * m_Source;
|
||||
|
||||
cCriticalSection m_CS;
|
||||
int m_BaseX; ///< MinChunkX for the m_Available rectangle
|
||||
int m_BaseZ; ///< MinChunkZ for the m_Available rectangle
|
||||
int m_Width; ///< Width of the m_Available rectangle
|
||||
int m_Height; ///< Height of the m_Available rectangle
|
||||
pItem * m_Available; ///< Items that have already been processed (baNow or baNever), [x + m_Width * z]
|
||||
cItems m_Queue; ///< Items that are queued for processing (baLater)
|
||||
cItems m_Pool; ///< Items that are not needed anymore, can be reused for other coords
|
||||
|
||||
cEvent m_evtQueued; // Triggerred when an item is added to m_Queue
|
||||
|
||||
cThreads m_Threads; // Threads that update the cache.
|
||||
bool m_IsTerminatingThreads; // Set to true to indicate to all threads that they should exit
|
||||
|
||||
/// Removes from a_Items all items that are outside of the given coords, moves those into m_Pool
|
||||
void FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ);
|
||||
|
||||
/// Processes one item from m_Queue into m_Available. Blocks if m_Queue is empty; respects m_IsTerminatingThreads
|
||||
void thrProcessQueueItem(void);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,114 +0,0 @@
|
||||
|
||||
// BiomeColors.cpp
|
||||
|
||||
// Implements the g_BiomeColors[] array preparation based on a stored biome-to-color map
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeColors.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int g_BiomeColors[256];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static struct
|
||||
{
|
||||
EMCSBiome Biome;
|
||||
int Color;
|
||||
} g_BiomeColorMap[] =
|
||||
{
|
||||
{ biOcean, 0x000070 },
|
||||
{ biPlains, 0x8db360 },
|
||||
{ biDesert, 0xfa9418 },
|
||||
{ biExtremeHills, 0x606060 },
|
||||
{ biForest, 0x056621 },
|
||||
{ biTaiga, 0x0b6659 },
|
||||
{ biSwampland, 0x2fffda },
|
||||
{ biRiver, 0x3030af },
|
||||
{ biHell, 0x7f0000 },
|
||||
{ biSky, 0x007fff },
|
||||
{ biFrozenOcean, 0xa0a0df },
|
||||
{ biFrozenRiver, 0xa0a0ff },
|
||||
{ biIcePlains, 0xffffff },
|
||||
{ biIceMountains, 0xa0a0a0 },
|
||||
{ biMushroomIsland, 0xff00ff },
|
||||
{ biMushroomShore, 0xa000ff },
|
||||
{ biBeach, 0xfade55 },
|
||||
{ biDesertHills, 0xd25f12 },
|
||||
{ biForestHills, 0x22551c },
|
||||
{ biTaigaHills, 0x163933 },
|
||||
{ biExtremeHillsEdge, 0x7f8f7f },
|
||||
{ biJungle, 0x537b09 },
|
||||
{ biJungleHills, 0x2c4205 },
|
||||
|
||||
{ biJungleEdge, 0x628b17 },
|
||||
{ biDeepOcean, 0x000030 },
|
||||
{ biStoneBeach, 0xa2a284 },
|
||||
{ biColdBeach, 0xfaf0c0 },
|
||||
{ biBirchForest, 0x307444 },
|
||||
{ biBirchForestHills, 0x1f5f32 },
|
||||
{ biRoofedForest, 0x40511a },
|
||||
{ biColdTaiga, 0x31554a },
|
||||
{ biColdTaigaHills, 0x597d72 },
|
||||
{ biMegaTaiga, 0x596651 },
|
||||
{ biMegaTaigaHills, 0x596659 },
|
||||
{ biExtremeHillsPlus, 0x507050 },
|
||||
{ biSavanna, 0xbdb25f },
|
||||
{ biSavannaPlateau, 0xa79d64 },
|
||||
{ biMesa, 0xd94515 },
|
||||
{ biMesaPlateauF, 0xb09765 },
|
||||
{ biMesaPlateau, 0xca8c65 },
|
||||
|
||||
// M variants:
|
||||
{ biSunflowerPlains, 0xb5db88 },
|
||||
{ biDesertM, 0xffbc40 },
|
||||
{ biExtremeHillsM, 0x888888 },
|
||||
{ biFlowerForest, 0x2d8e49 },
|
||||
{ biTaigaM, 0x338e81 },
|
||||
{ biSwamplandM, 0x07f9b2 },
|
||||
{ biIcePlainsSpikes, 0xb4dcdc },
|
||||
{ biJungleM, 0x7ba331 },
|
||||
{ biJungleEdgeM, 0x628b17 },
|
||||
{ biBirchForestM, 0x589c6c },
|
||||
{ biBirchForestHillsM, 0x47875a },
|
||||
{ biRoofedForestM, 0x687942 },
|
||||
{ biColdTaigaM, 0x243f36 },
|
||||
{ biMegaSpruceTaiga, 0x454f3e },
|
||||
{ biMegaSpruceTaigaHills, 0x454f4e },
|
||||
{ biExtremeHillsPlusM, 0x789878 },
|
||||
{ biSavannaM, 0xe5da87 },
|
||||
{ biSavannaPlateauM, 0xa79d74 },
|
||||
{ biMesaBryce, 0xff6d3d },
|
||||
{ biMesaPlateauFM, 0xd8bf8d },
|
||||
{ biMesaPlateauM, 0xf2b48d },
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static class cBiomeColorsInitializer
|
||||
{
|
||||
public:
|
||||
cBiomeColorsInitializer(void)
|
||||
{
|
||||
// Reset all colors to gray:
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColors); i++)
|
||||
{
|
||||
g_BiomeColors[i] = 0x7f7f7f;
|
||||
}
|
||||
for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColorMap); i++)
|
||||
{
|
||||
g_BiomeColors[g_BiomeColorMap[i].Biome] = g_BiomeColorMap[i].Color;
|
||||
}
|
||||
}
|
||||
} g_Initializer;
|
||||
|
||||
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
|
||||
// BiomeColors.h
|
||||
|
||||
// Declares the g_BiomeColors[] array used for biome color lookup
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern int g_BiomeColors[256];
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,119 +0,0 @@
|
||||
|
||||
// BiomeRenderer.cpp
|
||||
|
||||
// Implements the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "Pixmap.h"
|
||||
#include "Timer.h"
|
||||
#include "BiomeColors.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeRenderer::cBiomeRenderer(void) :
|
||||
m_OriginX(160),
|
||||
m_OriginY(160),
|
||||
m_Zoom(1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::SetSource(cBiomeSource * a_Source)
|
||||
{
|
||||
m_Cache.SetSource(a_Source);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeRenderer::Render(cPixmap & a_Pixmap)
|
||||
{
|
||||
cTimer Timer("cBiomeRenderer::Render");
|
||||
|
||||
int Wid = a_Pixmap.GetWidth();
|
||||
int Hei = a_Pixmap.GetHeight();
|
||||
|
||||
// Hint the approximate view area to the biome source so that it can adjust its caches:
|
||||
int MinBlockX = ( - m_OriginX) * m_Zoom;
|
||||
int MaxBlockX = (Wid - m_OriginX) * m_Zoom;
|
||||
int MinBlockZ = ( - m_OriginY) * m_Zoom;
|
||||
int MaxBlockZ = (Hei - m_OriginY) * m_Zoom;
|
||||
m_Cache.HintViewArea(MinBlockX / 16 - 1, MaxBlockX / 16 + 1, MinBlockZ / 16 - 1, MaxBlockZ / 16 + 1);
|
||||
|
||||
// Hold one current chunk of biome data:
|
||||
int CurChunkX = -10000;
|
||||
int CurChunkZ = -10000;
|
||||
cChunkDef::BiomeMap CurBiomes;
|
||||
|
||||
bool res = false;
|
||||
|
||||
for (int y = 0; y < Hei; y++)
|
||||
{
|
||||
int BlockZ = (y - m_OriginY) * m_Zoom;
|
||||
int ChunkZ = (BlockZ >= 0) ? (BlockZ / 16) : ((BlockZ + 1) / 16 - 1);
|
||||
int RelZ = BlockZ - ChunkZ * 16;
|
||||
for (int x = 0; x < Wid; x++)
|
||||
{
|
||||
int BlockX = (x - m_OriginX) * m_Zoom;
|
||||
int ChunkX = (BlockX >= 0) ? (BlockX / 16) : ((BlockX + 1) / 16 - 1);
|
||||
int RelX = BlockX - ChunkX * 16;
|
||||
if ((ChunkZ != CurChunkZ) || (ChunkX != CurChunkX))
|
||||
{
|
||||
CurChunkX = ChunkX;
|
||||
CurChunkZ = ChunkZ;
|
||||
switch (m_Cache.GetBiome(CurChunkX, CurChunkZ, CurBiomes))
|
||||
{
|
||||
case cBiomeSource::baLater:
|
||||
{
|
||||
res = true;
|
||||
// fallthrough:
|
||||
}
|
||||
case cBiomeSource::baNever:
|
||||
{
|
||||
for (int i = 0; i < ARRAYCOUNT(CurBiomes); i++)
|
||||
{
|
||||
CurBiomes[i] = biInvalidBiome;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch (Biome availability)
|
||||
}
|
||||
EMCSBiome Biome = cChunkDef::GetBiome(CurBiomes, RelX, RelZ);
|
||||
a_Pixmap.SetPixel(x, y, GetBiomeColor(Biome));
|
||||
} // for x
|
||||
} // for y
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeRenderer::GetBiomeColor(EMCSBiome a_Biome)
|
||||
{
|
||||
if ((a_Biome < 0) || (a_Biome >= ARRAYCOUNT(g_BiomeColors)))
|
||||
{
|
||||
return 0xff0000;
|
||||
}
|
||||
return g_BiomeColors[a_Biome];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeRenderer::MoveViewBy(int a_OffsX, int a_OffsY)
|
||||
{
|
||||
m_OriginX += a_OffsX;
|
||||
m_OriginY += a_OffsY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
|
||||
// BiomeRenderer.h
|
||||
|
||||
// Declares the cBiomeRenderer class representing the rendering engine
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BiomeCache.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd: Pixmap.h
|
||||
class cPixmap;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeRenderer
|
||||
{
|
||||
public:
|
||||
cBiomeRenderer(void);
|
||||
|
||||
void SetSource(cBiomeSource * a_Source); // Takes ownership of the source
|
||||
|
||||
/// Renders the biomes into the given pixmap. Returns true if some biome data was missing and can be retrieved later
|
||||
bool Render(cPixmap & a_Pixmap);
|
||||
|
||||
/// Returns the RGB color value for the specified biome
|
||||
int GetBiomeColor(EMCSBiome a_Biome);
|
||||
|
||||
void MoveViewBy(int a_OffsX, int a_OffsY);
|
||||
|
||||
void SetZoom(int a_NewZoom)
|
||||
{
|
||||
m_Zoom = a_NewZoom;
|
||||
}
|
||||
|
||||
protected:
|
||||
cBiomeCache m_Cache;
|
||||
|
||||
int m_OriginX;
|
||||
int m_OriginY;
|
||||
int m_Zoom;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
|
||||
// BiomeSource.h
|
||||
|
||||
// Declares the cBiomeSource abstract class used as an interface for getting biomes from any source
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "ChunkDef.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeSource abstract
|
||||
{
|
||||
public:
|
||||
enum eAvailability
|
||||
{
|
||||
baNow, // Data returned now
|
||||
baLater, // Data not returned, but will be available later, try again after a while
|
||||
baNever, // Data not returned, will not be available at all
|
||||
} ;
|
||||
|
||||
/// Fills a_Biomes with the biomes for the chunk specified
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) = 0;
|
||||
|
||||
/// Used to inform the source about the view area that will be queried in the near future.
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,247 +0,0 @@
|
||||
|
||||
// BiomeViewWnd.cpp
|
||||
|
||||
// Implements the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
#include "Globals.h"
|
||||
#include "BiomeViewWnd.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "GeneratorBiomeSource.h"
|
||||
#include "iniFile/iniFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const int TIMER_RERENDER = 1200;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeViewWnd::cBiomeViewWnd(void) :
|
||||
m_Wnd(NULL),
|
||||
m_Thunk(&cBiomeViewWnd::WndProc, this),
|
||||
m_IsLButtonDown(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title)
|
||||
{
|
||||
ASSERT(m_Wnd == NULL);
|
||||
|
||||
InitBiomeView();
|
||||
|
||||
// Create a regular STATIC window, then override its window procedure with our own. No need for obnoxious RegisterWindowClass() stuff.
|
||||
m_Wnd = CreateWindow("STATIC", a_Title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, a_ParentWnd, NULL, GetModuleHandle(NULL), NULL);
|
||||
if (m_Wnd == NULL)
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return false;
|
||||
}
|
||||
SetWindowLongPtr(m_Wnd, GWLP_WNDPROC, m_Thunk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeViewWnd::InitBiomeView(void)
|
||||
{
|
||||
cIniFile IniFile;
|
||||
IniFile.ReadFile("world.ini");
|
||||
int Seed = IniFile.GetValueSetI("Generator", "Seed", 0);
|
||||
bool CacheOffByDefault = false;
|
||||
m_BiomeGen = cBiomeGen::CreateBiomeGen(IniFile, Seed, CacheOffByDefault);
|
||||
m_Renderer.SetSource(new cGeneratorBiomeSource(m_BiomeGen));
|
||||
IniFile.WriteFile("world.ini");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeViewWnd::SetZoom(int a_NewZoom)
|
||||
{
|
||||
m_Renderer.SetZoom(a_NewZoom);
|
||||
Redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cBiomeViewWnd::Redraw(void)
|
||||
{
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (a_Msg)
|
||||
{
|
||||
case WM_CHAR: return OnChar (wParam, lParam);
|
||||
case WM_CLOSE: return OnClose ();
|
||||
case WM_COMMAND: return OnCommand (wParam, lParam);
|
||||
case WM_LBUTTONDOWN: return OnLButtonDown(wParam, lParam);
|
||||
case WM_LBUTTONUP: return OnLButtonUp (wParam, lParam);
|
||||
case WM_MOUSEMOVE: return OnMouseMove (wParam, lParam);
|
||||
case WM_PAINT: return OnPaint ();
|
||||
case WM_TIMER: return OnTimer (wParam);
|
||||
}
|
||||
return ::DefWindowProc(a_Wnd, a_Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnChar(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case '1': SetZoom(1); break;
|
||||
case '2': SetZoom(2); break;
|
||||
case '3': SetZoom(3); break;
|
||||
case '4': SetZoom(4); break;
|
||||
case '5': SetZoom(5); break;
|
||||
case '6': SetZoom(6); break;
|
||||
case '7': SetZoom(7); break;
|
||||
case '8': SetZoom(8); break;
|
||||
case 27:
|
||||
{
|
||||
// Esc pressed, exit
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnClose(void)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// TODO: Handle menu commands, when we get menu
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
m_IsLButtonDown = true;
|
||||
GetCursorPos(&m_MouseDown);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!m_IsLButtonDown)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
POINT pnt;
|
||||
GetCursorPos(&pnt);
|
||||
m_Renderer.MoveViewBy(pnt.x - m_MouseDown.x, pnt.y - m_MouseDown.y);
|
||||
m_MouseDown = pnt;
|
||||
Redraw();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
OnMouseMove(wParam, lParam); // Last movement - if the mouse move hasn't been reported due to speed
|
||||
m_IsLButtonDown = false;
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnPaint(void)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC DC = BeginPaint(m_Wnd, &ps);
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(m_Wnd, &rc);
|
||||
int Wid = rc.right - rc.left;
|
||||
int Hei = rc.bottom - rc.top;
|
||||
if ((m_Pixmap.GetWidth() != Wid) || (m_Pixmap.GetHeight() != Hei))
|
||||
{
|
||||
m_Pixmap.SetSize(Wid, Hei);
|
||||
if (m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
m_Pixmap.DrawToDC(DC, 0, 0);
|
||||
|
||||
EndPaint(m_Wnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LRESULT cBiomeViewWnd::OnTimer(WPARAM wParam)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case TIMER_RERENDER:
|
||||
{
|
||||
if (!m_Renderer.Render(m_Pixmap))
|
||||
{
|
||||
KillTimer(m_Wnd, TIMER_RERENDER);
|
||||
}
|
||||
InvalidateRect(m_Wnd, NULL, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
|
||||
// BiomeViewWnd.h
|
||||
|
||||
// Declares the cBiomeViewWnd class representing the window that displays biomes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "WndProcThunk.h"
|
||||
#include "BiomeRenderer.h"
|
||||
#include "BiomeCache.h"
|
||||
#include "Pixmap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cBiomeGen;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeViewWnd
|
||||
{
|
||||
public:
|
||||
cBiomeViewWnd(void);
|
||||
|
||||
bool Create(HWND a_ParentWnd, LPCTSTR a_Title);
|
||||
|
||||
protected:
|
||||
HWND m_Wnd;
|
||||
CWndProcThunk<cBiomeViewWnd> m_Thunk;
|
||||
|
||||
cBiomeRenderer m_Renderer;
|
||||
cPixmap m_Pixmap;
|
||||
|
||||
/// The generator that is to be visualised
|
||||
cBiomeGen * m_BiomeGen;
|
||||
|
||||
bool m_IsLButtonDown;
|
||||
POINT m_MouseDown;
|
||||
|
||||
|
||||
void InitBiomeView(void);
|
||||
|
||||
void SetZoom(int a_NewZoom);
|
||||
void Redraw(void);
|
||||
|
||||
LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// Message handlers:
|
||||
LRESULT OnChar (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnClose (void);
|
||||
LRESULT OnCommand (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnMouseMove (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnLButtonUp (WPARAM wParam, LPARAM lParam);
|
||||
LRESULT OnPaint (void);
|
||||
LRESULT OnTimer (WPARAM wParam);
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
|
||||
// BiomeVisualiser.cpp
|
||||
|
||||
// Implements the cBiomeVisualiser class representing the entire app. Also implements the WinMain() entrypoint
|
||||
|
||||
#include "Globals.h"
|
||||
#include "time.h"
|
||||
#include "BiomeVisualiser.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int WINAPI WinMain(HINSTANCE a_Instance, HINSTANCE a_PrevInstance, LPSTR a_CmdLine, int a_ShowCmd)
|
||||
{
|
||||
cBiomeVisualiser App;
|
||||
return App.Run();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cBiomeVisualiser::cBiomeVisualiser(void) :
|
||||
m_Logger(new cMCLogger(Printf("BiomeVisualiser_%08x.log", time(NULL))))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cBiomeVisualiser::Run(void)
|
||||
{
|
||||
if (!m_MainWnd.Create(GetDesktopWindow(), TEXT("BiomeVisualiser")))
|
||||
{
|
||||
LOGERROR("Cannot create main window: %d", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} // while (GetMessage)
|
||||
return msg.lParam;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
|
||||
// BiomeVisualiser.h
|
||||
|
||||
// Declares the cBiomeVisualiser class representing the entire application
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "BiomeViewWnd.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cBiomeVisualiser
|
||||
{
|
||||
public:
|
||||
cBiomeVisualiser(void);
|
||||
|
||||
int Run(void);
|
||||
|
||||
protected:
|
||||
cBiomeViewWnd m_MainWnd;
|
||||
|
||||
cMCLogger * m_Logger;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BiomeVisualiser", "BiomeVisualiser.vcproj", "{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release profiled|Win32 = Release profiled|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.Build.0 = Release profiled|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,527 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="BiomeVisualiser"
|
||||
ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
|
||||
RootNamespace="BiomeVisualiser"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../src;../../lib"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="../../src;../../lib"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="2"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release profiled|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="../../src;../../lib"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
EnableEnhancedInstructionSet="2"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="Globals.h"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
Profile="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\BiomeCache.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeCache.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeColors.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeColors.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeRenderer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeRenderer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeSource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeViewWnd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeViewWnd.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeVisualiser.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\BiomeVisualiser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\GeneratorBiomeSource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Pixmap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Pixmap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Timer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\WndProcThunk.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Shared"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\BiomeDef.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BiomeDef.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BlockID.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\BlockID.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\ChunkDef.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Enchantments.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Enchantments.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\WorldStorage\FastNBT.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\FastRandom.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\FastRandom.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Globals.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release profiled|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Globals.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Item.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Log.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Log.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\MCLogger.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\MCLogger.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Noise.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Noise.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Noise.inc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StringUtils.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\VoronoiMap.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\VoronoiMap.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="OSSupport"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\CriticalSection.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Event.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\IsThread.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\OSSupport\Sleep.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Generating"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\Generating\BioGen.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Generating\BioGen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Generating\ComposableGenerator.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="iniFile"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\lib\iniFile\iniFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\lib\iniFile\iniFile.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,42 +0,0 @@
|
||||
|
||||
// GeneratorBiomeSource.h
|
||||
|
||||
// Declares the cGeneratorBiomeSource that adapts a cBiomeGen into a cBiomeSource
|
||||
|
||||
#include "../src/Generating/BioGen.h"
|
||||
#include "BiomeSource.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cGeneratorBiomeSource :
|
||||
public cBiomeSource
|
||||
{
|
||||
public:
|
||||
cGeneratorBiomeSource(cBiomeGen * a_Generator) : m_Generator(a_Generator) {} // Takes ownership of the generator ptr
|
||||
|
||||
~cGeneratorBiomeSource()
|
||||
{
|
||||
delete m_Generator;
|
||||
}
|
||||
|
||||
// cBiomeSource overrides:
|
||||
virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override
|
||||
{
|
||||
m_Generator->GenBiomes(a_ChunkX, a_ChunkZ, a_Biomes);
|
||||
return baNow;
|
||||
}
|
||||
|
||||
virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override
|
||||
{
|
||||
// Nothing needed
|
||||
}
|
||||
|
||||
protected:
|
||||
cBiomeGen * m_Generator;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,120 +0,0 @@
|
||||
|
||||
// Pixmap.cpp
|
||||
|
||||
// Implements the cPixmap class that represents a RGB pixmap and allows simple operations on it
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Pixmap.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPixmap::cPixmap(void) :
|
||||
m_Width(0),
|
||||
m_Height(0),
|
||||
m_Stride(0),
|
||||
m_Pixels(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPixmap::cPixmap(int a_Width, int a_Height) :
|
||||
m_Width(0),
|
||||
m_Height(0),
|
||||
m_Stride(0),
|
||||
m_Pixels(NULL)
|
||||
{
|
||||
SetSize(a_Width, a_Height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cPixmap::~cPixmap()
|
||||
{
|
||||
delete m_Pixels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::SetSize(int a_Width, int a_Height)
|
||||
{
|
||||
delete m_Pixels;
|
||||
m_Pixels = new int[a_Width * a_Height];
|
||||
m_Width = a_Width;
|
||||
m_Height = a_Height;
|
||||
m_Stride = m_Width; // Currently we don't need a special stride value, but let's support it for the future :)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::SetPixel(int a_X, int a_Y, int a_Color)
|
||||
{
|
||||
ASSERT(a_X >= 0);
|
||||
ASSERT(a_X < m_Width);
|
||||
ASSERT(a_Y >= 0);
|
||||
ASSERT(a_Y < m_Height);
|
||||
|
||||
m_Pixels[a_X + a_Y * m_Stride] = a_Color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cPixmap::GetPixel(int a_X, int a_Y) const
|
||||
{
|
||||
ASSERT(a_X >= 0);
|
||||
ASSERT(a_X < m_Width);
|
||||
ASSERT(a_Y >= 0);
|
||||
ASSERT(a_Y < m_Height);
|
||||
|
||||
return m_Pixels[a_X + a_Y * m_Stride];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::Fill(int a_Color)
|
||||
{
|
||||
int NumElements = m_Height * m_Stride;
|
||||
for (int i = 0; i < NumElements; i++)
|
||||
{
|
||||
m_Pixels[i] = a_Color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPixmap::DrawToDC(HDC a_DC, int a_OriginX, int a_OriginY)
|
||||
{
|
||||
BITMAPINFO bmi;
|
||||
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
||||
bmi.bmiHeader.biWidth = m_Width;
|
||||
bmi.bmiHeader.biHeight = -m_Height; // Negative, we are top-down, unlike BMPs
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = m_Stride * m_Height * 4;
|
||||
bmi.bmiHeader.biXPelsPerMeter = 1440;
|
||||
bmi.bmiHeader.biYPelsPerMeter = 1440;
|
||||
bmi.bmiHeader.biClrUsed = 0;
|
||||
bmi.bmiHeader.biClrImportant = 0;
|
||||
SetDIBitsToDevice(a_DC, a_OriginX, a_OriginY, m_Width, m_Height, 0, 0, 0, m_Height, m_Pixels, &bmi, DIB_RGB_COLORS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,39 +0,0 @@
|
||||
|
||||
// Pixmap.h
|
||||
|
||||
// Declares a cPixmap class that represents a RGB pixmap and allows simple operations on it
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cPixmap
|
||||
{
|
||||
public:
|
||||
cPixmap(void);
|
||||
cPixmap(int a_Width, int a_Height);
|
||||
~cPixmap();
|
||||
|
||||
void SetSize(int a_Width, int a_Height);
|
||||
|
||||
int GetWidth (void) const { return m_Width; }
|
||||
int GetHeight(void) const { return m_Height; }
|
||||
|
||||
void SetPixel(int a_X, int a_Y, int a_Color);
|
||||
int GetPixel(int a_X, int a_Y) const;
|
||||
void Fill(int a_Color);
|
||||
|
||||
void DrawToDC(HDC a_DC, int a_OriginX, int a_OriginY);
|
||||
|
||||
protected:
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_Stride;
|
||||
int * m_Pixels;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
|
||||
// Timer.h
|
||||
|
||||
// Declares the cTimer class representing a RAII class that measures time from its creation till its destruction
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "time.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cTimer
|
||||
{
|
||||
public:
|
||||
cTimer(const AString & a_Title) :
|
||||
m_Title(a_Title),
|
||||
m_StartTime(clock())
|
||||
{
|
||||
}
|
||||
|
||||
~cTimer()
|
||||
{
|
||||
clock_t NumTicks = clock() - m_StartTime;
|
||||
LOG("%s took %d ticks (%.02f sec)", m_Title.c_str(), NumTicks, (double)NumTicks / CLOCKS_PER_SEC);
|
||||
}
|
||||
|
||||
protected:
|
||||
AString m_Title;
|
||||
clock_t m_StartTime;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
@ -1,143 +0,0 @@
|
||||
|
||||
// WndProcThunk.h
|
||||
|
||||
// Interfaces to the CWndProcThunk class responsible for WNDPROC class-thunking
|
||||
// For details, see http://www.hackcraft.net/cpp/windowsThunk/thiscall/
|
||||
// Also available is a CDlgProcThunk class doing the same work for DIALOGPROC
|
||||
|
||||
// MD: Made NX-compat by allocating the code structure using VirtualAlloc(..., PAGE_EXECUTE_READWRITE)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
template <class W> class CWndProcThunk;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef WNDPROCTHUNK_H_INCLUDED
|
||||
#define WNDPROCTHUNK_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename To, typename From> inline To union_cast(From fr) throw()
|
||||
{
|
||||
union
|
||||
{
|
||||
From f;
|
||||
To t;
|
||||
} uc;
|
||||
uc.f = fr;
|
||||
return uc.t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4355)
|
||||
|
||||
#if defined(_M_IX86)
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
template <class W> class CWndProcThunk
|
||||
{
|
||||
typedef ::LRESULT (W::* WndProc)(::HWND, ::UINT, ::WPARAM, ::LPARAM);
|
||||
typedef CWndProcThunk ThisClass;
|
||||
|
||||
struct SCode
|
||||
{
|
||||
BYTE m_mov; // mov ECX, m_this
|
||||
W * m_this; //
|
||||
BYTE m_jmp; // jmp m_relproc
|
||||
ptrdiff_t m_relproc; // relative jmp
|
||||
};
|
||||
|
||||
SCode * Code;
|
||||
|
||||
public:
|
||||
ThisClass(WndProc proc, W * obj)
|
||||
{
|
||||
Code = (SCode *)VirtualAlloc(NULL, sizeof(SCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
Code->m_mov = 0xB9,
|
||||
Code->m_this = obj,
|
||||
Code->m_jmp = 0xE9,
|
||||
Code->m_relproc = union_cast<char *>(proc) - reinterpret_cast<char *>(Code) - sizeof(*Code);
|
||||
::FlushInstructionCache(::GetCurrentProcess(), Code, sizeof(*Code));
|
||||
}
|
||||
|
||||
virtual ~CWndProcThunk()
|
||||
{
|
||||
VirtualFree(Code, sizeof(*Code), MEM_RELEASE);
|
||||
Code = NULL;
|
||||
}
|
||||
|
||||
operator ::WNDPROC() const {return reinterpret_cast<::WNDPROC>(Code); }
|
||||
operator ::LONG_PTR() const {return reinterpret_cast<::LONG_PTR>(Code); }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template <class W> class CDlgProcThunk
|
||||
{
|
||||
typedef ::BOOL (W::* DlgProc)(::HWND, ::UINT, ::WPARAM, ::LPARAM);
|
||||
typedef CDlgProcThunk ThisClass;
|
||||
|
||||
struct SCode
|
||||
{
|
||||
BYTE m_mov; // mov ECX, m_this
|
||||
W * m_this; //
|
||||
BYTE m_jmp; // jmp m_relproc
|
||||
ptrdiff_t m_relproc; // relative jmp
|
||||
};
|
||||
|
||||
SCode * Code;
|
||||
|
||||
public:
|
||||
CDlgProcThunk(DlgProc proc, W * obj)
|
||||
{
|
||||
Code = (SCode *)VirtualAlloc(NULL, sizeof(SCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
Code->m_mov = 0xB9,
|
||||
Code->m_this = obj,
|
||||
Code->m_jmp = 0xE9,
|
||||
Code->m_relproc = union_cast<char *>(proc) - reinterpret_cast<char *>(Code) - sizeof(*Code);
|
||||
::FlushInstructionCache(::GetCurrentProcess(), Code, sizeof(*Code));
|
||||
}
|
||||
|
||||
virtual ~CDlgProcThunk()
|
||||
{
|
||||
VirtualFree(Code, sizeof(*Code), MEM_RELEASE);
|
||||
Code = NULL;
|
||||
}
|
||||
|
||||
operator ::DLGPROC() const {return reinterpret_cast<::DLGPROC>(Code); }
|
||||
operator ::LONG_PTR() const {return reinterpret_cast<::LONG_PTR>(Code); }
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#else // _M_IX86
|
||||
#error Only X86 supported
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // WNDPROCTHUNK_H_INCLUDED
|
||||
|
||||
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
@echo off
|
||||
::
|
||||
:: Profiling using a MSVC standalone profiler
|
||||
::
|
||||
:: See http://www.codeproject.com/Articles/144643/Profiling-of-C-Applications-in-Visual-Studio-for-F for details
|
||||
::
|
||||
|
||||
|
||||
|
||||
|
||||
set pt="C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools"
|
||||
set appdir="Release profiled"
|
||||
set app="Release profiled\BiomeVisualiser.exe"
|
||||
set args=""
|
||||
|
||||
:: outputdir is relative to appdir!
|
||||
set outputdir=Profiling
|
||||
set output=profile.vsp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
::Create the output directory, if it didn't exist
|
||||
mkdir %outputdir%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: Start the profiler
|
||||
%pt%\vsperfcmd /start:sample /output:%outputdir%\%output%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Launch the application via the profiler
|
||||
%pt%\vsperfcmd /launch:%app% /args:%args%
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
:: Shut down the profiler (this command waits, until the application is terminated)
|
||||
%pt%\vsperfcmd /shutdown
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:: cd to outputdir, so that the reports are generated there
|
||||
cd %outputdir%
|
||||
|
||||
:: generate the report files (.csv)
|
||||
%pt%\vsperfreport /summary:all %output% /symbolpath:"srv*C:\Programovani\Symbols*http://msdl.microsoft.com/download/symbols"
|
||||
if errorlevel 1 goto haderror
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
goto finished
|
||||
|
||||
|
||||
|
||||
|
||||
:haderror
|
||||
echo An error was encountered
|
||||
pause
|
||||
|
||||
|
||||
|
||||
|
||||
:finished
|
@ -39,14 +39,12 @@ set_exe_flags()
|
||||
set(SHARED_SRC
|
||||
../../src/StringCompression.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/Log.cpp
|
||||
../../src/MCLogger.cpp
|
||||
../../src/LoggerListeners.cpp
|
||||
../../src/Logger.cpp
|
||||
)
|
||||
set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/Log.h
|
||||
../../src/MCLogger.h
|
||||
)
|
||||
flatten_files(SHARED_SRC)
|
||||
flatten_files(SHARED_HDR)
|
||||
|
@ -5,7 +5,8 @@
|
||||
|
||||
#include "Globals.h"
|
||||
#include "MCADefrag.h"
|
||||
#include "MCLogger.h"
|
||||
#include "Logger.h"
|
||||
#include "LoggerListeners.h"
|
||||
#include "zlib/zlib.h"
|
||||
|
||||
|
||||
@ -21,7 +22,13 @@ static const Byte g_Zeroes[4096] = {0};
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
new cMCLogger(Printf("Defrag_%08x.log", time(NULL)));
|
||||
cLogger::cListener * consoleLogListener = MakeConsoleListener();
|
||||
cLogger::cListener * fileLogListener = new cFileListener();
|
||||
cLogger::GetInstance().AttachListener(consoleLogListener);
|
||||
cLogger::GetInstance().AttachListener(fileLogListener);
|
||||
|
||||
cLogger::InitiateMultithreading();
|
||||
|
||||
cMCADefrag Defrag;
|
||||
if (!Defrag.Init(argc, argv))
|
||||
{
|
||||
@ -30,6 +37,11 @@ int main(int argc, char ** argv)
|
||||
|
||||
Defrag.Run();
|
||||
|
||||
cLogger::GetInstance().DetachListener(consoleLogListener);
|
||||
delete consoleLogListener;
|
||||
cLogger::GetInstance().DetachListener(fileLogListener);
|
||||
delete fileLogListener;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -34,20 +34,18 @@ set_exe_flags()
|
||||
set(SHARED_SRC
|
||||
../../src/ByteBuffer.cpp
|
||||
../../src/StringUtils.cpp
|
||||
../../src/Log.cpp
|
||||
../../src/MCLogger.cpp
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.cpp
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.cpp
|
||||
../../src/PolarSSL++/CryptoKey.cpp
|
||||
../../src/PolarSSL++/CtrDrbgContext.cpp
|
||||
../../src/PolarSSL++/EntropyContext.cpp
|
||||
../../src/PolarSSL++/RsaPrivateKey.cpp
|
||||
../../src/LoggerListeners.cpp
|
||||
../../src/Logger.cpp
|
||||
)
|
||||
set(SHARED_HDR
|
||||
../../src/ByteBuffer.h
|
||||
../../src/StringUtils.h
|
||||
../../src/Log.h
|
||||
../../src/MCLogger.h
|
||||
../../src/PolarSSL++/AesCfb128Decryptor.h
|
||||
../../src/PolarSSL++/AesCfb128Encryptor.h
|
||||
../../src/PolarSSL++/CryptoKey.h
|
||||
|
@ -1819,8 +1819,7 @@ bool cConnection::HandleServerKick(void)
|
||||
Reason.append(Split[4]);
|
||||
Reason.push_back(0);
|
||||
Reason.append(Split[5]);
|
||||
AString ReasonBE16;
|
||||
UTF8ToRawBEUTF16(Reason.data(), Reason.size(), ReasonBE16);
|
||||
AString ReasonBE16 = UTF8ToRawBEUTF16(Reason.data(), Reason.size());
|
||||
AString PacketStart("\xff");
|
||||
PacketStart.push_back((ReasonBE16.size() / 2) / 256);
|
||||
PacketStart.push_back((ReasonBE16.size() / 2) % 256);
|
||||
|
2
Tools/QtBiomeVisualiser/.gitignore
vendored
Normal file
2
Tools/QtBiomeVisualiser/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.pro.user
|
||||
*.pro.user.*
|
414
Tools/QtBiomeVisualiser/BiomeView.cpp
Normal file
414
Tools/QtBiomeVisualiser/BiomeView.cpp
Normal file
@ -0,0 +1,414 @@
|
||||
#include "Globals.h"
|
||||
#include "BiomeView.h"
|
||||
#include "QtChunk.h"
|
||||
#include <QPainter>
|
||||
#include <QResizeEvent>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const int DELTA_STEP = 120; // The normal per-notch wheel delta
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BiomeView::BiomeView(QWidget * parent) :
|
||||
super(parent),
|
||||
m_X(0),
|
||||
m_Z(0),
|
||||
m_Zoom(1),
|
||||
m_IsMouseDragging(false),
|
||||
m_MouseWheelDelta(0)
|
||||
{
|
||||
// Create the image used for undefined chunks:
|
||||
int offset = 0;
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
uchar color = (((x & 8) ^ (y & 8)) == 0) ? 0x44 : 0x88;
|
||||
m_EmptyChunkImage[offset++] = color;
|
||||
m_EmptyChunkImage[offset++] = color;
|
||||
m_EmptyChunkImage[offset++] = color;
|
||||
m_EmptyChunkImage[offset++] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the startup image:
|
||||
redraw();
|
||||
|
||||
// Add a chunk-update callback mechanism:
|
||||
connect(&m_Cache, SIGNAL(chunkAvailable(int, int)), this, SLOT(chunkAvailable(int, int)));
|
||||
|
||||
// Allow mouse and keyboard interaction:
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QSize BiomeView::minimumSizeHint() const
|
||||
{
|
||||
return QSize(300, 300);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QSize BiomeView::sizeHint() const
|
||||
{
|
||||
return QSize(800, 600);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource)
|
||||
{
|
||||
// Replace the source in the cache:
|
||||
m_Cache.setChunkSource(a_ChunkSource);
|
||||
|
||||
// Redraw with the new source:
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::setPosition(int a_BlockX, int a_BlockZ)
|
||||
{
|
||||
m_X = a_BlockX;
|
||||
m_Z = a_BlockZ;
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::setZoomLevel(double a_ZoomLevel)
|
||||
{
|
||||
m_Zoom = a_ZoomLevel;
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::redraw()
|
||||
{
|
||||
if (!hasData())
|
||||
{
|
||||
// No data means no image is displayed, no need to compose:
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
int chunksize = 16 * m_Zoom;
|
||||
|
||||
// first find the center block position
|
||||
int centerchunkx = floor(m_X / 16);
|
||||
int centerchunkz = floor(m_Z / 16);
|
||||
// and the center of the screen
|
||||
int centerx = m_Image.width() / 2;
|
||||
int centery = m_Image.height() / 2;
|
||||
// and align for panning
|
||||
centerx -= (m_X - centerchunkx * 16) * m_Zoom;
|
||||
centery -= (m_Z - centerchunkz * 16) * m_Zoom;
|
||||
// now calculate the topleft block on the screen
|
||||
int startx = centerchunkx - centerx / chunksize - 1;
|
||||
int startz = centerchunkz - centery / chunksize - 1;
|
||||
// and the dimensions of the screen in blocks
|
||||
int blockswide = m_Image.width() / chunksize + 3;
|
||||
int blockstall = m_Image.height() / chunksize + 3;
|
||||
|
||||
for (int z = startz; z < startz + blockstall; z++)
|
||||
{
|
||||
for (int x = startx; x < startx + blockswide; x++)
|
||||
{
|
||||
drawChunk(x, z);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::chunkAvailable(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
drawChunk(a_ChunkX, a_ChunkZ);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::reload()
|
||||
{
|
||||
if (!hasData())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_Cache.reload();
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
if (!hasData())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//fetch the chunk:
|
||||
ChunkPtr chunk = m_Cache.fetch(a_ChunkX, a_ChunkZ);
|
||||
|
||||
// Figure out where on the screen this chunk should be drawn:
|
||||
// first find the center chunk
|
||||
int centerchunkx = floor(m_X / 16);
|
||||
int centerchunkz = floor(m_Z / 16);
|
||||
// and the center chunk screen coordinates
|
||||
int centerx = m_Image.width() / 2;
|
||||
int centery = m_Image.height() / 2;
|
||||
// which need to be shifted to account for panning inside that chunk
|
||||
centerx -= (m_X - centerchunkx * 16) * m_Zoom;
|
||||
centery -= (m_Z - centerchunkz * 16) * m_Zoom;
|
||||
// centerx,y now points to the top left corner of the center chunk
|
||||
// so now calculate our x,y in relation
|
||||
double chunksize = 16 * m_Zoom;
|
||||
centerx += (a_ChunkX - centerchunkx) * chunksize;
|
||||
centery += (a_ChunkZ - centerchunkz) * chunksize;
|
||||
|
||||
int srcoffset = 0;
|
||||
uchar * bits = m_Image.bits();
|
||||
int imgstride = m_Image.bytesPerLine();
|
||||
|
||||
int skipx = 0,skipy = 0;
|
||||
int blockwidth = chunksize, blockheight = chunksize;
|
||||
// now if we're off the screen we need to crop
|
||||
if (centerx < 0)
|
||||
{
|
||||
skipx = -centerx;
|
||||
centerx = 0;
|
||||
}
|
||||
if (centery < 0)
|
||||
{
|
||||
skipy = -centery;
|
||||
centery = 0;
|
||||
}
|
||||
// or the other side, we need to trim
|
||||
if (centerx + blockwidth > m_Image.width())
|
||||
{
|
||||
blockwidth = m_Image.width() - centerx;
|
||||
}
|
||||
if (centery + blockheight > m_Image.height())
|
||||
{
|
||||
blockheight = m_Image.height() - centery;
|
||||
}
|
||||
if ((blockwidth <= 0) || (skipx >= blockwidth))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int imgoffset = centerx * 4 + centery * imgstride;
|
||||
|
||||
// If the chunk is valid, use its data; otherwise use the empty placeholder:
|
||||
const uchar * src = m_EmptyChunkImage;
|
||||
if (chunk.get() != nullptr)
|
||||
{
|
||||
src = chunk->getImage();
|
||||
}
|
||||
|
||||
// Blit or scale-blit the image:
|
||||
for (int z = skipy; z < blockheight; z++, imgoffset += imgstride)
|
||||
{
|
||||
srcoffset = floor((double)z / m_Zoom) * 16 * 4;
|
||||
if (m_Zoom == 1.0)
|
||||
{
|
||||
memcpy(bits + imgoffset, src + srcoffset + skipx * 4, (blockwidth - skipx) * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xofs = 0;
|
||||
for (int x = skipx; x < blockwidth; x++, xofs +=4)
|
||||
{
|
||||
memcpy(bits + imgoffset + xofs, src + srcoffset + (int)floor((double)x / m_Zoom) * 4, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::resizeEvent(QResizeEvent * a_Event)
|
||||
{
|
||||
m_Image = QImage(a_Event->size(), QImage::Format_RGB32);
|
||||
redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::paintEvent(QPaintEvent * a_Event)
|
||||
{
|
||||
QPainter p(this);
|
||||
if (hasData())
|
||||
{
|
||||
p.drawImage(QPoint(0, 0), m_Image);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.drawText(a_Event->rect(), Qt::AlignCenter, "No chunk source selected");
|
||||
}
|
||||
p.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::mousePressEvent(QMouseEvent * a_Event)
|
||||
{
|
||||
m_LastX = a_Event->x();
|
||||
m_LastY = a_Event->y();
|
||||
m_IsMouseDragging = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::mouseMoveEvent(QMouseEvent * a_Event)
|
||||
{
|
||||
// If there's no data displayed, bail out:
|
||||
if (!hasData())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_IsMouseDragging)
|
||||
{
|
||||
// The user is dragging the mouse, move the view around:
|
||||
m_X += (m_LastX - a_Event->x()) / m_Zoom;
|
||||
m_Z += (m_LastY - a_Event->y()) / m_Zoom;
|
||||
m_LastX = a_Event->x();
|
||||
m_LastY = a_Event->y();
|
||||
redraw();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the status bar info text:
|
||||
int blockX = floor((a_Event->x() - width() / 2) / m_Zoom + m_X);
|
||||
int blockZ = floor((a_Event->y() - height() / 2) / m_Zoom + m_Z);
|
||||
int chunkX, chunkZ;
|
||||
int relX = blockX, relY, relZ = blockZ;
|
||||
cChunkDef::AbsoluteToRelative(relX, relY, relZ, chunkX, chunkZ);
|
||||
auto chunk = m_Cache.fetch(chunkX, chunkZ);
|
||||
int biome = (chunk.get() != nullptr) ? chunk->getBiome(relX, relZ) : biInvalidBiome;
|
||||
emit hoverChanged(blockX, blockZ, biome);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
m_IsMouseDragging = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::wheelEvent(QWheelEvent * a_Event)
|
||||
{
|
||||
m_MouseWheelDelta += a_Event->delta();
|
||||
while (m_MouseWheelDelta >= DELTA_STEP)
|
||||
{
|
||||
emit wheelUp();
|
||||
m_MouseWheelDelta -= DELTA_STEP;
|
||||
}
|
||||
while (m_MouseWheelDelta <= -DELTA_STEP)
|
||||
{
|
||||
emit wheelDown();
|
||||
m_MouseWheelDelta += DELTA_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BiomeView::keyPressEvent(QKeyEvent * a_Event)
|
||||
{
|
||||
switch (a_Event->key())
|
||||
{
|
||||
case Qt::Key_Up:
|
||||
case Qt::Key_W:
|
||||
{
|
||||
m_Z -= 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Down:
|
||||
case Qt::Key_S:
|
||||
{
|
||||
m_Z += 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Left:
|
||||
case Qt::Key_A:
|
||||
{
|
||||
m_X -= 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Right:
|
||||
case Qt::Key_D:
|
||||
{
|
||||
m_X += 10.0 / m_Zoom;
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_PageUp:
|
||||
case Qt::Key_Q:
|
||||
{
|
||||
emit increaseZoom();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_PageDown:
|
||||
case Qt::Key_E:
|
||||
{
|
||||
emit decreaseZoom();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
114
Tools/QtBiomeVisualiser/BiomeView.h
Normal file
114
Tools/QtBiomeVisualiser/BiomeView.h
Normal file
@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <memory>
|
||||
#include "ChunkCache.h"
|
||||
#include "ChunkSource.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BiomeView :
|
||||
public QWidget
|
||||
{
|
||||
typedef QWidget super;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BiomeView(QWidget * parent = NULL);
|
||||
|
||||
QSize minimumSizeHint() const;
|
||||
QSize sizeHint() const;
|
||||
|
||||
/** Replaces the chunk source used by the biome view to get the chunk biome data.
|
||||
The entire view is then invalidated and regenerated. */
|
||||
void setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource);
|
||||
|
||||
/** Sets the position of the central pixel of the map to the specified point and redraws the view. */
|
||||
void setPosition(int a_BlockX, int a_BlockZ);
|
||||
|
||||
/** Sets the zoom level to the specified value and redraws the view. */
|
||||
void setZoomLevel(double a_ZoomLevel);
|
||||
|
||||
signals:
|
||||
/** Signalled when the user uses the wheel to scroll upwards. */
|
||||
void wheelUp();
|
||||
|
||||
/** Signalled when the user uses the wheel to scroll downwards. */
|
||||
void wheelDown();
|
||||
|
||||
/** Signalled when the user presses a key to increase zoom. */
|
||||
void increaseZoom();
|
||||
|
||||
/** Signalled when the user presses a key to decrease zoom. */
|
||||
void decreaseZoom();
|
||||
|
||||
/** Emitted when the user moves the mouse, to reflect the current block under the cursor. */
|
||||
void hoverChanged(int a_BlockX, int a_BlockZ, int a_Biome);
|
||||
|
||||
public slots:
|
||||
/** Redraw the entire widget area. */
|
||||
void redraw();
|
||||
|
||||
/** A specified chunk has become available, redraw it. */
|
||||
void chunkAvailable(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Reloads the current chunk source and redraws the entire workspace. */
|
||||
void reload();
|
||||
|
||||
protected:
|
||||
double m_X, m_Z;
|
||||
double m_Zoom;
|
||||
|
||||
/** Cache for the loaded chunk data. */
|
||||
ChunkCache m_Cache;
|
||||
|
||||
/** The entire view's contents in an offscreen image. */
|
||||
QImage m_Image;
|
||||
|
||||
/** Coords of the mouse for the previous position, used while dragging. */
|
||||
int m_LastX, m_LastY;
|
||||
|
||||
/** Set to true when the user has a mouse button depressed, and is dragging the view. */
|
||||
bool m_IsMouseDragging;
|
||||
|
||||
/** Accumulator for the mouse wheel's delta. When the accumulator hits a threshold, the view zooms. */
|
||||
int m_MouseWheelDelta;
|
||||
|
||||
/** Data used for rendering a chunk that hasn't been loaded yet */
|
||||
uchar m_EmptyChunkImage[16 * 16 * 4];
|
||||
|
||||
|
||||
/** Draws the specified chunk into m_Image */
|
||||
void drawChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Returns true iff the biome view has been initialized to contain proper biome data. */
|
||||
bool hasData(void) const { return m_Cache.hasData(); }
|
||||
|
||||
/** Called when the widget is resized */
|
||||
virtual void resizeEvent(QResizeEvent *) override;
|
||||
|
||||
/** Paints the entire widget */
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
|
||||
/** Called when the user presses any mouse button. */
|
||||
virtual void mousePressEvent(QMouseEvent * a_Event);
|
||||
|
||||
/** Called when the user moves the mouse. */
|
||||
virtual void mouseMoveEvent(QMouseEvent * a_Event);
|
||||
|
||||
/** Called when the user releases a previously held mouse button. */
|
||||
virtual void mouseReleaseEvent(QMouseEvent * a_Event) override;
|
||||
|
||||
/** Called when the user rotates the mouse wheel. */
|
||||
virtual void wheelEvent(QWheelEvent * a_Event) override;
|
||||
|
||||
/** Called when the user presses a key. */
|
||||
virtual void keyPressEvent(QKeyEvent * a_Event) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
126
Tools/QtBiomeVisualiser/ChunkCache.cpp
Normal file
126
Tools/QtBiomeVisualiser/ChunkCache.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "Globals.h"
|
||||
#include "ChunkCache.h"
|
||||
#include <QMutexLocker>
|
||||
#include <QThreadPool>
|
||||
#include "ChunkSource.h"
|
||||
#include "ChunkLoader.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ChunkCache::ChunkCache(QObject * parent) :
|
||||
super(parent)
|
||||
{
|
||||
m_Cache.setMaxCost(1024 * 1024 * 1024); // 1 GiB of memory for the cache
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ChunkPtr ChunkCache::fetch(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
// Retrieve from the cache:
|
||||
quint32 hash = getChunkHash(a_ChunkX, a_ChunkZ);
|
||||
ChunkPtr * res;
|
||||
{
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
res = m_Cache[hash];
|
||||
// If succesful and chunk loaded, return the retrieved value:
|
||||
if ((res != nullptr) && (*res)->isValid())
|
||||
{
|
||||
return *res;
|
||||
}
|
||||
}
|
||||
|
||||
// If the chunk is in cache but not valid, it means it has been already queued for rendering, do nothing now:
|
||||
if (res != nullptr)
|
||||
{
|
||||
return ChunkPtr(nullptr);
|
||||
}
|
||||
|
||||
// There's no such item in the cache, create it now:
|
||||
res = new ChunkPtr(new Chunk);
|
||||
if (res == nullptr)
|
||||
{
|
||||
return ChunkPtr(nullptr);
|
||||
}
|
||||
{
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Cache.insert(hash, res, sizeof(Chunk));
|
||||
}
|
||||
|
||||
// Queue the chunk for rendering:
|
||||
queueChunkRender(a_ChunkX, a_ChunkZ, *res);
|
||||
|
||||
// Return failure, the chunk is not yet rendered:
|
||||
return ChunkPtr(nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource)
|
||||
{
|
||||
// Replace the chunk source:
|
||||
m_ChunkSource = a_ChunkSource;
|
||||
|
||||
// Clear the cache:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Cache.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::reload()
|
||||
{
|
||||
assert(m_ChunkSource.get() != nullptr);
|
||||
|
||||
// Reload the chunk source:
|
||||
m_ChunkSource->reload();
|
||||
|
||||
// Clear the cache:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Cache.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::gotChunk(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
emit chunkAvailable(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
quint32 ChunkCache::getChunkHash(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
// Simply join the two coords into a single int
|
||||
// The coords will never be larger than 16-bits, so we can do this safely
|
||||
return (((static_cast<quint32>(a_ChunkX) & 0xffff) << 16) | (static_cast<quint32>(a_ChunkZ) & 0xffff));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkCache::queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk)
|
||||
{
|
||||
// Create a new loader task:
|
||||
ChunkLoader * loader = new ChunkLoader(a_ChunkX, a_ChunkZ, a_Chunk, m_ChunkSource);
|
||||
connect(loader, SIGNAL(loaded(int, int)), this, SLOT(gotChunk(int, int)));
|
||||
|
||||
QThreadPool::globalInstance()->start(loader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
72
Tools/QtBiomeVisualiser/ChunkCache.h
Normal file
72
Tools/QtBiomeVisualiser/ChunkCache.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QCache>
|
||||
#include <QMutex>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Chunk;
|
||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||
|
||||
class ChunkSource;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Caches chunk data for reuse */
|
||||
class ChunkCache :
|
||||
public QObject
|
||||
{
|
||||
typedef QObject super;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ChunkCache(QObject * parent = NULL);
|
||||
|
||||
/** Retrieves the specified chunk from the cache.
|
||||
Only returns valid chunks; if the chunk is invalid, queues it for rendering and returns an empty ptr. */
|
||||
ChunkPtr fetch(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Replaces the chunk source used by the biome view to get the chunk biome data.
|
||||
The cache is then invalidated. */
|
||||
void setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource);
|
||||
|
||||
/** Returns true iff the chunk source has been initialized. */
|
||||
bool hasData() const { return (m_ChunkSource.get() != nullptr); }
|
||||
|
||||
/** Reloads the current chunk source. */
|
||||
void reload();
|
||||
|
||||
signals:
|
||||
void chunkAvailable(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
protected slots:
|
||||
void gotChunk(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
protected:
|
||||
/** The cache of the chunks */
|
||||
QCache<quint32, ChunkPtr> m_Cache;
|
||||
|
||||
/** Locks te cache against multithreaded access */
|
||||
QMutex m_Mtx;
|
||||
|
||||
/** The source used to get the biome data. */
|
||||
std::shared_ptr<ChunkSource> m_ChunkSource;
|
||||
|
||||
|
||||
/** Returns the hash used by the chunk in the cache */
|
||||
quint32 getChunkHash(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Queues the specified chunk for rendering by m_ChunkSource. */
|
||||
void queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
Tools/QtBiomeVisualiser/ChunkLoader.cpp
Normal file
29
Tools/QtBiomeVisualiser/ChunkLoader.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "Globals.h"
|
||||
#include "ChunkLoader.h"
|
||||
#include "ChunkSource.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ChunkLoader::ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource) :
|
||||
m_ChunkX(a_ChunkX),
|
||||
m_ChunkZ(a_ChunkZ),
|
||||
m_Chunk(a_Chunk),
|
||||
m_ChunkSource(a_ChunkSource)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ChunkLoader::run()
|
||||
{
|
||||
m_ChunkSource->getChunkBiomes(m_ChunkX, m_ChunkZ, m_Chunk);
|
||||
emit loaded(m_ChunkX, m_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
45
Tools/QtBiomeVisualiser/ChunkLoader.h
Normal file
45
Tools/QtBiomeVisualiser/ChunkLoader.h
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QRunnable>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class Chunk;
|
||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||
|
||||
class ChunkSource;
|
||||
typedef std::shared_ptr<ChunkSource> ChunkSourcePtr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ChunkLoader :
|
||||
public QObject,
|
||||
public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource);
|
||||
virtual ~ChunkLoader() {}
|
||||
|
||||
signals:
|
||||
void loaded(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
protected:
|
||||
virtual void run() override;
|
||||
|
||||
private:
|
||||
int m_ChunkX, m_ChunkZ;
|
||||
ChunkPtr m_Chunk;
|
||||
ChunkSourcePtr m_ChunkSource;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
284
Tools/QtBiomeVisualiser/ChunkSource.cpp
Normal file
284
Tools/QtBiomeVisualiser/ChunkSource.cpp
Normal file
@ -0,0 +1,284 @@
|
||||
#include "Globals.h"
|
||||
#include "ChunkSource.h"
|
||||
#include <QThread>
|
||||
#include "src/Generating/BioGen.h"
|
||||
#include "src/StringCompression.h"
|
||||
#include "src/WorldStorage/FastNBT.h"
|
||||
#include "inifile/iniFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// BioGenSource:
|
||||
|
||||
BioGenSource::BioGenSource(cIniFilePtr a_IniFile) :
|
||||
m_IniFile(a_IniFile),
|
||||
m_Mtx(QMutex::Recursive)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk)
|
||||
{
|
||||
cChunkDef::BiomeMap biomes;
|
||||
{
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes);
|
||||
}
|
||||
a_DestChunk->setBiomes(biomes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void BioGenSource::reload()
|
||||
{
|
||||
int seed = m_IniFile->GetValueSetI("Seed", "Seed", 0);
|
||||
bool unused = false;
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AnvilSource::AnvilFile
|
||||
|
||||
class AnvilSource::AnvilFile
|
||||
{
|
||||
public:
|
||||
/** Coordinates of the region file. */
|
||||
int m_RegionX, m_RegionZ;
|
||||
|
||||
/** True iff the file contains proper data. */
|
||||
bool m_IsValid;
|
||||
|
||||
|
||||
|
||||
/** Creates a new instance with the specified region coords. Reads the file header. */
|
||||
AnvilFile(int a_RegionX, int a_RegionZ, const AString & a_WorldPath) :
|
||||
m_RegionX(a_RegionX),
|
||||
m_RegionZ(a_RegionZ),
|
||||
m_IsValid(false)
|
||||
{
|
||||
readFile(Printf("%s/r.%d.%d.mca", a_WorldPath.c_str(), a_RegionX, a_RegionZ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Returns the compressed data of the specified chunk.
|
||||
Returns an empty string when chunk not present. */
|
||||
AString getChunkData(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
if (!m_IsValid)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Translate to local coords:
|
||||
int RelChunkX = a_ChunkX - m_RegionX * 32;
|
||||
int RelChunkZ = a_ChunkZ - m_RegionZ * 32;
|
||||
ASSERT((RelChunkX >= 0) && (RelChunkX < 32));
|
||||
ASSERT((RelChunkZ >= 0) && (RelChunkZ < 32));
|
||||
|
||||
// Get the chunk data location:
|
||||
UInt32 chunkOffset = m_Header[RelChunkX + 32 * RelChunkZ] >> 8;
|
||||
UInt32 numChunkSectors = m_Header[RelChunkX + 32 * RelChunkZ] & 0xff;
|
||||
if ((chunkOffset < 2) || (numChunkSectors == 0))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get the real data size:
|
||||
const char * chunkData = m_FileData.data() + chunkOffset * 4096;
|
||||
UInt32 chunkSize = GetBEInt(chunkData);
|
||||
if ((chunkSize < 2) || (chunkSize / 4096 > numChunkSectors))
|
||||
{
|
||||
// Bad data, bail out
|
||||
return "";
|
||||
}
|
||||
|
||||
// Check the compression method:
|
||||
if (chunkData[4] != 2)
|
||||
{
|
||||
// Chunk is in an unknown compression
|
||||
return "";
|
||||
}
|
||||
chunkSize--;
|
||||
|
||||
// Read the chunk data:
|
||||
return m_FileData.substr(chunkOffset * 4096 + 5, chunkSize);
|
||||
}
|
||||
|
||||
protected:
|
||||
AString m_FileData;
|
||||
UInt32 m_Header[2048];
|
||||
|
||||
|
||||
/** Reads the whole specified file contents and parses the header. */
|
||||
void readFile(const AString & a_FileName)
|
||||
{
|
||||
// Read the entire file:
|
||||
m_FileData = cFile::ReadWholeFile(a_FileName);
|
||||
if (m_FileData.size() < sizeof(m_Header))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the header - change endianness:
|
||||
const char * hdr = m_FileData.data();
|
||||
for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++)
|
||||
{
|
||||
m_Header[i] = GetBEInt(hdr + 4 * i);
|
||||
}
|
||||
m_IsValid = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AnvilSource:
|
||||
|
||||
AnvilSource::AnvilSource(QString a_WorldRegionFolder) :
|
||||
m_WorldRegionFolder(a_WorldRegionFolder)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk)
|
||||
{
|
||||
// Load the compressed data:
|
||||
AString compressedChunkData = getCompressedChunkData(a_ChunkX, a_ChunkZ);
|
||||
if (compressedChunkData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Uncompress the chunk data:
|
||||
AString uncompressed;
|
||||
int res = InflateString(compressedChunkData.data(), compressedChunkData.size(), uncompressed);
|
||||
if (res != Z_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the NBT data:
|
||||
cParsedNBT nbt(uncompressed.data(), uncompressed.size());
|
||||
if (!nbt.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the biomes out of the NBT:
|
||||
int Level = nbt.FindChildByName(0, "Level");
|
||||
if (Level < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cChunkDef::BiomeMap biomeMap;
|
||||
int mcsBiomes = nbt.FindChildByName(Level, "MCSBiomes");
|
||||
if ((mcsBiomes >= 0) && (nbt.GetDataLength(mcsBiomes) == sizeof(biomeMap)))
|
||||
{
|
||||
// Convert the biomes from BigEndian to platform native numbers:
|
||||
const char * beBiomes = nbt.GetData(mcsBiomes);
|
||||
for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
|
||||
{
|
||||
biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i);
|
||||
}
|
||||
a_DestChunk->setBiomes(biomeMap);
|
||||
return;
|
||||
}
|
||||
|
||||
// MCS biomes not found, load Vanilla biomes instead:
|
||||
int biomes = nbt.FindChildByName(Level, "Biomes");
|
||||
if ((biomes < 0) || (nbt.GetDataLength(biomes) != ARRAYCOUNT(biomeMap)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Convert the biomes from Vanilla to EMCSBiome:
|
||||
const char * vanillaBiomes = nbt.GetData(biomes);
|
||||
for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
|
||||
{
|
||||
biomeMap[i] = EMCSBiome(vanillaBiomes[i]);
|
||||
}
|
||||
a_DestChunk->setBiomes(biomeMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AnvilSource::reload()
|
||||
{
|
||||
// Remove all files from the cache:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
m_Files.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void AnvilSource::chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ)
|
||||
{
|
||||
a_RegionX = a_ChunkX >> 5;
|
||||
a_RegionZ = a_ChunkZ >> 5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString AnvilSource::getCompressedChunkData(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
return getAnvilFile(a_ChunkX, a_ChunkZ)->getChunkData(a_ChunkX, a_ChunkZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AnvilSource::AnvilFilePtr AnvilSource::getAnvilFile(int a_ChunkX, int a_ChunkZ)
|
||||
{
|
||||
int RegionX, RegionZ;
|
||||
chunkToRegion(a_ChunkX, a_ChunkZ, RegionX, RegionZ);
|
||||
|
||||
// Search the cache for the file:
|
||||
QMutexLocker lock(&m_Mtx);
|
||||
for (auto itr = m_Files.cbegin(), end = m_Files.cend(); itr != end; ++itr)
|
||||
{
|
||||
if (((*itr)->m_RegionX == RegionX) && ((*itr)->m_RegionZ == RegionZ))
|
||||
{
|
||||
// Found the file in the cache, move it to front and return it:
|
||||
AnvilFilePtr file(*itr);
|
||||
m_Files.erase(itr);
|
||||
m_Files.push_front(file);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
// File not in cache, create it:
|
||||
AnvilFilePtr file(new AnvilFile(RegionX, RegionZ, m_WorldRegionFolder.toStdString()));
|
||||
m_Files.push_front(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
107
Tools/QtBiomeVisualiser/ChunkSource.h
Normal file
107
Tools/QtBiomeVisualiser/ChunkSource.h
Normal file
@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
#include "Globals.h"
|
||||
#include <QString>
|
||||
#include <QMutex>
|
||||
#include "QtChunk.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cBiomeGen;
|
||||
typedef std::shared_ptr<cBiomeGen> cBiomeGenPtr;
|
||||
class cIniFile;
|
||||
typedef std::shared_ptr<cIniFile> cIniFilePtr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Abstract interface for getting biome data for chunks. */
|
||||
class ChunkSource
|
||||
{
|
||||
public:
|
||||
virtual ~ChunkSource() {}
|
||||
|
||||
/** Fills the a_DestChunk with the biomes for the specified coords.
|
||||
It is expected to be thread-safe and re-entrant. Usually QThread::idealThreadCount() threads are used. */
|
||||
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) = 0;
|
||||
|
||||
/** Forces a fresh reload of the source. Useful mainly for the generator, whose underlying definition file may have been changed. */
|
||||
virtual void reload() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BioGenSource :
|
||||
public ChunkSource
|
||||
{
|
||||
public:
|
||||
/** Constructs a new BioGenSource based on the biome generator that is defined in the specified world.ini file. */
|
||||
BioGenSource(cIniFilePtr a_IniFile);
|
||||
|
||||
// ChunkSource overrides:
|
||||
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override;
|
||||
virtual void reload(void) override;
|
||||
|
||||
protected:
|
||||
/** The world.ini contents from which the generator is created and re-created on reload(). */
|
||||
cIniFilePtr m_IniFile;
|
||||
|
||||
/** The generator used for generating biomes. */
|
||||
std::unique_ptr<cBiomeGen> m_BiomeGen;
|
||||
|
||||
/** Guards m_BiomeGen against multithreaded access. */
|
||||
QMutex m_Mtx;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class AnvilSource :
|
||||
public ChunkSource
|
||||
{
|
||||
public:
|
||||
/** Constructs a new AnvilSource based on the world path. */
|
||||
AnvilSource(QString a_WorldRegionFolder);
|
||||
|
||||
// ChunkSource overrides:
|
||||
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override;
|
||||
virtual void reload() override;
|
||||
|
||||
protected:
|
||||
class AnvilFile;
|
||||
typedef std::shared_ptr<AnvilFile> AnvilFilePtr;
|
||||
|
||||
|
||||
/** Folder where the individual Anvil Region files are located. */
|
||||
QString m_WorldRegionFolder;
|
||||
|
||||
/** List of currently loaded files. Acts as a cache so that a file is not opened and closed over and over again.
|
||||
Protected against multithreaded access by m_Mtx. */
|
||||
std::list<AnvilFilePtr> m_Files;
|
||||
|
||||
/** Guards m_Files agains multithreaded access. */
|
||||
QMutex m_Mtx;
|
||||
|
||||
|
||||
/** Converts chunk coords to region coords. */
|
||||
void chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ);
|
||||
|
||||
/** Returns the compressed data of the specified chunk.
|
||||
Returns an empty string if the chunk is not available. */
|
||||
AString getCompressedChunkData(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
/** Returns the file object that contains the specified chunk.
|
||||
The file is taken from the cache if available there, otherwise it is created anew. */
|
||||
AnvilFilePtr getAnvilFile(int a_ChunkX, int a_ChunkZ);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
158
Tools/QtBiomeVisualiser/GeneratorSetup.cpp
Normal file
158
Tools/QtBiomeVisualiser/GeneratorSetup.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
#include "Globals.h"
|
||||
#include "GeneratorSetup.h"
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include "src/Generating/BioGen.h"
|
||||
#include "inifile/iniFile.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const QString s_GeneratorNames[] =
|
||||
{
|
||||
QString("Checkerboard"),
|
||||
QString("Constant"),
|
||||
QString("DistortedVoronoi"),
|
||||
QString("MultiStepMap"),
|
||||
QString("TwoLevel"),
|
||||
QString("Voronoi"),
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent) :
|
||||
super(a_Parent),
|
||||
m_IniFile(new cIniFile())
|
||||
{
|
||||
// The seed and generator name is in a separate form layout at the top, always present:
|
||||
m_eSeed = new QLineEdit();
|
||||
m_eSeed->setValidator(new QIntValidator());
|
||||
m_eSeed->setText("0");
|
||||
m_eSeed->setProperty("INI.SectionName", QVariant("Seed"));
|
||||
m_eSeed->setProperty("INI.ItemName", QVariant("Seed"));
|
||||
m_cbGenerator = new QComboBox();
|
||||
m_cbGenerator->setMinimumWidth(120);
|
||||
for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++)
|
||||
{
|
||||
m_cbGenerator->addItem(s_GeneratorNames[i]);
|
||||
}
|
||||
QFormLayout * baseLayout = new QFormLayout();
|
||||
baseLayout->addRow(new QLabel(tr("Seed")), m_eSeed);
|
||||
baseLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator);
|
||||
|
||||
// The rest of the controls are in a dynamically created form layout:
|
||||
m_FormLayout = new QFormLayout();
|
||||
|
||||
// The main layout joins these two vertically:
|
||||
m_MainLayout = new QVBoxLayout();
|
||||
m_MainLayout->addLayout(baseLayout);
|
||||
m_MainLayout->addLayout(m_FormLayout);
|
||||
m_MainLayout->addStretch();
|
||||
setLayout(m_MainLayout);
|
||||
|
||||
// Load the INI file, if specified, otherwise set defaults:
|
||||
if (a_IniFileName.empty() || !m_IniFile->ReadFile(a_IniFileName))
|
||||
{
|
||||
m_IniFile->SetValue("Generator", "Generator", "Composable");
|
||||
m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString());
|
||||
bool dummy;
|
||||
delete cBiomeGen::CreateBiomeGen(*m_IniFile, 0, dummy);
|
||||
}
|
||||
updateFromIni();
|
||||
|
||||
// Connect the change events only after the data has been loaded:
|
||||
connect(m_cbGenerator, SIGNAL(currentIndexChanged(QString)), this, SLOT(generatorChanged(QString)));
|
||||
connect(m_eSeed, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GeneratorSetup::generatorChanged(const QString & a_NewName)
|
||||
{
|
||||
// Clear the current contents of the form layout by assigning it to a stack temporary:
|
||||
{
|
||||
m_MainLayout->takeAt(1);
|
||||
QWidget().setLayout(m_FormLayout);
|
||||
}
|
||||
|
||||
// Re-create the layout:
|
||||
m_FormLayout = new QFormLayout();
|
||||
m_MainLayout->insertLayout(1, m_FormLayout);
|
||||
|
||||
// Recreate the INI file:
|
||||
m_IniFile->Clear();
|
||||
m_IniFile->SetValue("Generator", "Generator", "Composable");
|
||||
m_IniFile->SetValue("Generator", "BiomeGen", a_NewName.toStdString());
|
||||
|
||||
// Create a dummy biome gen from the INI file, this will create the defaults in the INI file:
|
||||
bool dummy;
|
||||
delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy);
|
||||
|
||||
// Read all values from the INI file and put them into the form layout:
|
||||
updateFromIni();
|
||||
|
||||
// Notify of the changes:
|
||||
emit generatorUpdated();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GeneratorSetup::editChanged(const QString & a_NewValue)
|
||||
{
|
||||
QString sectionName = sender()->property("INI.SectionName").toString();
|
||||
QString itemName = sender()->property("INI.ItemName").toString();
|
||||
m_IniFile->SetValue(sectionName.toStdString(), itemName.toStdString(), a_NewValue.toStdString());
|
||||
emit generatorUpdated();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void GeneratorSetup::updateFromIni()
|
||||
{
|
||||
m_eSeed->setText(QString::number(m_IniFile->GetValueI("Seed", "Seed", 0)));
|
||||
int keyID = m_IniFile->FindKey("Generator");
|
||||
if (keyID <= -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int numItems = m_IniFile->GetNumValues(keyID);
|
||||
AString generatorName = m_IniFile->GetValue("Generator", "BiomeGen");
|
||||
size_t generatorNameLen = generatorName.length();
|
||||
for (int i = 0; i < numItems; i++)
|
||||
{
|
||||
AString itemName = m_IniFile->GetValueName(keyID, i);
|
||||
if ((itemName == "Generator") || (itemName == "BiomeGen"))
|
||||
{
|
||||
// These special cases are not to be added
|
||||
continue;
|
||||
}
|
||||
AString itemValue = m_IniFile->GetValue(keyID, i);
|
||||
|
||||
QLineEdit * edit = new QLineEdit();
|
||||
edit->setText(QString::fromStdString(itemValue));
|
||||
edit->setProperty("INI.SectionName", QVariant("Generator"));
|
||||
edit->setProperty("INI.ItemName", QVariant(QString::fromStdString(itemName)));
|
||||
|
||||
// Remove the generator name prefix from the item name, for clarity purposes:
|
||||
if (NoCaseCompare(itemName.substr(0, generatorNameLen), generatorName) == 0)
|
||||
{
|
||||
itemName.erase(0, generatorNameLen);
|
||||
}
|
||||
|
||||
connect(edit, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString)));
|
||||
m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit);
|
||||
} // for i - INI values[]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
64
Tools/QtBiomeVisualiser/GeneratorSetup.h
Normal file
64
Tools/QtBiomeVisualiser/GeneratorSetup.h
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <QDialog>
|
||||
#include <QComboBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFormLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cIniFile;
|
||||
typedef std::shared_ptr<cIniFile> cIniFilePtr;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class GeneratorSetup :
|
||||
public QWidget
|
||||
{
|
||||
typedef QWidget super;
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/** Creates the widget and loads the contents of the INI file, if not empty. */
|
||||
explicit GeneratorSetup(const std::string & a_IniFileName, QWidget * parent = nullptr);
|
||||
|
||||
/** Returns the cIniFile instance that is being edited by this widget. */
|
||||
cIniFilePtr getIniFile() { return m_IniFile; }
|
||||
|
||||
signals:
|
||||
/** Emitted when the generator parameters have changed. */
|
||||
void generatorUpdated();
|
||||
|
||||
public slots:
|
||||
/** Called when the user selects a different generator from the top combobox.
|
||||
Re-creates m_IniFile and updates the form layout. */
|
||||
void generatorChanged(const QString & a_NewName);
|
||||
|
||||
protected slots:
|
||||
/** Called when any of the edit widgets are changed. */
|
||||
void editChanged(const QString & a_NewValue);
|
||||
|
||||
protected:
|
||||
QComboBox * m_cbGenerator;
|
||||
QLineEdit * m_eSeed;
|
||||
QVBoxLayout * m_MainLayout;
|
||||
QFormLayout * m_FormLayout;
|
||||
|
||||
cIniFilePtr m_IniFile;
|
||||
|
||||
int m_Seed;
|
||||
|
||||
|
||||
/** Updates the form layout with the values from m_IniFile. */
|
||||
void updateFromIni();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
395
Tools/QtBiomeVisualiser/Globals.h
Normal file
395
Tools/QtBiomeVisualiser/Globals.h
Normal file
@ -0,0 +1,395 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Compiler-dependent stuff:
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether
|
||||
#pragma warning(disable:4481)
|
||||
|
||||
// Disable some warnings that we don't care about:
|
||||
#pragma warning(disable:4100) // Unreferenced formal parameter
|
||||
|
||||
// Useful warnings from warning level 4:
|
||||
#pragma warning(3 : 4127) // Conditional expression is constant
|
||||
#pragma warning(3 : 4189) // Local variable is initialized but not referenced
|
||||
#pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch
|
||||
#pragma warning(3 : 4310) // Cast truncates constant value
|
||||
#pragma warning(3 : 4389) // Signed/unsigned mismatch
|
||||
#pragma warning(3 : 4505) // Unreferenced local function has been removed
|
||||
#pragma warning(3 : 4701) // Potentially unitialized local variable used
|
||||
#pragma warning(3 : 4702) // Unreachable code
|
||||
#pragma warning(3 : 4706) // Assignment within conditional expression
|
||||
|
||||
// Disabling this warning, because we know what we're doing when we're doing this:
|
||||
#pragma warning(disable: 4355) // 'this' used in initializer list
|
||||
|
||||
// Disabled because it's useless:
|
||||
#pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member
|
||||
|
||||
// 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places
|
||||
// #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data
|
||||
|
||||
#define OBSOLETE __declspec(deprecated)
|
||||
|
||||
// No alignment needed in MSVC
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
|
||||
#define FORMATSTRING(formatIndex, va_argsIndex)
|
||||
|
||||
// MSVC has its own custom version of zu format
|
||||
#define SIZE_T_FMT "%Iu"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "Iu"
|
||||
#define SIZE_T_FMT_HEX "%Ix"
|
||||
|
||||
#define NORETURN __declspec(noreturn)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// TODO: Can GCC explicitly mark classes as abstract (no instances can be created)?
|
||||
#define abstract
|
||||
|
||||
// override is part of c++11
|
||||
#if __cplusplus < 201103L
|
||||
#define override
|
||||
#endif
|
||||
|
||||
#define OBSOLETE __attribute__((deprecated))
|
||||
|
||||
#define ALIGN_8 __attribute__((aligned(8)))
|
||||
#define ALIGN_16 __attribute__((aligned(16)))
|
||||
|
||||
// Some portability macros :)
|
||||
#define stricmp strcasecmp
|
||||
|
||||
#define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex)))
|
||||
|
||||
#if defined(_WIN32)
|
||||
// We're compiling on MinGW, which uses an old MSVCRT library that has no support for size_t printfing.
|
||||
// We need direct size formats:
|
||||
#if defined(_WIN64)
|
||||
#define SIZE_T_FMT "%I64u"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "I64u"
|
||||
#define SIZE_T_FMT_HEX "%I64x"
|
||||
#else
|
||||
#define SIZE_T_FMT "%u"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "u"
|
||||
#define SIZE_T_FMT_HEX "%x"
|
||||
#endif
|
||||
#else
|
||||
// We're compiling on Linux, so we can use libc's size_t printf format:
|
||||
#define SIZE_T_FMT "%zu"
|
||||
#define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
|
||||
#define SIZE_T_FMT_HEX "%zx"
|
||||
#endif
|
||||
|
||||
#define NORETURN __attribute((__noreturn__))
|
||||
|
||||
#else
|
||||
|
||||
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
|
||||
|
||||
/*
|
||||
// Copy and uncomment this into another #elif section based on your compiler identification
|
||||
|
||||
// Explicitly mark classes as abstract (no instances can be created)
|
||||
#define abstract
|
||||
|
||||
// Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class)
|
||||
#define override
|
||||
|
||||
// Mark functions as obsolete, so that their usage results in a compile-time warning
|
||||
#define OBSOLETE
|
||||
|
||||
// Mark types / variables for alignment. Do the platforms need it?
|
||||
#define ALIGN_8
|
||||
#define ALIGN_16
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define NORETURNDEBUG NORETURN
|
||||
#else
|
||||
#define NORETURNDEBUG
|
||||
#endif
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
// Integral types with predefined sizes:
|
||||
typedef long long Int64;
|
||||
typedef int Int32;
|
||||
typedef short Int16;
|
||||
|
||||
typedef unsigned long long UInt64;
|
||||
typedef unsigned int UInt32;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
||||
|
||||
// If you get an error about specialization check the size of integral types
|
||||
template <typename T, size_t Size, bool x = sizeof(T) == Size>
|
||||
class SizeChecker;
|
||||
|
||||
template <typename T, size_t Size>
|
||||
class SizeChecker<T, Size, true>
|
||||
{
|
||||
T v;
|
||||
};
|
||||
|
||||
template class SizeChecker<Int64, 8>;
|
||||
template class SizeChecker<Int32, 4>;
|
||||
template class SizeChecker<Int16, 2>;
|
||||
|
||||
template class SizeChecker<UInt64, 8>;
|
||||
template class SizeChecker<UInt32, 4>;
|
||||
template class SizeChecker<UInt16, 2>;
|
||||
|
||||
// A macro to disallow the copy constructor and operator = functions
|
||||
// This should be used in the private: declarations for any class that shouldn't allow copying itself
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName &); \
|
||||
void operator =(const TypeName &)
|
||||
|
||||
// A macro that is used to mark unused local variables, to avoid pedantic warnings in gcc / clang / MSVC
|
||||
// Note that in MSVC it requires the full type of X to be known
|
||||
#define UNUSED_VAR(X) (void)(X)
|
||||
|
||||
// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc
|
||||
// Written so that the full type of param needn't be known
|
||||
#ifdef _MSC_VER
|
||||
#define UNUSED(X)
|
||||
#else
|
||||
#define UNUSED UNUSED_VAR
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// OS-dependent stuff:
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#define _WIN32_WINNT 0x501 // We want to target WinXP and higher
|
||||
|
||||
#include <Windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h> // IPv6 stuff
|
||||
|
||||
// Windows SDK defines min and max macros, messing up with our std::min and std::max usage
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
// Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant
|
||||
#ifdef GetFreeSpace
|
||||
#undef GetFreeSpace
|
||||
#endif // GetFreeSpace
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID_NDK)
|
||||
#define FILE_IO_PREFIX "/sdcard/mcserver/"
|
||||
#else
|
||||
#define FILE_IO_PREFIX ""
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// CRT stuff:
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// STL stuff:
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <queue>
|
||||
#include <limits>
|
||||
|
||||
|
||||
|
||||
#ifndef TEST_GLOBALS
|
||||
// Common headers (part 1, without macros):
|
||||
#include "src/StringUtils.h"
|
||||
#include "src/OSSupport/Sleep.h"
|
||||
#include "src/OSSupport/CriticalSection.h"
|
||||
#include "src/OSSupport/Semaphore.h"
|
||||
#include "src/OSSupport/Event.h"
|
||||
#include "src/OSSupport/Thread.h"
|
||||
#include "src/OSSupport/File.h"
|
||||
#include "src/Logger.h"
|
||||
#else
|
||||
// Logging functions
|
||||
void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2);
|
||||
|
||||
void inline LOGERROR(const char* a_Format, ...)
|
||||
{
|
||||
va_list argList;
|
||||
va_start(argList, a_Format);
|
||||
vprintf(a_Format, argList);
|
||||
va_end(argList);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common definitions:
|
||||
|
||||
/// Evaluates to the number of elements in an array (compile-time!)
|
||||
#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X)))
|
||||
|
||||
/// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)")
|
||||
#define KiB * 1024
|
||||
#define MiB * 1024 * 1024
|
||||
|
||||
/// Faster than (int)floorf((float)x / (float)div)
|
||||
#define FAST_FLOOR_DIV( x, div) (((x) - (((x) < 0) ? ((div) - 1) : 0)) / (div))
|
||||
|
||||
// Own version of assert() that writes failed assertions to the log for review
|
||||
#ifdef TEST_GLOBALS
|
||||
|
||||
class cAssertFailure
|
||||
{
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
#if (defined(_MSC_VER) && defined(_DEBUG))
|
||||
#define DBG_BREAK _CrtDbgBreak()
|
||||
#else
|
||||
#define DBG_BREAK
|
||||
#endif
|
||||
#define REPORT_ERROR(FMT, ...) \
|
||||
{ \
|
||||
AString msg = Printf(FMT, __VA_ARGS__); \
|
||||
puts(msg.c_str()); \
|
||||
fflush(stdout); \
|
||||
OutputDebugStringA(msg.c_str()); \
|
||||
DBG_BREAK; \
|
||||
}
|
||||
#else
|
||||
#define REPORT_ERROR(FMT, ...) \
|
||||
{ \
|
||||
AString msg = Printf(FMT, __VA_ARGS__); \
|
||||
puts(msg.c_str()); \
|
||||
fflush(stdout); \
|
||||
}
|
||||
#endif
|
||||
#define ASSERT(x) do { if (!(x)) { throw cAssertFailure();} } while (0)
|
||||
#define testassert(x) do { if (!(x)) { REPORT_ERROR("Test failure: %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } } while (0)
|
||||
#define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } REPORT_ERROR("Test failure: assert didn't fire for %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } while (0)
|
||||
|
||||
#else
|
||||
#ifdef _DEBUG
|
||||
#define ASSERT( x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), assert(0), 0))
|
||||
#else
|
||||
#define ASSERT(x) ((void)(x))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Pretty much the same as ASSERT() but stays in Release builds
|
||||
#define VERIFY( x) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0))
|
||||
|
||||
// Same as assert but in all Self test builds
|
||||
#ifdef SELF_TEST
|
||||
#define assert_test(x) ( !!(x) || (assert(!#x), exit(1), 0))
|
||||
#endif
|
||||
|
||||
// Allow both Older versions of MSVC and newer versions of everything use a shared_ptr:
|
||||
// Note that we cannot typedef, because C++ doesn't allow (partial) templates to be typedeffed.
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < 1600))
|
||||
// MSVC before 2010 doesn't have std::shared_ptr, but has std::tr1::shared_ptr, defined in <memory> included earlier
|
||||
#define SharedPtr std::tr1::shared_ptr
|
||||
#elif (defined(_MSC_VER) || (__cplusplus >= 201103L))
|
||||
// C++11 has std::shared_ptr in <memory>, included earlier
|
||||
#define SharedPtr std::shared_ptr
|
||||
#else
|
||||
// C++03 has std::tr1::shared_ptr in <tr1/memory>
|
||||
#include <tr1/memory>
|
||||
#define SharedPtr std::tr1::shared_ptr
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** A generic interface used mainly in ForEach() functions */
|
||||
template <typename Type> class cItemCallback
|
||||
{
|
||||
public:
|
||||
virtual ~cItemCallback() {}
|
||||
|
||||
/** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */
|
||||
virtual bool Item(Type * a_Type) = 0;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
/** Clamp X to the specified range. */
|
||||
template <typename T>
|
||||
T Clamp(T a_Value, T a_Min, T a_Max)
|
||||
{
|
||||
return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef TOLUA_TEMPLATE_BIND
|
||||
#define TOLUA_TEMPLATE_BIND(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Common headers (part 2, with macros):
|
||||
#include "src/ChunkDef.h"
|
||||
#include "src/BiomeDef.h"
|
||||
#include "src/BlockID.h"
|
||||
#include "src/BlockInfo.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
440
Tools/QtBiomeVisualiser/MainWindow.cpp
Normal file
440
Tools/QtBiomeVisualiser/MainWindow.cpp
Normal file
@ -0,0 +1,440 @@
|
||||
#include "Globals.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QAction>
|
||||
#include <QMenuBar>
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QSettings>
|
||||
#include <QDirIterator>
|
||||
#include <QStatusBar>
|
||||
#include "inifile/iniFile.h"
|
||||
#include "ChunkSource.h"
|
||||
#include "src/Generating/BioGen.h"
|
||||
#include "src/StringCompression.h"
|
||||
#include "src/WorldStorage/FastNBT.h"
|
||||
#include "GeneratorSetup.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const double MainWindow::m_ViewZooms[] =
|
||||
{
|
||||
0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 24,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget * parent) :
|
||||
QMainWindow(parent),
|
||||
m_GeneratorSetup(nullptr),
|
||||
m_LineSeparator(nullptr)
|
||||
{
|
||||
initMinecraftPath();
|
||||
|
||||
m_BiomeView = new BiomeView();
|
||||
connect(m_BiomeView, SIGNAL(increaseZoom()), this, SLOT(increaseZoom()));
|
||||
connect(m_BiomeView, SIGNAL(decreaseZoom()), this, SLOT(decreaseZoom()));
|
||||
connect(m_BiomeView, SIGNAL(wheelUp()), this, SLOT(increaseZoom()));
|
||||
connect(m_BiomeView, SIGNAL(wheelDown()), this, SLOT(decreaseZoom()));
|
||||
|
||||
m_StatusBar = new QStatusBar();
|
||||
this->setStatusBar(m_StatusBar);
|
||||
m_StatusBlockX = new QLabel(tr("X"));
|
||||
m_StatusBlockZ = new QLabel(tr("Z"));
|
||||
m_StatusBiome = new QLabel(tr("B"));
|
||||
m_StatusBar->addPermanentWidget(m_StatusBlockX);
|
||||
m_StatusBar->addPermanentWidget(m_StatusBlockZ);
|
||||
m_StatusBar->addPermanentWidget(m_StatusBiome);
|
||||
|
||||
m_MainLayout = new QHBoxLayout();
|
||||
m_MainLayout->addWidget(m_BiomeView, 1);
|
||||
m_MainLayout->setMenuBar(menuBar());
|
||||
m_MainLayout->setMargin(0);
|
||||
QWidget * central = new QWidget();
|
||||
central->setLayout(m_MainLayout);
|
||||
setCentralWidget(central);
|
||||
|
||||
createActions();
|
||||
createMenus();
|
||||
|
||||
connect(m_BiomeView, SIGNAL(hoverChanged(int, int, int)), this, SLOT(hoverChanged(int, int, int)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::newGenerator()
|
||||
{
|
||||
// (Re-)open the generator setup dialog with empty settings:
|
||||
openGeneratorSetup("");
|
||||
|
||||
// Set the chunk source:
|
||||
cIniFilePtr iniFile = m_GeneratorSetup->getIniFile();
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(iniFile)));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openGenerator()
|
||||
{
|
||||
// Let the user specify the world.ini file:
|
||||
QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)"));
|
||||
if (worldIni.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// (Re-)open the generator setup dialog:
|
||||
openGeneratorSetup(worldIni.toStdString());
|
||||
|
||||
// Set the chunk source:
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(m_GeneratorSetup->getIniFile())));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openWorld()
|
||||
{
|
||||
// Let the user specify the world:
|
||||
QString regionFolder = QFileDialog::getExistingDirectory(this, tr("Select the region folder"), QString());
|
||||
if (regionFolder.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the generator setup dialog, if open:
|
||||
closeGeneratorSetup();
|
||||
|
||||
// Set the chunk source:
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(regionFolder)));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openVanillaWorld()
|
||||
{
|
||||
// The world is stored in the sender action's data, retrieve it:
|
||||
QAction * action = qobject_cast<QAction *>(sender());
|
||||
if (action == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the generator setup dialog, if open:
|
||||
closeGeneratorSetup();
|
||||
|
||||
// Set the chunk source:
|
||||
m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(action->data().toString())));
|
||||
m_BiomeView->redraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::centerView()
|
||||
{
|
||||
m_BiomeView->setPosition(0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::setViewZoom()
|
||||
{
|
||||
// The zoom level is stored in the sender action's data, retrieve it:
|
||||
QAction * action = qobject_cast<QAction *>(sender());
|
||||
if (action == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
double newZoom = m_ViewZooms[action->data().toInt()];
|
||||
m_BiomeView->setZoomLevel(newZoom);
|
||||
action->setChecked(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::increaseZoom()
|
||||
{
|
||||
// If already at max zoom, bail out:
|
||||
if (m_CurrentZoomLevel >= ARRAYCOUNT(m_ViewZooms) - 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Increase the zoom level:
|
||||
m_CurrentZoomLevel += 1;
|
||||
m_actViewZoom[m_CurrentZoomLevel]->setChecked(true);
|
||||
m_BiomeView->setZoomLevel(m_ViewZooms[m_CurrentZoomLevel]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::decreaseZoom()
|
||||
{
|
||||
// If already at min zoom, bail out:
|
||||
if (m_CurrentZoomLevel == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Decrease the zoom level:
|
||||
m_CurrentZoomLevel -= 1;
|
||||
m_actViewZoom[m_CurrentZoomLevel]->setChecked(true);
|
||||
m_BiomeView->setZoomLevel(m_ViewZooms[m_CurrentZoomLevel]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::hoverChanged(int a_BlockX, int a_BlockZ, int a_Biome)
|
||||
{
|
||||
m_StatusBlockX->setText(tr("X: %1").arg(a_BlockX));
|
||||
m_StatusBlockZ->setText(tr("Z: %1").arg(a_BlockZ));
|
||||
m_StatusBiome->setText (tr("B: %1 (%2)").arg(BiomeToString(a_Biome).c_str()).arg(a_Biome));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::initMinecraftPath()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/Library/Application Support/minecraft");
|
||||
#elif defined Q_OS_WIN32
|
||||
QSettings ini(QSettings::IniFormat, QSettings::UserScope, ".minecraft", "minecraft1");
|
||||
m_MinecraftPath = QFileInfo(ini.fileName()).absolutePath();
|
||||
#else
|
||||
m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/.minecraft");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::createActions()
|
||||
{
|
||||
// Map menu:
|
||||
createWorldActions();
|
||||
|
||||
m_actNewGen = new QAction(tr("&New generator"), this);
|
||||
m_actNewGen->setShortcut(tr("Ctrl+N"));
|
||||
m_actNewGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
|
||||
connect(m_actNewGen, SIGNAL(triggered()), this, SLOT(newGenerator()));
|
||||
|
||||
m_actOpenGen = new QAction(tr("&Open generator..."), this);
|
||||
m_actOpenGen->setShortcut(tr("Ctrl+G"));
|
||||
m_actOpenGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
|
||||
connect(m_actOpenGen, SIGNAL(triggered()), this, SLOT(openGenerator()));
|
||||
|
||||
m_actOpenWorld = new QAction(tr("&Open world..."), this);
|
||||
m_actOpenWorld->setShortcut(tr("Ctrl+O"));
|
||||
m_actOpenWorld->setStatusTip(tr("Open an existing world and display its biomes"));
|
||||
connect(m_actOpenWorld, SIGNAL(triggered()), this, SLOT(openWorld()));
|
||||
|
||||
m_actReload = new QAction(tr("&Reload"), this);
|
||||
m_actReload->setShortcut(tr("F5"));
|
||||
m_actReload->setStatusTip(tr("Clear the view cache and force a reload of all the data"));
|
||||
connect(m_actReload, SIGNAL(triggered()), m_BiomeView, SLOT(reload()));
|
||||
|
||||
m_actExit = new QAction(tr("E&xit"), this);
|
||||
m_actExit->setShortcut(tr("Alt+X"));
|
||||
m_actExit->setStatusTip(tr("Exit %1").arg(QApplication::instance()->applicationName()));
|
||||
connect(m_actExit, SIGNAL(triggered()), this, SLOT(close()));
|
||||
|
||||
// View menu:
|
||||
m_actViewCenter = new QAction(tr("&Reset to center"), this);
|
||||
m_actViewCenter->setStatusTip(tr("Scrolls the view back to the map center"));
|
||||
connect(m_actViewCenter, SIGNAL(triggered()), this, SLOT(centerView()));
|
||||
|
||||
QActionGroup * zoomGroup = new QActionGroup(this);
|
||||
for (int i = 0; i < ARRAYCOUNT(m_ViewZooms); i++)
|
||||
{
|
||||
m_actViewZoom[i] = new QAction(tr("&Zoom %1%").arg(std::floor(m_ViewZooms[i] * 100)), this);
|
||||
m_actViewZoom[i]->setCheckable(true);
|
||||
if ((int)(m_ViewZooms[i] * 16) == 16)
|
||||
{
|
||||
m_actViewZoom[i]->setChecked(true);
|
||||
m_CurrentZoomLevel = i;
|
||||
}
|
||||
m_actViewZoom[i]->setData(QVariant(i));
|
||||
zoomGroup->addAction(m_actViewZoom[i]);
|
||||
connect(m_actViewZoom[i], SIGNAL(triggered()), this, SLOT(setViewZoom()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::createWorldActions()
|
||||
{
|
||||
QDir mc(m_MinecraftPath);
|
||||
if (!mc.cd("saves"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDirIterator it(mc);
|
||||
int key = 1;
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
if (!it.fileInfo().isDir())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString name = getWorldName(it.filePath().toStdString());
|
||||
if (name.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QAction * w = new QAction(this);
|
||||
w->setText(name);
|
||||
w->setData(it.filePath() + "/region");
|
||||
if (key < 10)
|
||||
{
|
||||
w->setShortcut("Ctrl+" + QString::number(key));
|
||||
key++;
|
||||
}
|
||||
connect(w, SIGNAL(triggered()), this, SLOT(openVanillaWorld()));
|
||||
m_WorldActions.append(w);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
// Map menu:
|
||||
QMenu * file = menuBar()->addMenu(tr("&Map"));
|
||||
file->addAction(m_actNewGen);
|
||||
file->addAction(m_actOpenGen);
|
||||
file->addSeparator();
|
||||
QMenu * worlds = file->addMenu(tr("Open &existing"));
|
||||
worlds->addActions(m_WorldActions);
|
||||
if (m_WorldActions.empty())
|
||||
{
|
||||
worlds->setEnabled(false);
|
||||
}
|
||||
file->addAction(m_actOpenWorld);
|
||||
file->addSeparator();
|
||||
file->addAction(m_actReload);
|
||||
file->addSeparator();
|
||||
file->addAction(m_actExit);
|
||||
|
||||
// View menu:
|
||||
QMenu * view = menuBar()->addMenu(tr("&View"));
|
||||
view->addAction(m_actViewCenter);
|
||||
view->addSeparator();
|
||||
for (size_t i = 0; i < ARRAYCOUNT(m_actViewZoom); i++)
|
||||
{
|
||||
view->addAction(m_actViewZoom[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QString MainWindow::getWorldName(const AString & a_Path)
|
||||
{
|
||||
AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat");
|
||||
if (levelData.empty())
|
||||
{
|
||||
// No such file / no data
|
||||
return QString();
|
||||
}
|
||||
|
||||
AString uncompressed;
|
||||
if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK)
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
cParsedNBT nbt(uncompressed.data(), uncompressed.size());
|
||||
if (!nbt.IsValid())
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
AString name = nbt.GetName(1);
|
||||
int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName");
|
||||
if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String))
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
return QString::fromStdString(nbt.GetString(levelNameTag));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::openGeneratorSetup(const AString & a_IniFileName)
|
||||
{
|
||||
// Close any previous editor:
|
||||
closeGeneratorSetup();
|
||||
|
||||
// Open up a new editor:
|
||||
m_GeneratorSetup = new GeneratorSetup(a_IniFileName);
|
||||
m_LineSeparator = new QWidget();
|
||||
m_LineSeparator->setFixedWidth(2);
|
||||
m_LineSeparator->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
m_LineSeparator->setStyleSheet(QString("background-color: #c0c0c0;"));
|
||||
m_MainLayout->addWidget(m_LineSeparator);
|
||||
m_MainLayout->addWidget(m_GeneratorSetup);
|
||||
|
||||
// Connect the signals from the setup pane:
|
||||
connect(m_GeneratorSetup, SIGNAL(generatorUpdated()), m_BiomeView, SLOT(reload()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::closeGeneratorSetup()
|
||||
{
|
||||
delete m_MainLayout->takeAt(2);
|
||||
delete m_MainLayout->takeAt(1);
|
||||
delete m_GeneratorSetup;
|
||||
delete m_LineSeparator;
|
||||
m_GeneratorSetup = nullptr;
|
||||
m_LineSeparator = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user