1
0

Merge remote-tracking branch 'origin/master' into issue850

Conflicts:
	src/Blocks/BlockLeaves.h
	src/Generating/Trees.cpp
This commit is contained in:
archshift 2014-07-29 13:04:00 -07:00
commit a9b597087b
652 changed files with 48003 additions and 11575 deletions

4
.gitignore vendored
View File

@ -15,6 +15,7 @@ cloc.xsl
*.suo
/EveryNight.cmd
/UploadLuaAPI.cmd
AllFiles.lst
# IDE Stuff
## Sublime Text
@ -26,6 +27,7 @@ cloc.xsl
## Eclipse
.cproject
.project
*.cbp
# world inside source
ChunkWorx.ini
@ -48,6 +50,7 @@ world_nether
CMakeFiles/
cmake_install.cmake
CMakeCache.txt
CTestTestfile.cmake
Makefile
*.a
@ -63,6 +66,7 @@ lib/tolua++/tolua
src/Bindings/Bindings.*
src/Bindings/BindingDependecies.txt
MCServer.dir/
src/AllFiles.lst
#win32 cmake stuff
*.vcxproj

2
.gitmodules vendored
View File

@ -9,4 +9,4 @@
url = https://github.com/bearbin/transapi.git
[submodule "lib/polarssl"]
path = lib/polarssl
url = https://github.com/polarssl/polarssl
url = https://github.com/mc-server/polarssl

View File

@ -2,8 +2,15 @@ language: cpp
compiler:
- gcc
- clang
before_install:
- if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi
# Build MCServer
script: cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | $MCSERVER_PATH)
script: ./CIbuild.sh
after_success:
- ./uploadCoverage.sh
env:
- TRAVIS_MCSERVER_BUILD_TYPE=RELEASE MCSERVER_PATH=./MCServer
@ -11,6 +18,11 @@ env:
- TRAVIS_MCSERVER_BUILD_TYPE=RELEASE TRAVIS_MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer
- TRAVIS_MCSERVER_BUILD_TYPE=DEBUG TRAVIS_MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer_debug
matrix:
include:
- compiler: gcc
env: TRAVIS_MCSERVER_BUILD_TYPE=COVERAGE MCSERVER_PATH=./MCServer
# Notification Settings
notifications:
email:

11
CIbuild.sh Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -e
cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1;
make -j 2;
make -j 2 test;
cd MCServer/;
if [ "$TRAVIS_MCSERVER_BUILD_TYPE" != "COVERAGE" ]
then echo stop | $MCSERVER_PATH;
fi

View File

@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 2.6)
cmake_minimum_required (VERSION 2.8.2)
# 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)
@ -14,6 +14,10 @@ if(DEFINED ENV{TRAVIS_MCSERVER_FORCE32})
set(FORCE32 $ENV{TRAVIS_MCSERVER_FORCE32})
endif()
if(DEFINED ENV{TRAVIS_BUILD_WITH_COVERAGE})
set(BUILD_WITH_COVERAGE $ENV{TRAVIS_BUILD_WITH_COVERAGE})
endif()
# This has to be done before any flags have been set up.
if(${BUILD_TOOLS})
add_subdirectory(Tools/MCADefrag/)
@ -58,7 +62,10 @@ add_subdirectory(lib/tolua++/)
add_subdirectory(lib/sqlite/)
add_subdirectory(lib/expat/)
add_subdirectory(lib/luaexpat/)
add_subdirectory(lib/md5/)
if (WIN32)
add_subdirectory(lib/luaproxy/)
endif()
# We use EXCLUDE_FROM_ALL so that only the explicit dependencies are used
@ -69,3 +76,8 @@ set_exe_flags()
add_subdirectory (src)
if(${SELF_TEST})
enable_testing()
add_subdirectory (tests)
endif()

View File

@ -45,7 +45,30 @@ It is possible to use an external profiler to learn more about how the code perf
There's a script file, `MCServer/profile_run.cmd` that encapsulates most of the profiling work, have a look at the comments at the top of that script for details on how to get it to work. You'll need to change to a profiled configuration (both debug and release can be profiled).
## Linux, MacOS, FreeBSD etc. ##
## OSX ##
Install git from its [website](http://git-scm.com) or homebrew: `brew install git`.
Install Xcode (commandline tools are recommended) from the App Store or https://developer.apple.com/downloads.
Install CMake from its [website](http://cmake.org) or homebrew: `brew install cmake`.
### Getting the sources ###
```
mkdir MCServer
cd MCServer
git clone https://github.com/mc-server/MCServer.git .
git submodule init
git submodule update
```
### Building ###
Follow the instructions at [CMake on Unix-based platforms](#cmake-on-unix-based-platforms), using Xcode as cmake's generator. If no generator is specified, CMake will use the Makefile generator, in which case you must build with the `make` command.
After doing so, run the command `xcodebuild lib/polarssl/POLARSSL.xcodeproj` in the build directory, in order to build polarssl, a library that is required by MCServer. Lastly, run the command `xcodebuild` to build MCServer. Optionally, you may open the project files for polarssl and then MCServer in Xcode and build there.
## Linux, FreeBSD etc. ##
Install git, cmake and gcc or clang, using your platform's package manager:
```
@ -61,6 +84,14 @@ git submodule init
git submodule update
```
### Building ###
Follow the instructions at [CMake on Unix-based platforms](#cmake-on-unix-based-platforms).
After doing so, run the command `make` in the build directory, and MCServer will build.
## CMake on Unix-based platforms ###
### Release Mode ###
Release mode is preferred for almost all cases, it has much better speed and less console spam. However, if you are developing MCServer actively, debug mode might be better.
@ -69,8 +100,10 @@ Assuming you are in the MCServer folder created in the initial setup step, you n
```
mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=RELEASE .. && make
cmake -DCMAKE_BUILD_TYPE=RELEASE ..
```
NOTE: CMake can generate project files for many different programs, such as Xcode, eclipse, and ninja. To use a different generator, first type `cmake --help`, and at the end, cmake will output the different generators that are available. To specify one, add `-G` followed by the name of the generator, in the `cmake` command. Note that the name is case-sensitive.
The executable will be built in the `MCServer/MCServer` folder and will be named `MCServer`.
### Debug Mode ###
@ -81,8 +114,10 @@ Assuming you are in the MCServer folder created in the Getting the sources step,
```
mkdir Debug
cd Debug
cmake -DCMAKE_BUILD_TYPE=DEBUG .. && make
cmake -DCMAKE_BUILD_TYPE=DEBUG ..
```
NOTE: CMake can generate project files for many different programs, such as Xcode, eclipse, and ninja. To use a different generator, first type `cmake --help`, and at the end, cmake will output the different generators that are available. To specify one, add `-G` followed by the name of the generator, in the `cmake` command. Note that the name is case-sensitive.
The executable will be built in the `MCServer/MCServer` folder and will be named `MCServer_debug`.
### 32 Bit Mode switch ###

View File

@ -27,7 +27,7 @@ Code Stuff
- The only exception: a `switch` statement with all `case` statements being a single short statement is allowed to use the short brace-less form.
- These two rules really mean that indent is governed by braces
* Add an empty last line in all source files (GCC and GIT can complain otherwise)
* Use doxy-comments for functions in the header file, format as `/** Description */`
* All new public functions in all classes need documenting comments on what they do and what behavior they follow, use doxy-comments formatted as `/** Description */`. Do not use asterisks on additional lines in multi-line comments.
* Use spaces after the comment markers: `// Comment` instead of `//Comment`

View File

@ -1,5 +1,6 @@
Many people have contributed to MCServer, and this list attempts to broadcast at least some of them.
BasedDoge (Donated AlchemistVillage prefabs)
bearbin (Alexander Harkness)
derouinw
Diusrex
@ -26,6 +27,7 @@ tonibm19
UltraCoderRU
worktycho
xoft
Yeeeeezus (Donated AlchemistVillage prefabs)
Howaner
Please add yourself to this list if you contribute to MCServer.

View File

@ -3,14 +3,14 @@ Hello! Thanks for wanting to work on this project :smile:, and I hope that this
Minecraft Basics
----------------
If you don't play Minecraft or don't have a great knowledge of the basic systems, you should get to know them. The [Minecraft Wiki](http://minecraft.gamepedia.com/Minecraft_Wiki) is quite useful for this task, although some youtubers are also fairly good at teaching the basics and just playing is quite good too.
If you don't play Minecraft or don't have a great knowledge of the basic systems, you should get to know them. The [Minecraft Wiki](http://minecraft.gamepedia.com/Minecraft_Wiki) is quite useful for this task, although some youtubers are also fairly good at teaching the basics and just playing is quite good too. It is possible to contribute without knowing minecraft in detail though.
I'd say that the important topics are:
* Differnt types of blocks and how they act.
* Mobs, what they do and how.
* Redstone, pistons, and automation.
* Farming
* Farming.
* Fighting, health and the hunger system.
Useful Resources
@ -39,7 +39,7 @@ You'll also need CMake to generate the makefile to build from.
**Windows:**
If you use Windows, your best bet is the MSVC2008 (available as a free download in the Express edition from MS) or MSVS2013 (ditto), solution files for both are currently in the repo.
If you use Windows, your best bet is the MSVC2008 (available as a free download in the Express edition from MS) or MSVS2013 (ditto), solution files for which can be generated with cmake. You'll also need cmake to generate the project files.
Setting up the Repo
-------------------
@ -85,7 +85,7 @@ Basically, the process is:
**Windows:**
You need to first execute the `src/Bindings/AllToLua.bat` script file, then just open the solution file in your MSVC of choice and build.
You need to first generate a project file with `cmake . -DCMAKE_BUILD_TYPE=DEBUG` then execute the `src/Bindings/AllToLua.bat` script file, then just open the solution file in your MSVC of choice and build.
How to Run
----------
@ -99,18 +99,18 @@ There are a few fairly easy issues for you to get started with, as well as some
**Easy**:
* #288
* #385
* #402
* #380
* #503
* #491
* #140
* #493
* #577
* #381
* #752
* Clean up some of the compiler warnings. (Check [Travis CI](http://travis-ci.org/mc-server/MCServer) for a list of them.) With clang, there are over 10000 lines of warnings to clean up.
**More Difficult**:
* #17
* #398
* #133
* #134
* #215
You may also want to write some plugins. They are written in lua, with excellent API documentation available via [APIDump](http://mc-server.xoft.cz/LuaAPI). The [Core](https://github.com/mc-server/Core) plugin should also help quite a bit here.

4
MCServer/.gitignore vendored
View File

@ -30,3 +30,7 @@ motd.txt
*.xml
mcserver_api.lua
# Ignore the webadmin certs / privkey, so that no-one commits theirs by accident:
webadmin/httpscert.crt
webadmin/httpskey.pem

View File

@ -114,6 +114,7 @@ g_APIDesc =
GetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ", Return = "NIBBLETYPE", Notes = "Returns the skylight at the specified absolute coords" },
GetBlockType = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified absolute coords" },
GetBlockTypeMeta = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified absolute coords" },
GetCoordRange = {Params = "", Return = "MaxX, MaxY, MaxZ", Notes = "Returns the maximum relative coords in all 3 axes. See also GetSize()." },
GetDataTypes = { Params = "", Return = "number", Notes = "Returns the mask of datatypes that the object is currently holding" },
GetOrigin = { Params = "", Return = "OriginX, OriginY, OriginZ", Notes = "Returns the origin coords of where the area was read from." },
GetOriginX = { Params = "", Return = "number", Notes = "Returns the origin x-coord" },
@ -124,7 +125,7 @@ g_APIDesc =
GetRelBlockSkyLight = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "NIBBLETYPE", Notes = "Returns the skylight at the specified relative coords" },
GetRelBlockType = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified relative coords" },
GetRelBlockTypeMeta = { Params = "RelBlockX, RelBlockY, RelBlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified relative coords" },
GetSize = { Params = "", Return = "SizeX, SizeY, SizeZ", Notes = "Returns the size of the area in all 3 axes." },
GetSize = { Params = "", Return = "SizeX, SizeY, SizeZ", Notes = "Returns the size of the area in all 3 axes. See also GetCoordRange()." },
GetSizeX = { Params = "", Return = "number", Notes = "Returns the size of the held data in the x-axis" },
GetSizeY = { Params = "", Return = "number", Notes = "Returns the size of the held data in the y-axis" },
GetSizeZ = { Params = "", Return = "number", Notes = "Returns the size of the held data in the z-axis" },
@ -522,13 +523,16 @@ 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)." },
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." },
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." },
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." },
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)." },
@ -1151,6 +1155,7 @@ These ItemGrids are available in the API and can be manipulated by the plugins,
HasItems = { Params = "{{cItem|cItem}}", Return = "bool", Notes = "Returns true if there are at least as many items of the specified type as in the parameter" },
HowManyCanFit = { Params = "{{cItem|cItem}}", Return = "number", Notes = "Returns the number of the specified items that can fit in the storage, including empty slots" },
HowManyItems = { Params = "{{cItem|cItem}}", Return = "number", Notes = "Returns the number of the specified items that are currently stored" },
RemoveItem = { Params = "{{cItem}}", Return = "number", Notes = "Removes the specified item from the inventory, as many as possible, up to the item's m_ItemCount. Returns the number of items that were removed." },
RemoveOneEquippedItem = { Params = "", Return = "", Notes = "Removes one item from the hotbar's currently selected slot" },
SetArmorSlot = { Params = "ArmorSlotNum, {{cItem|cItem}}", Return = "", Notes = "Sets the specified armor slot contents" },
SetEquippedSlotNum = { Params = "EquippedSlotNum", Return = "", Notes = "Sets the currently selected hotbar slot number" },
@ -1380,6 +1385,7 @@ local Item5 = cItem(E_ITEM_DIAMOND_CHESTPLATE, 1, 0, "thorns=1;unbreaking=3");
{ Params = "SlotNum", Return = "bool", Notes = "Returns true if the specified slot is empty, or an invalid slot is specified" },
{ Params = "X, Y", Return = "bool", Notes = "Returns true if the specified slot is empty, or an invalid slot is specified" },
},
RemoveItem = { Params = "{{cItem}}", Return = "number", Notes = "Removes the specified item from the grid, as many as possible, up to the item's m_ItemCount. Returns the number of items that were removed." },
RemoveOneItem =
{
{ Params = "SlotNum", Return = "{{cItem|cItem}}", Notes = "Removes one item from the stack in the specified slot and returns it as a single cItem. Empty slots are skipped and an empty item is returned" },
@ -1687,6 +1693,9 @@ a_Player:OpenWindow(Window);
TakeDamage = { Return = "" },
KilledBy = { Return = "" },
GetHealth = { Return = "number" },
AddEntityEffect = { Params = "EffectType, {{cEntityEffect}}", Return = "", Notes = "Applies an entity effect" },
RemoveEntityEffect = { Params = "EffectType", Return = "", Notes = "Removes a currently applied entity effect" },
ClearEntityEffects = { Return = "", Notes = "Removes all currently applied entity effects" },
},
Inherits = "cEntity",
}, -- cPawn
@ -1871,9 +1880,9 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
},
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." },
ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Executes the command as if given by the specified Player. Checks permissions. Returns true if executed." },
ExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Executes the command as if given by the specified Player. Checks permissions." },
FindPlugins = { Params = "", Return = "", Notes = "Refreshes the list of plugins to include all folders inside the Plugins folder (potentially new disabled plugins)" },
ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "bool", Notes = "Same as ExecuteCommand, but doesn't check permissions" },
ForceExecuteCommand = { Params = "{{cPlayer|Player}}, CommandStr", Return = "{{cPluginManager#CommandResult|CommandResult}}", Notes = "Same as ExecuteCommand, but doesn't check permissions" },
ForEachCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindCommand(). The CallbackFn has the following signature: <pre class=\"prettyprint lang-lua\">function(Command, Permission, HelpString)</pre>. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." },
ForEachConsoleCommand = { Params = "CallbackFn", Return = "bool", Notes = "Calls the CallbackFn function for each command that has been bound using BindConsoleCommand(). The CallbackFn has the following signature: <pre class=\"prettyprint lang-lua\">function (Command, HelpString)</pre>. If the callback returns true, the enumeration is aborted and this API function returns false; if it returns false or no value, the enumeration continues with the next command, and the API function returns true." },
Get = { Params = "", Return = "cPluginManager", Notes = "(STATIC) Returns the single instance of the plugin manager" },
@ -1889,8 +1898,23 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
LogStackTrace = { Params = "", Return = "", Notes = "(STATIC) Logs a current stack trace of the Lua engine to the server console log. Same format as is used when the plugin fails." },
ReloadPlugins = { Params = "", Return = "", Notes = "Reloads all active plugins" },
},
ConstantGroups=
{
CommandResult =
{
Include = "^cr.*",
TextBefore = [[
Results that the (Force)ExecuteCommand return. This gives information if the command is executed or not and the reason.
]],
},
},
Constants =
{
crBlocked = { Notes = "When a plugin stopped the command using the OnExecuteCommand hook" },
crError = { Notes = "When the command handler for the given command results in an error" },
crExecuted = { Notes = "When the command is successfully executed." },
crNoPermission = { Notes = "When the player doesn't have permission to execute the given command." },
crUnknownCommand = { Notes = "When the given command doesn't exist." },
HOOK_BLOCK_SPREAD = { Notes = "Called when a block spreads based on world conditions" },
HOOK_BLOCK_TO_PICKUPS = { Notes = "Called when a block has been dug and is being converted to pickups. The server has provided the default pickups and the plugins may modify them." },
HOOK_CHAT = { Notes = "Called when a client sends a chat message that is not a command. The plugin may modify the chat message" },
@ -1969,7 +1993,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage);
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." },
FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for the given player." },
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>" },
GetCraftingRecipes = { Params = "", Return = "{{cCraftingRecipe|cCraftingRecipe}}", Notes = "Returns the CraftingRecipes object" },
@ -2294,10 +2318,14 @@ end
IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the current gamemode is gmCreative." },
IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the current gamemode is gmSurvival." },
IsPVPEnabled = { Params = "", Return = "bool", Notes = "Returns whether PVP is enabled in the world settings." },
IsWeatherRain = { Params = "", Return = "bool", Notes = "Returns true if the current weather is rain." },
IsWeatherStorm = { Params = "", Return = "bool", Notes = "Returns true if the current weather is a storm." },
IsWeatherRain = { Params = "", Return = "bool", Notes = "Returns true if the current world is raining." },
IsWeatherRainAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location is raining (takes into account biomes)." },
IsWeatherStorm = { Params = "", Return = "bool", Notes = "Returns true if the current world is stormy." },
IsWeatherStormAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location is stormy (takes into account biomes)." },
IsWeatherSunny = { Params = "", Return = "bool", Notes = "Returns true if the current weather is sunny." },
IsWeatherWet = { Params = "", Return = "bool", Notes = "Returns true if the current weather has any precipitation (rain or storm)." },
IsWeatherSunnyAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the current weather is sunny at the specified location (takes into account biomes)." },
IsWeatherWet = { Params = "", Return = "bool", Notes = "Returns true if the current world has any precipitation (rain or storm)." },
IsWeatherWetAt = { Params = "BlockX, BlockZ", Return = "bool", Notes = "Returns true if the specified location has any precipitation (rain or storm) (takes into account biomes)." },
QueueBlockForTick = { Params = "BlockX, BlockY, BlockZ, TicksToWait", Return = "", Notes = "Queues the specified block to be ticked after the specified number of gameticks." },
QueueSaveAllChunks = { Params = "", Return = "", Notes = "Queues all chunks to be saved in the world storage thread" },
QueueSetBlock = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta, TickDelay", Return = "", Notes = "Queues the block to be set to the specified blocktype and meta after the specified amount of game ticks. Uses SetBlock() for the actual setting, so simulators are woken up and block entities are handled correctly." },
@ -2317,6 +2345,7 @@ end
{ Params = "BlockX, BlockY, BlockZ, BlockMeta", Return = "", Notes = "Sets the meta for the block at the specified coords." },
{ Params = "{{Vector3i|BlockCoords}}, BlockMeta", Return = "", Notes = "Sets the meta for the block at the specified coords." },
},
SetChunkAlwaysTicked = { Params = "ChunkX, ChunkZ, IsAlwaysTicked", Return = "", Notes = "Sets the chunk to always be ticked even when it doesn't contain any clients. IsAlwaysTicked set to true turns forced ticking on, set to false turns it off. Every call with 'true' should be paired with a later call with 'false', otherwise the ticking won't stop. Multiple actions can request ticking independently, the ticking will continue until the last call with 'false'. Note that when the chunk unloads, it loses the value of this flag." },
SetNextBlockTick = { Params = "BlockX, BlockY, BlockZ", Return = "", Notes = "Sets the blockticking to start at the specified block in the next tick." },
SetCommandBlockCommand = { Params = "BlockX, BlockY, BlockZ, Command", Return = "bool", Notes = "Sets the command to be executed in a command block at the specified coordinates. Returns if command was changed." },
SetCommandBlocksEnabled = { Params = "IsEnabled (bool)", Return = "", Notes = "Sets whether command blocks should be enabled on the (entire) server." },
@ -2929,6 +2958,7 @@ end
{
-- No sorting is provided for these, they will be output in the same order as defined here
{ FileName = "Writing-a-MCServer-plugin.html", Title = "Writing a MCServer plugin" },
{ FileName = "InfoFile.html", Title = "Using the Info.lua file" },
{ FileName = "SettingUpDecoda.html", Title = "Setting up the Decoda Lua IDE" },
{ FileName = "SettingUpZeroBrane.html", Title = "Setting up the ZeroBrane Studio Lua IDE" },
{ FileName = "UsingChunkStays.html", Title = "Using ChunkStays" },

View File

@ -2,23 +2,33 @@ return
{
HOOK_DISCONNECT =
{
CalledWhen = "A player has explicitly disconnected.",
CalledWhen = [[
A client has disconnected, either by explicitly sending the disconnect packet (in older protocols) or
their connection was terminated
]],
DefaultFnName = "OnDisconnect", -- also used as pagename
Desc = [[
This hook is called when a client is about to be disconnected from the server, for whatever reason.
<p><b>Note that this hook will be removed after <1.7 protocol support is removed, as it was originally a hook for
the client sending the server a disconnect packet, which no longer happens.</b></p>
This hook is called when a client has disconnected from the server, for whatever reason. It is also
called when the client sends the Disconnect packet (only in pre-1.7 protocols). This hook is not called
for server ping connections.</p>
<p>
Note that the hook is called even for connections to players who failed to auth. In such a case there's
no {{cPlayer}} object associated with the client.</p>
<p>
See also the {{OnHandshake|HOOK_HANDSHAKE}} hook which is called when the client connects (and presents
a handshake message, so that they are not just status-pinging). If you need to store a per-player
object, use the {{OnPlayerJoined|HOOK_PLAYER_JOINED}} and {{OnPlayerDestroyed|HOOK_PLAYER_DESTROYED}}
hooks instead, those are guaranteed to have the {{cPlayer}} object associated.
]],
Params =
{
{ Name = "Player", Type = "{{cPlayer}}", Notes = "The player who has disconnected" },
{ Name = "Client", Type = "{{cClientHandle}}", Notes = "The client who has disconnected" },
{ Name = "Reason", Type = "string", Notes = "The reason that the client has sent in the disconnect packet" },
},
Returns = [[
If the function returns false or no value, MCServer calls other plugins' callbacks for this event.
If the function returns true, no other plugins are called for this event. In either case,
the player is disconnected.
the client is disconnected.
]],
}, -- HOOK_DISCONNECT
}

View File

@ -0,0 +1,33 @@
return
{
HOOK_ENTITY_ADD_EFFECT =
{
CalledWhen = "An entity effect is about to get added to an entity.",
DefaultFnName = "OnEntityAddEffect", -- also used as pagename
Desc = [[
This hook is called whenever an entity effect is about to be added to an entity. The plugin may
disallow the addition by returning true.</p>
<p>Note that this hook only fires for adding the effect, but not for the actual effect application. See
also the {{OnEntityRemoveEffect|HOOK_ENTITY_REMOVE_EFFECT}} for notification about effects expiring /
removing, and {{OnEntityApplyEffect|HOOK_ENTITY_APPLY_EFFECT}} for the actual effect application to the
entity.
]],
Params =
{
{ Name = "Entity", Type = "{{cEntity}}", Notes = "The entity to which the effect is about to be added" },
{ Name = "EffectType", Type = "number", Notes = "The type of the effect to be added. One of the effXXX constants." },
{ Name = "EffectDuration", Type = "number", Notes = "The duration of the effect to be added, in ticks." },
{ Name = "EffectIntensity", Type = "number", Notes = "The intensity (level) of the effect to be added. " },
{ Name = "DistanceModifier", Type = "number", Notes = "The modifier for the effect intensity, based on distance. Used mainly for splash potions." },
},
Returns = [[
If the plugin returns true, the effect will not be added and none of the remaining hook handlers will
be called. If the plugin returns false, MCServer calls all the remaining hook handlers and finally
the effect is added to the entity.
]],
}, -- HOOK_EXECUTE_COMMAND
}

View File

@ -0,0 +1,27 @@
return
{
HOOK_PLAYER_FOOD_LEVEL_CHANGE =
{
CalledWhen = "Called before the player food level changed. Plugin may override",
DefaultFnName = "OnPlayerFoodLevelChange", -- also used as pagename
Desc = [[
This hook is called before the food level changes.
The food level is not changed yet, plugins may choose
to refuse the change.
]],
Params =
{
{ Name = "Player", Type = "{{cPlayer}}", Notes = "The player who changes the food level." },
{ Name = "NewFoodLevel", Type = "number", Notes = "The new food level." },
},
Returns = [[
If the function returns false or no value, the next plugin's callback is called. Afterwards, the
server changes the food level of the player. If the function returns true, no
other callback is called for this event and the player's food level doesn't change.
]],
}, -- HOOK_PLAYER_FOOD_LEVEL_CHANGE
};

View File

@ -2,7 +2,7 @@ return
{
HOOK_PLAYER_USED_BLOCK =
{
CalledWhen = "A player has just used a block (chest, furnace). Notification only.",
CalledWhen = "A player has just used a block (chest, furnace...). Notification only.",
DefaultFnName = "OnPlayerUsedBlock", -- also used as pagename
Desc = [[
This hook is called after a {{cPlayer|player}} has right-clicked a block that can be used, such as a

View File

@ -10,6 +10,11 @@ return
Params =
{
{ Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." },
{ Name = "BlockX", Type = "number", Notes = "The X-coord where the projectile hit." },
{ Name = "BlockY", Type = "number", Notes = "The Y-coord where the projectile hit." },
{ Name = "BlockZ", Type = "number", Notes = "The Z-coord where the projectile hit." },
{ Name = "BlockFace", Type = "number", Notes = "The side of the block where the projectile hit." },
{ Name = "BlockHitPos", Type = "Vector3d", Notes = "The exact position where the projectile hit." },
},
Returns = [[
If the function returns false or no value, the next plugin's callback is called. If the function

View File

@ -6,7 +6,7 @@ return
DefaultFnName = "OnWeatherChanging", -- also used as pagename
Desc = [[
This hook is called when the current weather has expired and a new weather is selected. Plugins may
override the new weather setting.</p>
override the new weather being set.</p>
<p>
The new weather setting is sent to the clients only after this hook has been processed.</p>
<p>
@ -19,9 +19,12 @@ return
{ Name = "Weather", Type = "number", Notes = "The newly selected weather. One of wSunny, wRain, wStorm" },
},
Returns = [[
If the function returns false or no value, the server calls other plugins' callbacks and finally
sets the weather. If the function returns true, the server takes the second returned value (wSunny
by default) and sets it as the new weather. No other plugins' callbacks are called in this case.
The hook handler can return up to two values. If the first value is false or not present, the server
calls other plugins' callbacks and finally sets the weather. If it is true, the server doesn't call any
more callbacks for this hook. The second value returned is used as the new weather. If no value is
given, the weather from the parameters is used as the weather. Returning false as the first value and a
specific weather constant as the second value makes the server call the rest of the hook handlers with
the new weather value.
]],
}, -- HOOK_WEATHER_CHANGING
}

View File

@ -0,0 +1,246 @@
<!DOCTYPE html>
<html>
<head>
<title>MCServer - Info.lua file</title>
<link rel="stylesheet" type="text/css" href="main.css" />
<link rel="stylesheet" type="text/css" href="prettify.css" />
<script src="prettify.js"></script>
<script src="lang-lua.js"></script>
<meta charset="UTF-8">
</head>
<body>
<div id="content">
<h1>Info.lua file</h1>
<h2>Contents</h2>
<ul>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#Overall">The overall structure</a></li>
<li><a href="#AdditionalInformation">AdditionalInformation table</a></li>
<li><a href="#Commands">Commands table</a></li>
<li><a href="#ConsoleCommands">ConsoleCommands table</a></li>
<li><a href="#Permissions">Permissions table</a></li>
<li><a href="#Using">Using the file in code</a></li>
<li><a href="#Examples">Examples</a></li>
</ul>
<hr />
<a name="Introduction"><h2>Introduction</h2></a>
<p>For a long time MCServer plugins were plagued by poor documentation. The plugins worked, people who wrote them knew how to use them, but for anyone new to the plugin it was a terrible ordeal learning how to use it. Most of the times, the plugin authors only wrote what commands the plugin supported, sometimes not even that. Then, there was a call to action to put an end to this, to make documenting the plugins easy and at the same time centralized. Thus, the Info.lua file was born.</p>
<p>Most plugins have some parts that are the same across all the plugins. These are commands, console commands and their permissions. If a plugin implemented a command, it would practically copy &amp; paste the same code over and over again. So it makes sense to extract only unique information, centralize it and automate all the parts around it. This was another reason for the Info.lua file - it is a central hub of commands, console commands and their permissions.</p>
<p>Last, but not least, we want to make a plugin repository on the web in the future, a repository that would store plugins, their descriptions, comments. It makes sense that the centralized information can be parsed by the repository automatically, so that advanced things, such as searching for a plugin based on a command, or determining whether two plugins collide command-wise, are possible.</p>
<p>After this file format has been devised, a tool has been written that allows for an easy generation of the documentation for the plugin in various formats. It outputs the documentation in a format that is perfect for pasting into the forum. It generates documentation in a Markup format to use in README.md on GitHub and similar sites. The clever thing is that you don't need to keep all those formats in sync manually - you edit the Info.lua file and this tool will re-generate the documentation for you.</p>
<p>So to sum up, the Info.lua file contains the plugins' commands, console commands, their permissions and possibly the overall plugin documentation, in a structured manner that can be parsed by a program, yet is human readable and editable.</p>
<hr />
<a name="Overall"><h2>The overall structure</h2></a>
<p>The file consist of a declaration of a single Lua table, g_PluginInfo. This table contains all the information, structured, as its members. Each member can be a structure by itself. The entire file is a valid Lua source file, so any tool that syntax-checks Lua source can syntax-check this file. The file is somewhat forward- and backward- compatible, in the sense that it can be extended in any way without breaking.</p>
<p>Here's a skeleton of the file:</p>
<pre class="prettyprint lang-lua">
g_PluginInfo =
{
Name = "Example Plugin",
Date = "2014-06-12",
Description = "This is an example plugin that shows how to use the Info.lua file",
-- The following members will be documented in greater detail later:
AdditionalInformation = {},
Commands = {},
ConsoleCommands = {},
Permissions = {},
}
</pre>
<p>As you can see, the structure is pretty straightforward. Note that the order of the elements inside the table is not important (Lua property).</p>
<p>The first few elements are for book-keeping. They declare the plugin's name, the date in ISO-format, representing the version of the plugin, and the description. The idea is that the description sums up what the plugin is all about, within some two or three sentences.</p>
<hr />
<a name="AdditionalInformation"><h2>AdditionalInformation table</h2></a>
<p>This table is used for more detailed description of the plugin. If there is any non-trivial setup process, dependencies, describe them here. This is where the description should get detailed. Don't worry about using several paragraphs of text here, if it makes the plugin easier to understand.</p>
<p>The table should have the following layout:</p>
<pre class="prettyprint lang-lua">
AdditionalInformation =
{
{
Title = "Chapter 1",
Contents = "Describe one big aspect of the plugin here",
},
{
Title = "Chapter 2",
Contents = "Describe another big topic",
},
}
</pre>
<p>The idea here is that the tool that is used to generate the documentation from the Info.lua file will create a linkified table of contents and then each of the information elements' contents. This information should be all that is needed to successfully configure, run and manage the plugin.</p>
<hr />
<a name="Commands"><h2>Commands table</h2></a>
<p>The commands table lists all the commands that the plugin implements, together with their handler functions, required permissions, help strings and further information. The table supports recursion, which allows plugins to create multi-word commands easily (such as "//schematic load" and "//schematic save"), each having its own separate handler.</p>
<p>The table uses structure similar to the following:</p>
<pre class="prettyprint lang-lua">
Commands =
{
["/cmd1"] =
{
HelpString = "Performs the first action",
Permission = "firstplugin.cmds.1",
Alias = "/c1",
Handler = HandleCmd1,
ParameterCombinations =
{
{
Params = "x y z",
Help = "Performs the first action at the specified coordinates",
},
{
Params = "-p",
Help = "Performs the first action at the player's coordinates",
}
},
},
["/cmd2"] =
{
Alias = {"/c2", "//c2" },
Subcommands =
{
sub1 = -- This declares a "/cmd2 sub1" command
{
HelpString = "Performs the second action's first subcommand",
Permission = "firstplugin.cmds.2.1",
Alias = "1",
Handler = HandleCmd2Sub1,
ParameterCombinations =
{
{
Params = "x y z",
Help = "Performs the second action's first subcommand at the specified coordinates",
},
{
Params = "-p",
Help = "Performs the second action's first subcommand at the player's coordinates",
}
},
},
sub2 = -- Declares a "/cmd2 sub2" command
{
HelpString = "Performs the second action's second subcommand",
Permission = "firstplugin.cmds.2.2",
Handler = HandleCmd2Sub2,
},
},
},
}
</pre>
<p>Although it may seem overwhelming at first, there is a "method to this madness". Each element of the Commands table defines one command. Most commands start with a slash, so the special Lua syntax for table elements with non-standard names needs to be applied (<code>["/cmd1"] =</code>). The command can either specify subcommands, or a handler function (specifying both is UndefinedBehavior). Subcommands uses the same structure as the entire Commands table, recursively.</p>
<p>The permission element specifies that the command is only available with the specified permission. Note that the permission for subcommand's parent isn't checked when the subcommand is called. This means that specifying the permission for a command that has subcommands has no effect whatsoever, but is discouraged because we may add processing for that in the future.</p>
<p>The ParameterCombinations table is used only for generating the documentation, it lists the various combinations of parameters that the command supports. It's worth specifying even if the command supports only one combination, because that combination will get documented this way.</p>
<p>The Alias member specifies any possible aliases for the command. Each alias is registered separately and if there is a subcommand table, it is applied to all aliases, just as one would expect. You can specify either a single string as the value (if there's only one alias), or a table of strings for multiple aliases. Commands with no aliases do not need to specify this member at all.</p>
<hr />
<a name="ConsoleCommands"><h2>ConsoleCommands table</h2>
<p>This table serves a purpose similar to that of the Commands table, only these commands are provided for the server console. Therefore, there are no permissions specified for these commands. Since most console commands don't use a leading slash, the command names don't need the special syntax. Also, the handler function doesn't receive the Player parameter.</p>
<p>Here's an example of a ConsoleCommands table:</p>
<pre class="prettyprint lang-lua">
ConsoleCommands =
{
concmd =
{
HelpString = "Performs the console action",
Subcommands =
{
sub1 =
{
HelpString = "Performs the console action's first subcommand",
Handler = HandleConCmdSub1,
ParameterCombinations =
{
{
Params = "x y z",
Help = "Performs the console action's first subcommand at the specified coordinates",
},
},
},
sub2 =
{
HelpString = "Performs the console action's second subcommand",
Handler = HandleConCmdSub2,
},
},
},
}
</pre>
<hr />
<a name="Permissions"><h2>Permissions table</h2></a>
<p>The purpose of this table is to document permissions that the plugin uses. The documentation generator automatically collects the permissions specified in the Command table; the Permissions table adds a description for these permissions and may declare other permissions that aren't specifically included in the Command table.</p>
<pre class="prettyprint lang-lua">
Permissions =
{
["firstplugin.cmd.1.1"] =
{
Description = "Allows the players to build high towers using the first action.",
RecommendedGroups = "players",
},
["firstplugin.cmd.2.1"] =
{
Description = "Allows the players to kill entities using the second action. Note that this may be misused to kill other players, too.",
RecommendedGroups = "admins, mods",
},
}
</pre>
<p>The RecommendedGroup element lists, in plain English, the intended groups for which the permission should be enabled on a typical server. Plugin authors are advised to create reasonable defaults, prefering security to openness, so that admins using these settings blindly don't expose their servers to malicious users.</p>
<hr />
<a name="Using"><h2>Using the file in code</h2></a>
<p>Just writing the Info.lua file and saving it to the plugin folder is not enough for it to actually be used. Your plugin needs to include the following boilerplate code, preferably in its Initialize() function:</p>
<pre class="prettyprint lang-lua">
-- Use the InfoReg shared library to process the Info.lua file:
dofile(cPluginManager:GetPluginsPath() .. "/InfoReg.lua")
RegisterPluginInfoCommands()
RegisterPluginInfoConsoleCommands()
</pre>
<p>Of course, if your plugin doesn't have any console commands, it doesn't need to call the RegisterPluginInfoConsoleCommands() function, and similarly if it doesn't have any in-game commands, it doesn't need to call the RegisterPluginInfoCommands() function.</p>
<hr />
<a name="Examples"><h2>Examples</h2></a>
<p>There are several plugins that already implement this approach. You can visit them for inspiration and to see what the generated documentation looks like:</p>
<ul>
<li>Gallery plugin: <a href="https://github.com/mc-server/Gallery/blob/master/Info.lua">Info.lua</a>, <a href="http://forum.mc-server.org/showthread.php?tid=1306">Forum</a> documentation</li>
<li>WorldEdit plugin: <a href="https://github.com/mc-server/WorldEdit/blob/master/Info.lua">Info.lua</a>, <a href="http://forum.mc-server.org/showthread.php?tid=870">Forum</a> and <a href="https://github.com/mc-server/WorldEdit">MarkDown</a> documentation</li>
</ul>
<script>
prettyPrint();
</script>
</div>
</body>
</html>

View File

@ -39,7 +39,8 @@ pre
body
{
min-width: 800px;
min-width: 400px;
max-width: 1200px;
width: 95%;
margin: 10px auto;
background-color: white;

View File

@ -27,10 +27,14 @@ local function LoadAPIFiles(a_Folder, a_DstTable)
-- We only want .lua files from the folder:
if (cFile:IsFile(FileName) and fnam:match(".*%.lua$")) then
local TablesFn, Err = loadfile(FileName);
if (TablesFn == nil) then
if (type(TablesFn) ~= "function") then
LOGWARNING("Cannot load API descriptions from " .. FileName .. ", Lua error '" .. Err .. "'.");
else
local Tables = TablesFn();
if (type(Tables) ~= "table") then
LOGWARNING("Cannot load API descriptions from " .. FileName .. ", returned object is not a table (" .. type(Tables) .. ").");
break
end
for k, cls in pairs(Tables) do
a_DstTable[k] = cls;
end

View File

@ -43,7 +43,7 @@ function HandleRequest_Generation( Request )
local Content = ""
if (Request.PostParams["AGHRRRR"] ~= nil) then
GENERATION_STATE = 0
WW_instance:SaveAllChunks()
WW_instance:QueueSaveAllChunks()
WW_instance:QueueUnloadUnusedChunks()
LOGERROR("" .. PLUGIN:GetName() .. " v" .. PLUGIN:GetVersion() .. ": works ABORTED by admin")
end

View File

@ -29,7 +29,10 @@ function Initialize(Plugin)
PM:AddHook(cPluginManager.HOOK_WORLD_TICK, OnWorldTick);
PM:AddHook(cPluginManager.HOOK_PLUGINS_LOADED, OnPluginsLoaded);
PM:AddHook(cPluginManager.HOOK_PLUGIN_MESSAGE, OnPluginMessage);
PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined)
PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined);
PM:AddHook(cPluginManager.HOOK_PROJECTILE_HIT_BLOCK, OnProjectileHitBlock);
PM:AddHook(cPluginManager.HOOK_CHUNK_UNLOADING, OnChunkUnloading);
PM:AddHook(cPluginManager.HOOK_WORLD_STARTED, OnWorldStarted);
-- _X: Disabled so that the normal operation doesn't interfere with anything
-- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated);
@ -57,9 +60,10 @@ function Initialize(Plugin)
PM:BindCommand("/ff", "debuggers", HandleFurnaceFuel, "- Shows how long the currently held item would burn in a furnace");
PM:BindCommand("/sched", "debuggers", HandleSched, "- Schedules a simple countdown using cWorld:ScheduleTask()");
PM:BindCommand("/cs", "debuggers", HandleChunkStay, "- Tests the ChunkStay Lua integration for the specified chunk coords");
PM:BindCommand("/compo", "debuggers", HandleCompo, "- Tests the cCompositeChat bindings")
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("/compo", "debuggers", HandleCompo, "- Tests the cCompositeChat bindings");
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.");
Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers)
Plugin:AddWebTab("StressTest", HandleRequest_StressTest)
@ -345,7 +349,7 @@ end
function OnUsingBlazeRod(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, CursorY, CursorZ)
-- Magic rod of query: show block types and metas for both neighbors of the pointed face
local Type, Meta, Valid = Player:GetWorld():GetBlockTypeMeta(BlockX, BlockY, BlockZ, Type, Meta);
local Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(BlockX, BlockY, BlockZ);
if (Type == E_BLOCK_AIR) then
Player:SendMessage(cChatColor.LightGray .. "Block {" .. BlockX .. ", " .. BlockY .. ", " .. BlockZ .. "}: air:" .. Meta);
@ -355,7 +359,7 @@ function OnUsingBlazeRod(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, Cur
end
local X, Y, Z = AddFaceDirection(BlockX, BlockY, BlockZ, BlockFace);
Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(X, Y, Z, Type, Meta);
Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(X, Y, Z);
if (Type == E_BLOCK_AIR) then
Player:SendMessage(cChatColor.LightGray .. "Block {" .. X .. ", " .. Y .. ", " .. Z .. "}: air:" .. Meta);
else
@ -530,7 +534,7 @@ function OnTakeDamage(Receiver, TDI)
-- Receiver is cPawn
-- TDI is TakeDamageInfo
LOG(Receiver:GetClass() .. " was dealt " .. DamageTypeToString(TDI.DamageType) .. " damage: Raw " .. TDI.RawDamage .. ", Final " .. TDI.FinalDamage .. " (" .. (TDI.RawDamage - TDI.FinalDamage) .. " covered by armor)");
-- LOG(Receiver:GetClass() .. " was dealt " .. DamageTypeToString(TDI.DamageType) .. " damage: Raw " .. TDI.RawDamage .. ", Final " .. TDI.FinalDamage .. " (" .. (TDI.RawDamage - TDI.FinalDamage) .. " covered by armor)");
return false;
end
@ -1102,6 +1106,41 @@ end
function HandleRMItem(a_Split, a_Player)
-- Check params:
if (a_Split[2] == nil) then
a_Player:SendMessage("Usage: /rmitem <Item> [Count]")
return true
end
-- Parse the item type:
local Item = cItem()
if (not StringToItem(a_Split[2], Item)) then
a_Player:SendMessageFailure(a_Split[2] .. " isn't a valid item")
return true
end
-- Parse the optional item count
if (a_Split[3] ~= nil) then
local Count = tonumber(a_Split[3])
if (Count == nil) then
a_Player:SendMessageFailure(a_Split[3] .. " isn't a valid number")
return true
end
Item.m_ItemCount = Count
end
-- Remove the item:
local NumRemovedItems = a_Player:GetInventory():RemoveItem(Item)
a_Player:SendMessageSuccess("Removed " .. NumRemovedItems .. " Items!")
return true
end
function HandleRequest_Debuggers(a_Request)
local FolderContents = cFile:GetFolderContents("./");
return "<p>The following objects have been returned by cFile:GetFolderContents():<ul><li>" .. table.concat(FolderContents, "</li><li>") .. "</li></ul></p>";
@ -1379,3 +1418,40 @@ end
function OnProjectileHitBlock(a_Projectile, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_BlockHitPos)
-- Test projectile hooks by setting the blocks they hit on fire:
local BlockX, BlockY, BlockZ = AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)
local World = a_Projectile:GetWorld()
World:SetBlock(BlockX, BlockY, BlockZ, E_BLOCK_FIRE, 0)
end
function OnChunkUnloading(a_World, a_ChunkX, a_ChunkZ)
-- Do not let chunk [0, 0] unload, so that it continues ticking [cWorld:SetChunkAlwaysTicked() test]
if ((a_ChunkX == 0) and (a_ChunkZ == 0)) then
return true
end
end
function OnWorldStarted(a_World)
-- Make the chunk [0, 0] in every world keep ticking [cWorld:SetChunkAlwaysTicked() test]
a_World:ChunkStay({{0, 0}}, nil,
function()
-- The chunk is loaded, make it always tick:
a_World:SetChunkAlwaysTicked(0, 0, true)
end
)
end

View File

@ -22,6 +22,8 @@ function Initialize(Plugin)
Plugin:SetVersion(1);
cPluginManager.AddHook(cPluginManager.HOOK_PLAYER_USED_ITEM, OnPlayerUsedItem);
LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion());
return true;
end
@ -36,8 +38,8 @@ function OnPlayerUsedItem(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, Cu
return false;
end;
if (Player:HasPermission("diamondmover.move") == false) then
return true;
if (not Player:HasPermission("diamondmover.move")) then
return false;
end;
-- Rclk with a diamond to push in the direction the player is facing
@ -56,7 +58,7 @@ function OnPlayerUsedItem(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, Cu
if (PlayerPitch > 70) then -- looking down
BlockY = BlockY - 1;
else
local PlayerRot = Player:GetRotation() + 180; -- Convert [-180, 180] into [0, 360] for simpler conditions
local PlayerRot = Player:GetYaw() + 180; -- Convert [-180, 180] into [0, 360] for simpler conditions
if ((PlayerRot < 45) or (PlayerRot > 315)) then
BlockZ = BlockZ - 1;
else

View File

@ -6,7 +6,7 @@ function GetHandyVersion()
return HANDY_VERSION
end
-- Checks if handy is in proper version
function CheckForRequiedVersion( inVersion )
function CheckForRequiredVersion( inVersion )
if( inVersion > HANDY_VERSION ) then return false end
return true
end
@ -213,4 +213,4 @@ end
function BoolToString( inValue )
if( inValue == true ) then return 1 end
return 0
end
end

View File

@ -61,18 +61,31 @@
#--------------------------
# Fuels
! 263:1 = 1600 # 1 Coal -> 80 sec
! 263:1:1 = 1600 # 1 Charcoal -> 80 sec
! 42:126:1 = 150 # 1 Halfslab -> 7.5 seconds
! 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 = 200000 # 1 Lava Bucket -> 1000 sec
! 17:1 = 300 # 1 Wood -> 15 sec
! 6:1 = 100 # 1 Sapling -> 5 sec
! 173:1 = 7400 # 1 Coal Block -> 370 sec, based on https://github.com/minetest/common/commit/e0f5a6fd6936052756e27a05a2bfdd6aa86b38e1 which is a clone of MC
! 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

Binary file not shown.

View File

@ -0,0 +1,11 @@
echo This script generates the certificate and private key for the https webadmin
echo Note that the generated certificate is self-signed, and therefore not trusted by browsers
echo Note that this script requires openssl to be installed and in PATH
echo.
echo When OpenSSL asks you for Common Name, you need to enter the fully qualified domain name of the server, that is, e. g. gallery.xoft.cz
echo.
echo If OpenSSL fails with an error, "WARNING: can't open config file: /usr/local/ssl/openssl.cnf", you need to run this script as an administrator
echo.
openssl req -x509 -newkey rsa:2048 -keyout httpskey.pem -out httpscert.crt -days 3650 -nodes
pause

View File

@ -0,0 +1,10 @@
#!/bin/bash
echo "This script generates the certificate and private key for the https webadmin"
echo "Note that the generated certificate is self-signed, and therefore not trusted by browsers"
echo "Note that this script requires openssl to be installed and in PATH"
echo ""
echo "When OpenSSL asks you for Common Name, you need to enter the fully qualified domain name of the server, that is, e. g. gallery.xoft.cz"
echo ""
openssl req -x509 -newkey rsa:2048 -keyout httpskey.pem -out httpscert.crt -days 3650 -nodes

View File

@ -1,38 +1,39 @@
MCServer
MCServer [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) [![Coverity Scan Build Status](https://scan.coverity.com/projects/1930/badge.svg)](https://scan.coverity.com/projects/1930) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74)
========
**Current Protocol Supported:** Minecraft v1.2 -> v1.7
MCServer is a performant C++ Minecraft server designed for use in memory and cpu-limited places, or just to make regular server perform better.
MCServer is a Minecraft server that is written in C++ and designed to be efficient with memory and CPU, as well as having a flexible Lua Plugin API.
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.
Installation
------------
To install MCServer, you can either download the repository and compile it, or download a pre-compiled version.
Normally, you will want to download a pre-compiled version of MCServer from one of the buildservers:
If you've cloned the repository using Git, you need to pull down the submodules (core plugins, some dependencies). This can be achieved with `git submodule init` and then on a regular basis (to keep up to date) `git submodule update`.
* [Linux and Raspberry Pi](http://ci.bearbin.net) (Bearbin's CI Server)
* [Windows](http://mc-server.xoft.cz) (xoft's nightly build service)
If you downloaded a ZIP file of the sources instead, you will need to download PolarSSL, too, from https://github.com/polarssl/polarssl , and unpack it into the `lib/polarssl` folder. You will also need to manually download all the plugins that you want included.
You simply need to download and extract these files before you can use the server.
Compilation instructions are available in the COMPILING file.
Linux builds can be downloaded from [Bearbin's CI Service](http://ci.bearbin.net) and Windows builds from xoft's [nightly build service](http://mc-server.xoft.cz).
After you've extracted the files, simply run the MCServer executable.
If you're a more advanced user, you may want to compile the server yourself for more performance. See the [COMPILING.md](https://github.com/mc-server/MCServer/blob/master/COMPILING.md) file for more details.
Contributing
------------
MCServer is licensed under the Apache license V2, and we welcome anybody to fork and submit a Pull Request back with their changes, and if you want to join as a permanent member we can add you to the team.
Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more details.
Other Stuff
-----------
For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [wiki](http://wiki.mc-server.org/).
For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [Plugin API](http://mc-server.xoft.cz/LuaAPI/).
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)
Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer)
Support Us on Gittip: [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team)
Travis CI: [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer)

View File

@ -1,32 +1,49 @@
macro (add_flags_lnk FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_COVERAGE} ${FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_COVERAGE} ${FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_COVERAGE "${CMAKE_MODULE_LINKER_FLAGS_COVERAGE} ${FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${FLAGS}")
endmacro()
macro(add_flags_cxx FLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} ${FLAGS}")
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE} ${FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}")
endmacro()
macro(set_flags)
# Add coverage processing, if requested:
if (NOT MSVC)
if (CMAKE_BUILD_TYPE STREQUAL "COVERAGE")
message("Including CodeCoverage")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/")
include(CodeCoverage)
endif()
endif()
# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC):
if (NOT MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -D_DEBUG")
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE} -D_DEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
endif()
if(MSVC)
@ -42,9 +59,10 @@ macro(set_flags)
elseif(APPLE)
#on os x clang adds pthread for us but we need to add it for gcc
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
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")
add_flags_cxx("-stdlib=libc++")
add_flags_lnk("-stdlib=libc++")
else()
@ -53,16 +71,21 @@ macro(set_flags)
else()
# Let gcc / clang know that we're compiling a multi-threaded app:
add_flags_cxx("-pthread")
if (UNIX)
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")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
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()
# We use a signed char (fixes #640 on RasPi)
add_flags_cxx("-fsigned-char")
endif()
@ -97,10 +120,12 @@ macro(set_lib_flags)
string(REPLACE "/W3" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "/W3" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
else()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -w")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -w")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -w")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -w")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -w")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -w")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -w")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -w")
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -w")
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE} -w")
endif()
# On Unix we use two dynamic loading libraries dl and ltdl.
@ -118,8 +143,8 @@ endmacro()
macro(enable_profile)
# Declare the flags used for profiling builds:
if (MSVC)
set (CXX_PROFILING "")
set (LNK_PROFILING "/PROFILE")
set (CXX_PROFILING "/Zi")
set (LNK_PROFILING "/PROFILE /DEBUG")
else()
set (CXX_PROFILING "-pg")
set (LNK_PROFILING "-pg")
@ -128,7 +153,7 @@ macro(enable_profile)
# Declare the profiling configurations:
SET(CMAKE_CXX_FLAGS_DEBUGPROFILE
"${CMAKE_CXX_FLAGS_DEBUG} ${PCXX_ROFILING}"
"${CMAKE_CXX_FLAGS_DEBUG} ${CXX_PROFILING}"
CACHE STRING "Flags used by the C++ compiler during profile builds."
FORCE )
SET(CMAKE_C_FLAGS_DEBUGPROFILE
@ -171,36 +196,42 @@ macro(enable_profile)
CMAKE_EXE_LINKER_FLAGS_RELEASEPROFILE
CMAKE_SHARED_LINKER_FLAGS_RELEASEPROFILE )
# The configuration types need to be set after their respective c/cxx/linker flags and before the project directive
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile" CACHE STRING "" FORCE)
if(MSVC)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile" CACHE STRING "" FORCE)
else()
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile;Coverage" CACHE STRING "" FORCE)
endif()
endmacro()
macro(set_exe_flags)
# Remove disabling the maximum warning level:
# clang does not like a command line that reads -Wall -Wextra -w -Wall -Wextra and does not output any warnings
# We do not do that for MSVC since MSVC produces an awful lot of warnings for its own STL headers;
# the important warnings are turned on using #pragma in Globals.h
if (NOT MSVC)
string(REPLACE "-w" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
string(REPLACE "-w" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
string(REPLACE "-w" "" CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE}")
string(REPLACE "-w" "" CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_COVERAGE}")
add_flags_cxx("-Wall -Wextra -Wno-unused-parameter -Wno-error=switch")
# we support non-IEEE 754 fpus so can make no guarentees about error
add_flags_cxx("-ffast-math")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# 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-extra-semi -Wno-error=switch-enum -Wno-documentation")
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")
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-weak-vtables -Wno-switch-enum -Wno-exit-time-destructors")
add_flags_cxx("-Wno-error=extra-semi -Wno-weak-vtables -Wno-switch-enum")
endif()
endif()

View File

@ -1,32 +1,53 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}"
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
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA} = {EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}
{B61007AC-B557-4B67-A765-E468C0C3A821} = {B61007AC-B557-4B67-A765-E468C0C3A821}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\VC2008\zlib.vcproj", "{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}"
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
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.ActiveCfg = Debug|Win32
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Debug|Win32.Build.0 = Debug|Win32
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release profiled|Win32.Build.0 = Release profiled|Win32
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.Release|Win32.ActiveCfg = Release|Win32
{EA9D50FD-937A-4EF5-8C37-5F4175AF4FEA}.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

View File

@ -5,38 +5,7 @@
#include "Globals.h"
#include "BiomeMap.h"
static const int g_BiomePalette[] =
{
// ARGB:
0xff0000ff, /* Ocean */
0xff00cf3f, /* Plains */
0xffffff00, /* Desert */
0xff7f7f7f, /* Extreme Hills */
0xff00cf00, /* Forest */
0xff007f3f, /* Taiga */
0xff3f7f00, /* Swampland */
0xff003fff, /* River */
0xff7f0000, /* Hell */
0xff007fff, /* Sky */
0xff3f3fff, /* Frozen Ocean */
0xff3f3fff, /* Frozen River */
0xff7fffcf, /* Ice Plains */
0xff3fcf7f, /* Ice Mountains */
0xffcf00cf, /* Mushroom Island */
0xff7f00ff, /* Mushroom Island Shore */
0xffffff3f, /* Beach */
0xffcfcf00, /* Desert Hills */
0xff00cf3f, /* Forest Hills */
0xff006f1f, /* Taiga Hills */
0xff7f8f7f, /* Extreme Hills Edge */
0xff004f00, /* Jungle */
0xff003f00, /* Jungle Hills */
} ;
#include "../BiomeVisualiser/BiomeColors.h"
@ -139,7 +108,7 @@ void cBiomeMap::StartNewRegion(int a_RegionX, int a_RegionZ)
unsigned char * BiomeRow = (unsigned char *)m_Biomes + z * 512;
for (int x = 0; x < 512; x++)
{
RowData[x] = g_BiomePalette[BiomeRow[x]];
RowData[x] = g_BiomeColors[BiomeRow[x]];
}
f.Write(RowData, sizeof(RowData));
} // for z

View File

@ -41,7 +41,7 @@ protected:
virtual bool OnDecompressedData(const char * a_DecompressedNBT, int a_DataSize) override { return false; }
virtual bool OnRealCoords(int a_ChunkX, int a_ChunkZ) override { return false; }
virtual bool OnLastUpdate(Int64 a_LastUpdate) override { return false; }
virtual bool OnTerrainPopulated(bool a_Populated) override { return !a_Populated; } // If not populated, we don't want it!
virtual bool OnTerrainPopulated(bool a_Populated) override { return false; } // We don't care about "populated", the biomes are the same
virtual bool OnBiomes(const unsigned char * a_BiomeData) override;
void StartNewRegion(int a_RegionX, int a_RegionZ);

View File

@ -24,6 +24,15 @@
#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)?
@ -40,6 +49,14 @@
// Some portability macros :)
#define stricmp strcasecmp
#define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex)))
#define SIZE_T_FMT "%zu"
#define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
#define SIZE_T_FMT_HEX "%zx"
#define NORETURN __attribute((__noreturn__))
#else
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
@ -194,6 +211,8 @@ typedef unsigned short UInt16;
/// Faster than (int)floorf((float)x / (float)div)
#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) )
#define TOLUA_TEMPLATE_BIND(...)
// Own version of assert() that writes failed assertions to the log for review
#ifdef _DEBUG
#define ASSERT( x ) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), assert(0), 0 ) )
@ -204,6 +223,8 @@ typedef unsigned short UInt16;
// 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 ) )
typedef unsigned char Byte;
@ -227,3 +248,4 @@ public:

View File

@ -109,7 +109,7 @@ bool cSpringStats::OnSectionsFinished(void)
int Base = BaseY + z * 16;
for (int x = 1; x < 15; x++)
{
if (cChunkDef::GetNibble(m_BlockMetas, Base + x) != 0)
if (cChunkDef::GetNibble(m_BlockMetas, x, y, z) != 0)
{
// Not a source block
continue;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="BiomeVisualiser"
ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
RootNamespace="BiomeVisualiser"
@ -327,6 +327,14 @@
<Filter
Name="Shared"
>
<File
RelativePath="..\..\src\BiomeDef.cpp"
>
</File>
<File
RelativePath="..\..\src\BiomeDef.h"
>
</File>
<File
RelativePath="..\..\src\BlockID.cpp"
>
@ -355,6 +363,14 @@
RelativePath="..\..\src\WorldStorage\FastNBT.h"
>
</File>
<File
RelativePath="..\..\src\FastRandom.cpp"
>
</File>
<File
RelativePath="..\..\src\FastRandom.h"
>
</File>
<File
RelativePath="..\..\src\Globals.cpp"
>

View File

@ -22,6 +22,15 @@
#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)?
@ -39,6 +48,12 @@
#define stricmp strcasecmp
#define FORMATSTRING(formatIndex,va_argsIndex)
#define SIZE_T_FMT "%zu"
#define SIZE_T_FMT_PRECISION(x) "%" #x "zu"
#define SIZE_T_FMT_HEX "%zx"
#define NORETURN __attribute((__noreturn__))
#else
#error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler"
@ -225,6 +240,7 @@ template <typename Type> class cItemCallback
public:
/// 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;
virtual ~cItemCallback() {}
} ;

View File

@ -36,14 +36,24 @@ set(SHARED_SRC
../../src/StringUtils.cpp
../../src/Log.cpp
../../src/MCLogger.cpp
../../src/Crypto.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
)
set(SHARED_HDR
../../src/ByteBuffer.h
../../src/StringUtils.h
../../src/Log.h
../../src/MCLogger.h
../../src/Crypto.h
../../src/PolarSSL++/AesCfb128Decryptor.h
../../src/PolarSSL++/AesCfb128Encryptor.h
../../src/PolarSSL++/CryptoKey.h
../../src/PolarSSL++/CtrDrbgContext.h
../../src/PolarSSL++/EntropyContext.h
../../src/PolarSSL++/RsaPrivateKey.h
)
set(SHARED_OSS_SRC
../../src/OSSupport/CriticalSection.cpp

View File

@ -7,6 +7,7 @@
#include "Connection.h"
#include "Server.h"
#include <iostream>
#include "PolarSSL++/CryptoKey.h"
#ifdef _WIN32
#include <direct.h> // For _mkdir()
@ -471,7 +472,7 @@ bool cConnection::SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a
bool cConnection::SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer)
bool cConnection::SendEncryptedData(SOCKET a_Socket, cAesCfb128Encryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer)
{
DataLog(a_Data, a_Size, "Encrypting %d bytes to %s", a_Size, a_Peer);
const Byte * Data = (const Byte *)a_Data;
@ -495,7 +496,7 @@ bool cConnection::SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryp
bool cConnection::SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer)
bool cConnection::SendEncryptedData(SOCKET a_Socket, cAesCfb128Encryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer)
{
AString All;
a_Data.ReadAll(All);
@ -2899,7 +2900,7 @@ void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, c
Byte SharedSecret[16];
Byte EncryptedSecret[128];
memset(SharedSecret, 0, sizeof(SharedSecret)); // Use all zeroes for the initial secret
cPublicKey PubKey(a_ServerPublicKey);
cCryptoKey PubKey(a_ServerPublicKey);
int res = PubKey.Encrypt(SharedSecret, sizeof(SharedSecret), EncryptedSecret, sizeof(EncryptedSecret));
if (res < 0)
{

View File

@ -11,6 +11,8 @@
#include "ByteBuffer.h"
#include "OSSupport/Timer.h"
#include "PolarSSL++/AesCfb128Decryptor.h"
#include "PolarSSL++/AesCfb128Encryptor.h"
@ -66,8 +68,8 @@ protected:
cByteBuffer m_ClientBuffer;
cByteBuffer m_ServerBuffer;
cAESCFBDecryptor m_ServerDecryptor;
cAESCFBEncryptor m_ServerEncryptor;
cAesCfb128Decryptor m_ServerDecryptor;
cAesCfb128Encryptor m_ServerEncryptor;
AString m_ServerEncryptionBuffer; // Buffer for the data to be sent to the server once encryption is established
@ -109,10 +111,10 @@ protected:
bool SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a_Peer);
/// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false
bool SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer);
bool SendEncryptedData(SOCKET a_Socket, cAesCfb128Encryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer);
/// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false
bool SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer);
bool SendEncryptedData(SOCKET a_Socket, cAesCfb128Encryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer);
/// Decodes packets coming from the client, sends appropriate counterparts to the server; returns false if the connection is to be dropped
bool DecodeClientsPackets(const char * a_Data, int a_Size);

View File

@ -216,6 +216,20 @@ typedef unsigned char Byte;
// 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 ) )
// 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
@ -232,12 +246,6 @@ public:
#include "../../src/Crypto.h"
#define LOGERROR printf
#define LOGINFO printf
#define LOGWARNING printf

View File

@ -20,7 +20,7 @@ You need to set the server *not* to verify usernames ("online-mode=false" in ser
ProtoProxy is not much dependent on the protocol - it will work with unknown packets, it just won't parse them into human-readable format.
The latest protocol which has been tested is 1.6.1 (#73).
The latest protocol which has been tested is 1.7.9 (#5).
*/

View File

@ -9,6 +9,8 @@
#pragma once
#include "PolarSSL++/RsaPrivateKey.h"
@ -17,7 +19,7 @@
class cServer
{
SOCKET m_ListenSocket;
cRSAPrivateKey m_PrivateKey;
cRsaPrivateKey m_PrivateKey;
AString m_PublicKeyDER;
short m_ConnectPort;
@ -27,7 +29,7 @@ public:
int Init(short a_ListenPort, short a_ConnectPort);
void Run(void);
cRSAPrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
cRsaPrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
const AString & GetPublicKeyDER (void) { return m_PublicKeyDER; }
short GetConnectPort(void) const { return m_ConnectPort; }

529
docs/Generator.html Normal file
View File

@ -0,0 +1,529 @@
<html>
<head>
<title>Generating terrain in MCServer</title>
</head>
<body>
<h1>Generating terrain in MCServer</h1>
<p>This article explains the principles behind the terrain generator in MCServer. It is not strictly
specific to MCServer, though, it can be viewed as a generic guide to various terrain-generating algorithms,
with specific implementation notes regarding MCServer.</p>
<p>Contents:
<ul>
<li><a href="#preface">Preface: How it's done in real life</a></li>
<li><a href="#expectedprops">Expected properties</a></li>
<li><a href="#reversingflow">Reversing the flow</a></li>
<li><a href="#composablegen">The ComposableGenerator pipeline</a></li>
<li><a href="#coherentnoise">Using coherent noise</a></li>
<li><a href="#biomegen">Generating biomes</a></li>
<li><a href="#heightgen">Terrain height</a></li>
<li><a href="#compositiongen">Terrain composition</a></li>
<li><a href="#finishgen">Finishers</a></li>
<li><a href="#makefaster">Making it all faster</a></li>
<li><a href="#GPU">Executing on a GPU</a></li>
</ul>
</p>
<hr />
<a name="preface"><h2>Preface: How it's done in real life</h2></a>
<p>The nature has many complicated geological, physical and biological processes working on all scales from
microscopic to planet-wide scale, that have shaped the terrain into what we see today. The tectonic plates
collide, push mountain ranges up and ocean trenches down. Erosion dulls the sharp shapes. Plantlife takes
over to further change the overall look of the world.</p>
<p>Generally speaking, the processes take what's there and change it. Unlike computer generating, which
usually creates a finished terrain from scratch, or maybe with only a few iterations. It would be unfeasible
for software to emulate all the natural processes in enough detail to provide world generation for a game,
mainly because in the nature everything interacts with everything. If a mountain range rises, it changes the
way that the precipitation is carried by the wind to the lands beyond the mountains, thus changing the
erosion rate there and the vegetation type. </p>
<hr />
<a name="expectedprops"><h2>Expected properties</h2></a>
<p>For a MineCraft-like game terrain generator we need the generator to have several properties:
<ul>
<li>The generator must be able to generate terrain in small chunks. This means it must be possible to
generate each of the chunks separately, without dependencies on the neighboring chunks. Note that this
doesn't mean chunks cannot coordinate together, it means that "a tree in one chunk cannot ask if there's
a building in the neighbor chunk", simply because the neighbor chunk may not be generated yet.</li>
<li>The generated chunk needs to be the same if re-generated. This property is not exactly required, but it
makes available several techniques that wouldn't be possible otherwise.</li>
<li>The generator needs to be reasonably fast. For a server application this means at least some 20 chunks
per second for chunks close to each other, and 5 chunks per second for distant chunks. The reason for this
distinction will be discussed later.</li>
</ul>
</p>
<hr />
<a name="reversingflow"><h2>Reversing the flow</h2></a>
<p>As already mentioned, the nature works basically by generating raw terrain composition, then "applying"
erosion, vegetation and finally this leads to biomes being formed. Let's now try a somewhat inverse
approach: First generate biomes, then fit them with appropriate terrain, and finally cover in vegetation
and all the other stuff.</p>
<p>Splitting the parts like this suddenly makes it possible to create a generator with the required
properties. We can generate a reasonable biome map chunk-wise, independently of all the other data. Once we
have the biomes, we can compose the terrain for the chunk by using the biome data for the chunk, and
possibly even for neighboring chunks. Note that we're not breaking the first property, the biomes can be
generated separately so a neighboring chunk's biome map can be generated without the need for the entire
neighboring chunk to be present. Similarly, once we have the terrain composition for a chunk, we can
generate all the vegetation and structures in it, and those can again use the terrain composition in
neighboring chunks.</p>
<hr />
<a name="composablegen"><h2>The ComposableGenerator pipeline</h2></a>
<p>This leads us directly to the main pipeline that is used for generating terrain in MCServer. For
technical reasons, the terrain composition step is further subdivided into Height generation and Composition
generation, and the structures are really called Finishers. For each chunk the generator generates, in this
sequence:
<ul>
<li>Biomes</li>
<li>Terrain height</li>
<li>Terrain composition</li>
<li>Finishers</li>
</ul>
</p>
<img src="img/biomes.jpg" />
<img src="img/terrainheight.jpg" />
<img src="img/terraincomposition.jpg" />
<img src="img/finishers.jpg" />
<p>The beautiful thing about this is that the individual components can be changed independently. You can
have 5 biome generators and 3 height generators and you can let the users mix'n'match.
</p>
<hr />
<a name="coherentnoise"><h2>Using coherent noise for the generation</h2></a>
<p>For a great tutorial on coherent noise, see the <a href="http://libnoise.sourceforge.net/">LibNoise
documentation</a>.</p>
<p>Coherent noise is a type of noise that has three important properties that we can use to our advantage:
<ul>
<li>The noise is smooth</li>
<li>The noise is algorithmically generated, which means that the same data is generated when the same
parameters are given to the noise functions.</li>
<li>The noise can be seamlessly extended in any direction</li>
</ul></p>
<p>We'll be mostly using Perlin noise in this article. It is the easiest one to visualise and use and is one
of the most useful kinds of coherent noises. Here's an example of a Perlin noise generated in 2 dimensions:</p>
<img src="img/perlin.jpg" />
<p>It comes only naturally that such a 2D noise can be used as a terrain height map directly:</p>
<img src="img/perlinheightmap.jpg" />
<p>However, this is not the only use for this noise, and 2 dimensions is not the limit - this noise can be
generated for any number of dimensions.</p>
<hr />
<a name="biomegen"><h2>Generating biomes</h2></a>
<p>The easiest way to generate biomes is to not generate them at all - simply assign a single constant biome
to everywhere. And indeed there are times when this kind of "generator" is useful - for the MineCraft's Flat
world type, or for testing purposes, or for tematic maps. In MCServer, this is exactly what the Constant
biome generator does.</p>
<p>Of course, there are more interesting test scenarios for which multiple biomes must be generated as easy
as possible. For these special needs, there's a CheckerBoard biome generator. As the name suggests, it
generates a grid of alternating biomes.</p>
<h3>Voronoi diagram</h3>
<p>Those two generators were more of a technicality, we need to make something more interesting if we're
going for a natural look. The Voronoi generator is the first step towards such a change. Recall that a
<a href="http://en.wikipedia.org/wiki/Voronoi_diagram">Voronoi diagram</a> is a construct that creates a
set of areas where each point in an area is closer to the appropriate seed of the area than the seeds of any
other area:</p>
<img src="img/voronoi.png" />
<p>To generate biomes using this approach, you select random "seeds", assign a biome to each one, and then
for each "column" of the world you find the seed that is the nearest to that column, and use that seed's
biome.</p>
<p>The overall shape of a Voronoi diagram is governed by the placement of the seeds. In extreme cases, a
seed could affect the entire diagram, which is what we don't want - we need our locality, so that we can
generate a chunk's worth of biome data. We also don't want the too much irregular diagrams that are produced
when the seeds are in small clusters. We need our seeds to come in random, yet somewhat uniform fashion.</p>
<p>Luckily, we have just the tool: Grid with jitter. Originally used in antialiasing techniques, they can be
successfully applied as a source of the seeds for a Voronoi diagram. Simply take a regular 2D grid of seeds
with the grid distance being N, and move each seed along the X and Y axis by a random distance, usually in
the range [-N / 2, +N / 2]:</p>
<img src="img/jittergrid.jpg" />
<p>Such a grid is the ideal seed source for a Voronoi biome generator, because not
only are the Voronoi cells "reasonable", but the seed placement's effect on the diagram is localized - each
pixel in the diagram depends on at most 4 x 4 seeds around it. In the following picture, the seed for the
requested point (blue) must be within the indicated circle. Even the second-nearest seed, which we will need
later, is inside that circle.</p>
<img src="img/jittergridlocality.jpg" />
<p>Calculating the jitter for each cell can be done easily by using a 2D Perlin noise for each coord. We
calculate the noise's value at [X, Z], which gives us a number in the range [-1; 1]. We then multiply the
number by N / 2, this gives us the required range of [-N / 2, +N / 2]. Adding this number to the X coord
gives us the seed's X position. We use another Perlin noise and the same calculation for the Z coord of the
seed.</p>
<p>Here's an example of a biome map generated using the Voronoi + jitter grid, as implemented by the Voronoi
biome generator in MCServer:</p>
<img src="img/voronoijitterbiomes.png" />
<h3>Distorted Voronoi</h3>
<p>The biomes are starting to look interesting, but now they have straight-line borders, which looks rather
weird and the players will most likely notice very soon. We need to somehow distort the borders to make them
look more natural. By far the easiest way to achieve that is to use a little trick: When the generator is
asked for the biome at column [X, Z], instead of calculating the Voronoi biome for column [X, Z], we first
calculate a random offset for each coord, and add it to the coordinates. So the generator actually responds
with the biome for [X + rndX, Z + rndZ].</p>
<p>In order to keep the property that generating for the second time gives us the same result, we need the
"random offset" to be replicatable - same output for the same input. This is where we use yet another Perlin
noise - just like with the jitter for the Voronoi grid, we add a value from a separate noise to each
coordinate before sending the coordinates down to the Voronoi generator:</p>
<code>
DistortedVoronoiBiome(X, Z) := VoronoiBiome(X + PerlinX(X, Z), Z + PerlinZ(X, Z))
</code>
<p>The following image shows the effects of the change, as generated by MCServer's DistortedVoronoi biome
generator. It is actually using the very same Voronoi map as the previous image, the only change has been
the addition of the distortion:</p>
<img src="img/distortedvoronoibiomes.png" />
<p>As you can see, this already looks reasonable enough, it could be considered natural biomes, if it
weren't for several drawbacks:
<ul>
<li>There's no way to limit the neighbors. A desert biome can neighbor a tundra biome. </li>
<li>All the biomes are considered equal. There's no way to make oceans larger. A mushroom biome is
generated right next to other land biomes.</li>
</ul></p>
<h3>Adding relativity</h3>
<p>Our next goal is to remove the first defect of the distorted Voronoi generator: unrelated biomes
generating next to each other. It is highly unlikely to find a jungle biome next to a desert biome, so we
want to have as few of those borders as possible. We could further improve on the selection of
biome-to-seed in the Voronoi generator. Or we can try a completely different idea altogether.</p>
<p>Recall how we talked about the nature, where the biomes are formed by the specific conditions of a place.
What if we could make a similar dependency, but without the terrain? It turns out this is possible rather
easily - instead of depending on the terrain, we choose two completely artificial measures. Let's call them
Temperature and Humidity. If we knew the temperature of the place, we know what set of biomes are possible
for such temperatures - we won't place deserts in the cold and tundra in the hot anymore. Similarly, the
humidity will help us sort out the desert vs jungle issue. But how do we get a temperature and humidity?
Once again, the Perlin noise comes to the rescue. We can use a simple 2D Perlin noise as the temperature
map, and another one as the humidity map.</p>
<p>What we need next is a decision of what biome to generate in certain temperature and humidity
combinations. The fastest way for a computer is to have a 2D array, where the temperature is one dimension
and humidity the other, and the values in the array specify the biome to generate:</p>
<img src="img/temperaturehumiditydecisionsimple.jpg" />
<p>We can even "misuse" the above diagram to include the hill variants of the biomes and have those hills
neighbor each other properly, simply by declaring some of the decision diagram's parts as hills:</p>
<img src="img/temperaturehumiditydecisionhills.jpg" />
<p>The problem with this approach is that there are biomes that should not depend on temperature or
humidity, they generate across all of their values. Biomes like Oceans, Rivers and Mushroom. We could
either add them somewhere into the decision diagram, or we can make the generator use a multi-step decision:
<ul>
<li>Decide whether the point is in the ocean, land or mushroom</li>
<li>If it's land, decide if it's real land or river.</li>
<li>If it's real land, use a TemperatureHumidity approach to generate land-biomes</li>
</ul>
</p>
<p>This is the approach implemented in MCServer's MultiStepMap biome generator. It generates biome maps like
this:</p>
<img src="img/multistepmapbiomes.png" />
<p>To decide whether the point is in the ocean, land or mushroom, the generator first chooses seeds in a grid
that will be later fed to a DistortedVoronoi algorithm, the seeds get the "ocean" and "land" values. Then it
considers all the "ocean" seeds that are surrounded by 8 other "ocean" seeds and turns a random few of them
into "mushroom". This special seed processing makes the mushroom biomes mostly surrounded by ocean. The
following image shows an example seeds grid that the generator might consider, only the two framed cells are
allowed to change into mushroom. L = land, O = ocean:</p>
<img src="img/multistepmapgrid.jpg" />
<p>Next, the generator calculates the DistortedVoronoi for the seeds. For the areas that are calculated as
mushroom, the distance to the nearest-seed is used to further shrink the mushroom biome and then to
distinguish between mushroom and mushroom-shore (image depicts a Voronoi cell for illustration purposes, it
works similarly with DistortedVoronoi). O = ocean, M = mushroom, MS = mushroom shore:</p>
<img src="img/multistepmapdistance.jpg" />
<a name="perlinrivers">
<p>The rivers are added only to the areas that have been previously marked as land. A simple 2D Perlin noise
is used as the base, where its value is between 0 and a configured threshold value, a river is created. This
creates the rivers in a closed-loop-like shapes, occasionally splitting two branches off:</p>
<img src="img/perlinrivers1.jpg" />
<img src="img/perlinrivers2.jpg" />
<img src="img/perlinrivers3.jpg" />
</a>
<p>For the leftover land biomes, the two Perlin noises, representing temperature and humidity, are used to
generate the biomes, as described earlier. Additionally, the temperature map is used to turn the Ocean biome
into FrozenOcean, and the River biome into FrozenRiver, wherever the temperature drops below a threshold.</p>
<h3>Two-level Voronoi</h3>
<p>The 1.7 MineCraft update brought a completely new terrain generation, which has sparked renewed interest
in the biome generation. A new, potentially simpler way of generating biomes was found, the two-level
DistortedVoronoi generator.</p>
<p>The main idea behind it all is that we create large areas of similar biomes. There are several groups of
related biomes that can be generated near each other: Desert biomes, Ice biomes, Forest biomes, Mesa biomes.
Technically, the Ocean biomes were added as yet another group, so that the oceans will generate in
approximately the size of the larger areas, too.</p>
<p>For each column a DistortedVoronoi is used to select, which large area to use. This in turn results in
the list of biomes from which to choose. Another DistortedVoronoi, this time with a smaller grid size, is
used to select one biome out of that list. Additionally, the smaller DistortedVoronoi calculates not only
the nearest seed's distance, but also the distance to the second-nearest seed; the ratio between these two
is used as an indicator whether the column is in the "inside" or on the "outskirt" of the smaller Voronoi
cell. This allows us to give certain biomes an "edge" biome - the Mushroom biome has a MushroomShore edge,
the ExtremeHills biome have an ExtremeHillsEdge biome on the edge, etc.</p>
<p>The images below illustrate the process with regular Voronoi diagrams, for clarity purposes. The real
generator uses distortion before querying the small areas.</p>
<img src="img/twolevellargeareas.jpg" /><br />
<img src="img/twolevelsmallgrid.jpg" /><br />
<img src="img/twolevelsmallareas.jpg" /><br />
<p>The following image shows an example output of a TwoLevel biome generator in MCServer:</p>
<img src="img/twolevelbiomes.png" />
<p>Note that rivers are currently not implemented in this generator in MCServer, but they could be added
using the same approach as in MultiStepMap - by using a thresholded 2D Perlin noise.</p>
<hr />
<a name="heightgen"><h2>Terrain height</h2></a>
<p>As with biomes, the easiest way to generate terrain height is not generating at all - assigning a constant
height value to all columns. This is again useful either for internal tests, and for worlds like MineCraft's
Flat world.</p>
<p>For a somewhat more realistic landscape, we will employ the good old 2D Perlin noise. We can use it
directly as a heightmap - each value we get from the noise is stretched into the desired range (usually from
40 to 120 blocks for regular MineCraft worlds) and used as the height value. However, this doesn't play too
well with the biomes we've just generated. If the biome says "ocean" and the Perlin noise says "mountain",
the end result will be unpleasant.</p>
<p>So we want a height generator that is biome-aware. The easiest way of doing this is to have a separate
generator for each biome. Simply use the biome map to select which generator to use, then ask the appropriate
generator for the height value. Again, this doesn't work too well - imagine an ExtremeHills biome right next
to an Ocean biome. If no extra care is taken, the border between these two will be a high wall. The following
image shows a 2D representation (for simplification purposes) of the problem:</p>
<img src="img/biomeheights.jpg" />
<p>This requires some further processing. What we need is for the terrain height to be dependent not only on
the immediate biome for that column, but also on the close surroundings of the column. This is exactly the
kind of task that averaging is designed for. If we take the area of 9x9 biomes centered around the queried
column, generate height for each of the biomes therein, sum them up and divide by 81 (the number of biomes
summed), we will be effectively making a 9-long running average over the terrain, and all the borders will
suddenly become smooth. The following image shows the situation from the previous paragraph after applying
the averaging process: </p>
<img src="img/biomeheightsavg.jpg" />
<p>The approach used in MCServer's Biomal generator is based on this idea, with two slight modifications.
Instead of using a separate generator for each biome, one generator is used with a different set of input
parameters for each biomes. These input parameters modify the overall amplitude and frequency of the Perlin
noise that the generator produces, thus modifying the final terrain with regards to biomes. Additionally, the
averaging process is weighted - columns closer to the queried column get a more powerful weight in the sum
than the columns further away. The following image shows the output of MCServer's Biomal terrain height
generator (each block type represents a different biome - ocean in the front (stone), plains and ice plains
behind it (lapis, whitewool), extreme hills back right (soulsand), desert hills back left (mossy
cobble)):</p>
<a name="biomalheights"><img src="img/biomalheights.jpg" /></a>
<p>One key observation about this whole approach is that in order for it to work, the biomes must be
available for columns outside the currently generated chunk, otherwise the columns at the chunk's edge would
not be able to properly average their height. This requirement can be fulfilled only by biome generators that
adhere to the second <a href="#expectedproperties">Expected property</a> - that re-generating will produce
the same data. If the biome generator returned different data for the same chunk each time it was invoked, it
would become impossible to apply the averaging.</p>
<p>(TODO: height with variations (N/A in MCS yet)</p>
<hr />
<a name="compositiongen"><h2>Terrain composition</h2></a>
<p>As with the other generators, the composition generator category has its easy and debugging items, too.
There's the "special" composition of "all the blocks are the same type", which fills the entire column, from
the bottom to the height, with a single blocktype. This generator is useful when testing the generators in
the other categories, to speed up the generation by leaving out unnecessary calculations. Another special
compositor is a similar one, that fills all blocks with the same type, but the type varies for each biome.
This way it's easy to see the generated biomes and possibly the heights for those biomes, as shown in the
previous section on the <a href="#biomalheights">height averaging screenshot</a>.</p>
<p>For a natural look, we need to put together a more complicated algorithm. The standard set forth in
MineCraft is that the top of the world is covered in grass, then there are a few blocks of dirt and finally
stone. This basic layout is then varied for different biomes - deserts have sand and sandstone instead of the
grass and dirt layer. Mushroom biomes have mycelium in place of the grass. This per-biome dependency is
trivial to implement - when compositing, simply use the appropriate layout for the column's biome.</p>
<p>The next change concerns oceans. The generated heightmap doesn't include any waterlevel indication
whatsoever. So it's up to the terrain compositor to actually decide where to place water. We do this by
configuration - simply have a value in the config file specifying the sealevel height. The compositor then
has to add water above any column which has a height lower than that. Additionally, the water needs to
override per-biome layout selection - we don't want grass blocks to generate under water when the terrain
height in the plains biome drops below the sealevel accidentally.</p>
<p>The final feature in the compositor is the decision between multiple composition layouts within a single
biome. A megataiga biome contains patches of non-grass dirt and podzol blocks, and the ocean floor can be
made of dirt, gravel, sand or clay. A simple 2D Perlin noise can be used to select the layout to use for a
specific column - simply threshold the noise's value by as many thresholds as there are layout variations,
and use the layout corresponding to the threshold:</p>
<img src="img/perlincompositor1.jpg" />
<img src="img/perlincompositor2.jpg" />
<img src="img/perlincompositor3.jpg" />
<h3>Nether composition</h3>
<p>So far we've been discussing only the Overworld generator. But MineCraft contains more than that. The
Nether has a completely different look and feel, and quite different processes are required to generate that.
Recall that MineCraft's Nether is 128 blocks high, with bedrock both at the top and the bottom. Between these
two, the terrain looks more like a cavern than a surface. Not surprisingly, the Nether doesn't need a
complicated height generator, it can use the flat height. However, the terrain composition must take an
altogether different approach.</p>
<p>The very first idea is to use the Perlin noise, but generate it in 3D, rather than 2D. Then, for each
block, evaluate the noise value, if below 0, make it air, if not, make it netherrack.
<p>To make it so that the bedrock at the top and at the bottom is never revealed, we can add a value
increasing the more the Y coord gets towards the bottom or the top. This way the thresholding then guarantees
that there will be no air anywhere near the bedrock.</p>
<p>(TODO)</p>
<hr />
<a name="finishgen"><h2>Finishers</h2></a>
<p>Finishers are a vast category of various additions to the terrain generator. They range from very easy
ones, such as generating snow on top of the terrain in cold biomes, through medium ones, such as growing
patches of flowers, complicated ones, such as placing trees and generating caves, all the way to very
complicated ones such as villages and nether fortresses. There is no formal distinction between all these
"categories", the only thing they have in common is that they take a chunk of blocks and modify it in some
way.</p>
<h3>Snow</h3>
<p>Snow is probably the easiest of the finishers. It generates a block of snow on top of each block that is
on top of the terrain and is not marked as non-snowable. It checks the chunk's heightmap to determine the top
block, then checks whether the block supports snow on its top. Rails, levers and tall grass don't support
snow, for example.</p>
<h3>Ice</h3>
<p>Another example of an easy finisher. This scans through the world and turn each water block on the surface
into an ice block if the biome is cold. This means that any water block that is under any kind of other
block, such as under a tree's leaves, will still stay water. Thus an additional improvement could be made by
scanning down from the surface block through blocks that we deem as non-surface, such as leaves, torches,
ladders, fences etc. Note that MCServer currently implements only the easy solution.</p>
<h3>Bottom lava</h3>
<p>Most worlds in MineCraft have lava lakes at their bottom. Generating these is pretty straightforward: Use
the user-configured depth and replace all the air blocks below this depth with lava blocks. Note however,
that this makes this generator dependent on the order in which the finishers are applied. If the mineshafts
generate before bottom lava, the mineshafts that are below the lava level will get filled with lava. On the
other hand, if bottom lava is generated before the mineshafts, it is possible for a mineshaft to "drill
through" a lake of lava. MCServer doesn't try to solve this and instead lets the admin choose whichever they
prefer.</p>
<h3>Specific foliage</h3>
<p>There are generators for specific kinds of foliage. The dead bushes in the desert biome and lilypads in
the swamp biome both share the same generating pattern. They are both specific to a single biome and they
both require a specific block underneath them in order to generate. Their implementation is simple: pick
several random columns in the chunk. If the column is of the correct biome and has the correct top block,
add the foliage block on top.</p>
<p>In order to generate the same set of coordinates when the chunk is re-generated, we use the Perlin noise's
basis functions (the ones providing the random values for Perlin cell vertices). These basically work as a
hash function for the coorinates - the same input coordinates generate the same output value. We use the
chunk's coordinates as two of the coords, and the iteration number as the third coordinate, to generate a
random number. We then check the biome and the top block at those coordinates, if they allow, we generate the
foliage block on top.</p>
<p>Another example of specific foliage is the tall grass in the plains biome. There are quite a lot of these
tall grass blocks, it would be inefficient to generate them using the random-coords approach described above.
Instead, we will use a 2D Perlin noise again, with a threshold defining where to put the grass and where
not.</p>
<h3>Small foliage</h3>
<p>For the flowers, grass, mushrooms in caves etc. we want to use a slightly different algorithm. These
foliage blocks are customarily generated in small "clumps" - there are several blocks of the same type near
together. To generate these, we first select random coords, using the coord hash functions, for a center of a
clump. Then we select the type of block to generate. Finally, we loop over adding a random (coord hash)
number to the clump center coords to get the block where to generate the foliage block:</p>
<img src="img/smallfoliageclumps.jpg" />
<p>In order to make the clump more "round" and "centered", we want the offsets to be closer to the clump
center more often. This is done using a thing called Gaussian function distribution. Instead of having each
random number generate with the same probability, we want higher probability for the numbers around zero,
like this:</p>
<img src="img/gaussprobability.jpg" />
<p>Instead of doing complicated calculations to match this shape exactly, we will use a much easier shape.
By adding together two random numbers in the same range, we get the probability distribution that has a
"roof" shape, enough for our needs:</p>
<img src="img/roofprobability.jpg" />
<p>(For the curious, there is a proof that adding together infinitely many uniform-distributed random numbers
produces random numbers with the Gaussian distribution.)</p>
<p>This scheme can be used to produce clumps of flowers, when we select the 2D coords of the clump center on
the top surface of the terrain. We simply generate the 2D coords of the foliage blocks and use the terrain
height to find the third coord. If we want to generate clumps of mushrooms in the caves, however, we need to
generate the clump center coords in 3D and either use 3 offsets for the mushrooms, or use 2 offsets plus
searching for the closest opening Y-wise in the terrain.</p>
<p>Note that the clumps generated by this scheme may overlap several chunks. Therefore it's crucial to
actually check the surrounding chunks if their clumps overlap into the currently generated chunk, and apply
those as well, otherwise there will be visible cuts in the foliage along the chunks borders.</p>
<h3>Springs</h3>
<p>Water and lava springs are essential for making the underground quite a lot more interesting. They are
rather easy to generate, but a bit more difficult to get right. Generating simply means that a few random
locations (obtained by our familiar coord hashing) are checked and if the block type in there is stone. Then
we see all the horizontal neighbors of the block, plus the block underneath. If all of them except one are
stone, and the one left is air, our block is suitable for turning into a spring. If there were more air
neighbors, the spring would look somewhat unnatural; if there were no air neighbors, the spring won't flow
anywhere, so it would be rather useless.</p>
<p>The difficult part about springs is the amount of them to generate. There should be a few springs on the
surface, perhaps a bit more in the mountaineous biomes. There should be quite a few more springs underground,
but there should definitely be more water springs than lava springs in the upper levels of the terrain, while
there should be more lava springs and almost no water springs near the bottom. To accomodate this, the
MCServer team has made a tool that scanned through MineCraft's terrain and counted the amount of both types
of springs in relation to their height. Two curves have been found for the distribution of each type of the
spring:</p>
<img src="http://mc-server.xoft.cz/img/vanilla_springs_huge.png" />
<p>MCServer uses an approximation of the above curves to choose the height at which to generate the
spring.</p>
<!--
<h3>Caves</h3>
<p>Caves are definitely one of the main things people notice about MineCraft terrain. There are quite a lot
of different algorithms available to generate terrain with caves.
-->
<hr />
<a name="makefaster"><h2>Making it all faster</h2></a>
<p>(TODO)</p>
<a name="GPU"><h2>Executing on a GPU</h2></a>
<p>Much of the terain generation consists of doing the same thing for every single column or block in a chunk. This
sort of computation is much faster on a GPU as GPUs are massively parallel. High end GPUs can execute up to 30,000
threads simultaneously, which would allow them to generate every block in half a chunk in parallel or every column
in over 100 chunks in parallel. A naive comparison suggests that a 800MHz GPU with 15,000 threads can execute parallel
code 250 times faster than a 3GHz CPU with 128 bit SIMD. Obviously we want to harness that power.</p>
</body>
</html>

BIN
docs/img/biomalheights.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
docs/img/biomeheights.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/img/biomes.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
docs/img/finishers.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/img/jittergrid.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/img/perlin.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
docs/img/perlinrivers1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/img/perlinrivers2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/img/perlinrivers3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/img/terrainheight.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/img/twolevelbiomes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
docs/img/voronoi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,160 @@
#
# 2012-01-31, Lars Bilke
# - Enable Code Coverage
#
# 2013-09-17, Joakim Söderberg
# - Added support for Clang.
# - Some additional usage instructions.
#
# USAGE:
# 1. Copy this file into your cmake modules path.
#
# 2. Add the following line to your CMakeLists.txt:
# INCLUDE(CodeCoverage)
#
# 3. Set compiler flags to turn off optimization and enable coverage:
# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
#
# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target
# which runs your test executable and produces a lcov code coverage report:
# Example:
# SETUP_TARGET_FOR_COVERAGE(
# my_coverage_target # Name for custom target.
# test_driver # Name of the test driver executable that runs the tests.
# # NOTE! This should always have a ZERO as exit code
# # otherwise the coverage generation will not complete.
# coverage # Name of output directory.
# )
#
# 4. Build a Debug build:
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# make
# make my_coverage_target
#
#
# Check prereqs
FIND_PROGRAM( GCOV_PATH gcov )
FIND_PROGRAM( LCOV_PATH lcov )
FIND_PROGRAM( GENHTML_PATH genhtml )
FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests)
IF(NOT GCOV_PATH)
MESSAGE(FATAL_ERROR "gcov not found! Aborting...")
ENDIF() # NOT GCOV_PATH
IF(NOT CMAKE_COMPILER_IS_GNUCXX)
# Clang version 3.0.0 and greater now supports gcov as well.
MESSAGE(WARNING "Compiler is not GNU gcc! Clang Version 3.0.0 and greater supports gcov as well, but older versions don't.")
IF(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
ENDIF()
ENDIF() # NOT CMAKE_COMPILER_IS_GNUCXX
SET(CMAKE_CXX_FLAGS_COVERAGE
"-g -O0 --coverage -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C++ compiler during coverage builds."
FORCE )
SET(CMAKE_C_FLAGS_COVERAGE
"-g -O0 --coverage -fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C compiler during coverage builds."
FORCE )
SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used for linking binaries during coverage builds."
FORCE )
SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
FORCE )
MARK_AS_ADVANCED(
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
IF ( NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Coverage"))
MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" )
ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
# Param _targetname The name of new the custom make target
# Param _testrunner The name of the target which runs the tests.
# MUST return ZERO always, even on errors.
# If not, no coverage report will be created!
# Param _outputname lcov output is generated as _outputname.info
# HTML report is generated in _outputname/index.html
# Optional fourth parameter is passed as arguments to _testrunner
# Pass them in list form, e.g.: "-j;2" for -j 2
FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname)
IF(NOT LCOV_PATH)
MESSAGE(FATAL_ERROR "lcov not found! Aborting...")
ENDIF() # NOT LCOV_PATH
IF(NOT GENHTML_PATH)
MESSAGE(FATAL_ERROR "genhtml not found! Aborting...")
ENDIF() # NOT GENHTML_PATH
# Setup target
ADD_CUSTOM_TARGET(${_targetname}
# Cleanup lcov
${LCOV_PATH} --directory . --zerocounters
# Run tests
COMMAND ${_testrunner} ${ARGV3}
# Capturing lcov counters and generating report
COMMAND ${LCOV_PATH} --directory . --capture --output-file ${_outputname}.info
COMMAND ${LCOV_PATH} --remove ${_outputname}.info 'tests/*' '/usr/*' --output-file ${_outputname}.info.cleaned
COMMAND ${GENHTML_PATH} -o ${_outputname} ${_outputname}.info.cleaned
COMMAND ${CMAKE_COMMAND} -E remove ${_outputname}.info ${_outputname}.info.cleaned
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
)
# Show info where to find the report
ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
COMMAND ;
COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report."
)
ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE
# Param _targetname The name of new the custom make target
# Param _testrunner The name of the target which runs the tests
# Param _outputname cobertura output is generated as _outputname.xml
# Optional fourth parameter is passed as arguments to _testrunner
# Pass them in list form, e.g.: "-j;2" for -j 2
FUNCTION(SETUP_TARGET_FOR_COVERAGE_COBERTURA _targetname _testrunner _outputname)
IF(NOT PYTHON_EXECUTABLE)
MESSAGE(FATAL_ERROR "Python not found! Aborting...")
ENDIF() # NOT PYTHON_EXECUTABLE
IF(NOT GCOVR_PATH)
MESSAGE(FATAL_ERROR "gcovr not found! Aborting...")
ENDIF() # NOT GCOVR_PATH
ADD_CUSTOM_TARGET(${_targetname}
# Run tests
${_testrunner} ${ARGV3}
# Running gcovr
COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} -e '${CMAKE_SOURCE_DIR}/tests/' -o ${_outputname}.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Running gcovr to produce Cobertura code coverage report."
)
# Show info where to find the report
ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD
COMMAND ;
COMMENT "Cobertura code coverage report saved in ${_outputname}.xml."
)
ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE_COBERTURA

View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -243,7 +243,7 @@ int cIniFile::FindKey(const AString & a_KeyName) const
{
if (CheckCase(names[keyID]) == CaseKeyName)
{
return keyID;
return (int)keyID;
}
}
return noID;
@ -279,7 +279,7 @@ int cIniFile::AddKeyName(const AString & keyname)
{
names.resize(names.size() + 1, keyname);
keys.resize(keys.size() + 1);
return names.size() - 1;
return (int)names.size() - 1;
}
@ -447,6 +447,15 @@ bool cIniFile::SetValueI(const AString & a_KeyName, const AString & a_ValueName,
bool cIniFile::SetValueI(const AString & a_Keyname, const AString & a_ValueName, const Int64 a_Value, const bool a_CreateIfNotExists)
{
return SetValue(a_Keyname, a_ValueName, Printf("%lld", a_Value), a_CreateIfNotExists);
}
bool cIniFile::SetValueF(const AString & a_KeyName, const AString & a_ValueName, double const a_Value, const bool a_CreateIfNotExists)
{
return SetValue(a_KeyName, a_ValueName, Printf("%f", a_Value), a_CreateIfNotExists);
@ -571,6 +580,24 @@ int cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, c
Int64 cIniFile::GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue)
{
AString Data;
Printf(Data, "%lld", defValue);
AString resultstring = GetValueSet(keyname, valuename, Data);
Int64 result = defValue;
#ifdef _WIN32
sscanf_s(resultstring.c_str(), "%lld", &result);
#else
sscanf(resultstring.c_str(), "%lld", &result);
#endif
return result;
}
bool cIniFile::DeleteValueByID(const int keyID, const int valueID)
{
if ((keyID < (int)keys.size()) && (valueID < (int)keys[keyID].names.size()))
@ -683,7 +710,7 @@ int cIniFile::GetNumKeyComments(const int keyID) const
{
if (keyID < (int)keys.size())
{
return keys[keyID].comments.size();
return (int)keys[keyID].comments.size();
}
return 0;
}

View File

@ -119,6 +119,7 @@ public:
AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "");
double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0);
int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0);
Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0);
bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false)
{
return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) != 0);
@ -141,6 +142,7 @@ public:
bool SetValue (const int keyID, const int valueID, const AString & value);
bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true);
bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true);
bool SetValueI(const AString & a_Keyname, const AString & a_ValueName, const Int64 a_Value, const bool a_CreateIfNotExists = true);
bool SetValueB(const AString & a_KeyName, const AString & a_ValueName, const bool a_Value, const bool a_CreateIfNotExists = true)
{
return SetValueI(a_KeyName, a_ValueName, int(a_Value), a_CreateIfNotExists);

View File

@ -623,7 +623,7 @@ Reader::decodeDouble( Token &token )
const int bufferSize = 32;
int count;
int length = int(token.end_ - token.start_);
if ( length <= bufferSize )
if ( length < bufferSize )
{
Char buffer[bufferSize];
memcpy( buffer, token.start_, length );

View File

@ -11,13 +11,14 @@ file(GLOB SOURCE
list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.c" "${PROJECT_SOURCE_DIR}/src/luac.c")
# add headers to MSVC project files:
if (WIN32)
if (MSVC)
file(GLOB HEADERS "src/*.h")
list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.h" "${PROJECT_SOURCE_DIR}/src/luac.h")
set(SOURCE ${SOURCE} ${HEADERS})
source_group("Sources" FILES ${SOURCE})
endif()
# Lua needs to be linked dynamically on Windows and statically on *nix, so that LuaRocks work
if (WIN32)
add_library(lua SHARED ${SOURCE})
@ -47,7 +48,7 @@ if (WIN32)
)
endif()
set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51")
set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51" PREFIX "")
# NOTE: The DLL for each configuration is stored at the same place, thus overwriting each other.
# This is known, however such behavior is needed for LuaRocks - they always load "lua5.1.dll" or "lua51.dll"
@ -57,6 +58,7 @@ else()
add_library(lua ${SOURCE})
endif()
# Tell Lua what dynamic loader to use (for LuaRocks):
if (UNIX)
add_definitions(-DLUA_USE_DLOPEN)

View File

@ -0,0 +1,61 @@
# This project adds a Lua Proxy DLL on Windows
# By an unfortunate choice in the popular LuaBinaries distribution, there are two names for the Lua DLL on Windows: lua51.dll and lua5.1.dll.
# Some binary Lua packages are built for one, the others for the other. Messy!
# In order to support both package flavors, we create a "proxy DLL":
# Basically the lua5.1.dll has its PE Exports section manipulated so that it points each exported function to its lua51.dll implementation.
# Effectively, this forwards all calls from lua5.1.dll to lua51.dll without any performance costs (the forwarding is done in the Windows PE loader on app start).
# This project creates the proxy DLL by using a specially crafted .DEF file that is used to link the Proxy DLL.
# Note that it has been tested only on MSVC, it might not work with other compilers.
# The initial implementation was taken from http://lua-users.org/wiki/LuaProxyDllFour , but adapted to MSVC
if (WIN32)
if (MSVC)
# Tell the linker to use the DEF file to generate the proxy:
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /NOENTRY /DEF:lua5.1.def /MANIFEST:NO")
elseif (MINGW)
# MinGW requires no further flags and has been tested
else()
message ("LuaProxy: This cmake code has not been tested on your compiler. Please report your success or failure in the forum.")
endif()
add_library(luaproxy SHARED "lua5.1.def" "Dummy.c")
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
set_target_properties(luaproxy PROPERTIES
OUTPUT_NAME "lua5.1"
PREFIX ""
)
target_link_libraries(luaproxy lua)
# Output the executable into the $/MCServer folder, so that MCServer can find it:
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer)
SET_TARGET_PROPERTIES(luaproxy PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
ARCHIVE_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
ARCHIVE_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
LIBRARY_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
LIBRARY_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}/MCServer
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}/MCServer
RUNTIME_OUTPUT_DIRECTORY_DEBUGPROFILE ${CMAKE_SOURCE_DIR}/MCServer
RUNTIME_OUTPUT_DIRECTORY_RELEASEPROFILE ${CMAKE_SOURCE_DIR}/MCServer
)
else()
message (FATAL_ERROR "This project is needed only for Windows, modify your cmake file not to include it on Linux")
endif()

4
lib/luaproxy/Dummy.c Normal file
View File

@ -0,0 +1,4 @@
// Dummy.c
// Because the MSVC compiler needs at least one C file to compile the project

115
lib/luaproxy/lua5.1.def Normal file
View File

@ -0,0 +1,115 @@
EXPORTS
luaL_addlstring=lua51.luaL_addlstring
luaL_addstring=lua51.luaL_addstring
luaL_addvalue=lua51.luaL_addvalue
luaL_argerror=lua51.luaL_argerror
luaL_buffinit=lua51.luaL_buffinit
luaL_callmeta=lua51.luaL_callmeta
luaL_checkany=lua51.luaL_checkany
luaL_checkinteger=lua51.luaL_checkinteger
luaL_checklstring=lua51.luaL_checklstring
luaL_checknumber=lua51.luaL_checknumber
luaL_checkoption=lua51.luaL_checkoption
luaL_checkstack=lua51.luaL_checkstack
luaL_checktype=lua51.luaL_checktype
luaL_checkudata=lua51.luaL_checkudata
luaL_error=lua51.luaL_error
luaL_findtable=lua51.luaL_findtable
luaL_getmetafield=lua51.luaL_getmetafield
luaL_gsub=lua51.luaL_gsub
luaL_loadbuffer=lua51.luaL_loadbuffer
luaL_loadfile=lua51.luaL_loadfile
luaL_loadstring=lua51.luaL_loadstring
luaL_newmetatable=lua51.luaL_newmetatable
luaL_newstate=lua51.luaL_newstate
luaL_openlib=lua51.luaL_openlib
luaL_openlibs=lua51.luaL_openlibs
luaL_optinteger=lua51.luaL_optinteger
luaL_optlstring=lua51.luaL_optlstring
luaL_optnumber=lua51.luaL_optnumber
luaL_prepbuffer=lua51.luaL_prepbuffer
luaL_pushresult=lua51.luaL_pushresult
luaL_ref=lua51.luaL_ref
luaL_register=lua51.luaL_register
luaL_typerror=lua51.luaL_typerror
luaL_unref=lua51.luaL_unref
luaL_where=lua51.luaL_where
lua_atpanic=lua51.lua_atpanic
lua_call=lua51.lua_call
lua_checkstack=lua51.lua_checkstack
lua_close=lua51.lua_close
lua_concat=lua51.lua_concat
lua_cpcall=lua51.lua_cpcall
lua_createtable=lua51.lua_createtable
lua_dump=lua51.lua_dump
lua_equal=lua51.lua_equal
lua_error=lua51.lua_error
lua_gc=lua51.lua_gc
lua_getallocf=lua51.lua_getallocf
lua_getfenv=lua51.lua_getfenv
lua_getfield=lua51.lua_getfield
lua_gethook=lua51.lua_gethook
lua_gethookcount=lua51.lua_gethookcount
lua_gethookmask=lua51.lua_gethookmask
lua_getinfo=lua51.lua_getinfo
lua_getlocal=lua51.lua_getlocal
lua_getmetatable=lua51.lua_getmetatable
lua_getstack=lua51.lua_getstack
lua_gettable=lua51.lua_gettable
lua_gettop=lua51.lua_gettop
lua_getupvalue=lua51.lua_getupvalue
lua_insert=lua51.lua_insert
lua_iscfunction=lua51.lua_iscfunction
lua_isnumber=lua51.lua_isnumber
lua_isstring=lua51.lua_isstring
lua_isuserdata=lua51.lua_isuserdata
lua_lessthan=lua51.lua_lessthan
lua_load=lua51.lua_load
lua_newstate=lua51.lua_newstate
lua_newthread=lua51.lua_newthread
lua_newuserdata=lua51.lua_newuserdata
lua_next=lua51.lua_next
lua_objlen=lua51.lua_objlen
lua_pcall=lua51.lua_pcall
lua_pushboolean=lua51.lua_pushboolean
lua_pushcclosure=lua51.lua_pushcclosure
lua_pushfstring=lua51.lua_pushfstring
lua_pushinteger=lua51.lua_pushinteger
lua_pushlightuserdata=lua51.lua_pushlightuserdata
lua_pushlstring=lua51.lua_pushlstring
lua_pushnil=lua51.lua_pushnil
lua_pushnumber=lua51.lua_pushnumber
lua_pushstring=lua51.lua_pushstring
lua_pushthread=lua51.lua_pushthread
lua_pushvalue=lua51.lua_pushvalue
lua_pushvfstring=lua51.lua_pushvfstring
lua_rawequal=lua51.lua_rawequal
lua_rawget=lua51.lua_rawget
lua_rawgeti=lua51.lua_rawgeti
lua_rawset=lua51.lua_rawset
lua_rawseti=lua51.lua_rawseti
lua_remove=lua51.lua_remove
lua_replace=lua51.lua_replace
lua_resume=lua51.lua_resume
lua_setallocf=lua51.lua_setallocf
lua_setfenv=lua51.lua_setfenv
lua_setfield=lua51.lua_setfield
lua_sethook=lua51.lua_sethook
lua_setlocal=lua51.lua_setlocal
lua_setmetatable=lua51.lua_setmetatable
lua_settable=lua51.lua_settable
lua_settop=lua51.lua_settop
lua_setupvalue=lua51.lua_setupvalue
lua_status=lua51.lua_status
lua_toboolean=lua51.lua_toboolean
lua_tocfunction=lua51.lua_tocfunction
lua_tointeger=lua51.lua_tointeger
lua_tolstring=lua51.lua_tolstring
lua_tonumber=lua51.lua_tonumber
lua_topointer=lua51.lua_topointer
lua_tothread=lua51.lua_tothread
lua_touserdata=lua51.lua_touserdata
lua_type=lua51.lua_type
lua_typename=lua51.lua_typename
lua_xmove=lua51.lua_xmove
lua_yield=lua51.lua_yield

140
lib/luaproxy/lua5.1.lua Normal file
View File

@ -0,0 +1,140 @@
-- lua5.1.lua
-- Generates the lua5.1.def file from the list of Lua symbols below
local symbols =
{
"luaL_addlstring",
"luaL_addstring",
"luaL_addvalue",
"luaL_argerror",
"luaL_buffinit",
"luaL_callmeta",
"luaL_checkany",
"luaL_checkinteger",
"luaL_checklstring",
"luaL_checknumber",
"luaL_checkoption",
"luaL_checkstack",
"luaL_checktype",
"luaL_checkudata",
"luaL_error",
"luaL_findtable",
"luaL_getmetafield",
"luaL_gsub",
"luaL_loadbuffer",
"luaL_loadfile",
"luaL_loadstring",
"luaL_newmetatable",
"luaL_newstate",
"luaL_openlib",
"luaL_openlibs",
"luaL_optinteger",
"luaL_optlstring",
"luaL_optnumber",
"luaL_prepbuffer",
"luaL_pushresult",
"luaL_ref",
"luaL_register",
"luaL_typerror",
"luaL_unref",
"luaL_where",
"lua_atpanic",
"lua_call",
"lua_checkstack",
"lua_close",
"lua_concat",
"lua_cpcall",
"lua_createtable",
"lua_dump",
"lua_equal",
"lua_error",
"lua_gc",
"lua_getallocf",
"lua_getfenv",
"lua_getfield",
"lua_gethook",
"lua_gethookcount",
"lua_gethookmask",
"lua_getinfo",
"lua_getlocal",
"lua_getmetatable",
"lua_getstack",
"lua_gettable",
"lua_gettop",
"lua_getupvalue",
"lua_insert",
"lua_iscfunction",
"lua_isnumber",
"lua_isstring",
"lua_isuserdata",
"lua_lessthan",
"lua_load",
"lua_newstate",
"lua_newthread",
"lua_newuserdata",
"lua_next",
"lua_objlen",
"lua_pcall",
"lua_pushboolean",
"lua_pushcclosure",
"lua_pushfstring",
"lua_pushinteger",
"lua_pushlightuserdata",
"lua_pushlstring",
"lua_pushnil",
"lua_pushnumber",
"lua_pushstring",
"lua_pushthread",
"lua_pushvalue",
"lua_pushvfstring",
"lua_rawequal",
"lua_rawget",
"lua_rawgeti",
"lua_rawset",
"lua_rawseti",
"lua_remove",
"lua_replace",
"lua_resume",
"lua_setallocf",
"lua_setfenv",
"lua_setfield",
"lua_sethook",
"lua_setlocal",
"lua_setmetatable",
"lua_settable",
"lua_settop",
"lua_setupvalue",
"lua_status",
"lua_toboolean",
"lua_tocfunction",
"lua_tointeger",
"lua_tolstring",
"lua_tonumber",
"lua_topointer",
"lua_tothread",
"lua_touserdata",
"lua_type",
"lua_typename",
"lua_xmove",
"lua_yield",
-- "luaopen_base",
-- "luaopen_debug",
-- "luaopen_io",
-- "luaopen_math",
-- "luaopen_os",
-- "luaopen_package",
-- "luaopen_string",
-- "luaopen_table",
}
local def = io.open("lua5.1.def", "w")
def:write("EXPORTS\n")
for _,symbol in ipairs(symbols) do
def:write("\t" .. symbol .. "=lua51." .. symbol .. "\n")
end
def:close()

View File

@ -1,12 +0,0 @@
cmake_minimum_required (VERSION 2.6)
project (md5)
include_directories ("${PROJECT_SOURCE_DIR}/../../src/")
file(GLOB SOURCE
"*.cpp"
"*.h"
)
add_library(md5 ${SOURCE})

View File

@ -1,369 +0,0 @@
/* MD5
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
for bzflag (http://www.bzflag.org)
based on:
md5.h and md5.c
reference implemantion of RFC 1321
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* interface header */
#include "md5.h"
/* system implementation headers */
#include <stdio.h>
#ifndef _WIN32
#include <cstring>
#endif
// Constants for MD5Transform routine.
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
///////////////////////////////////////////////
// F, G, H and I are basic MD5 functions.
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
return x&y | ~x&z;
}
inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
return x&z | y&~z;
}
inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
return x^y^z;
}
inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
return y ^ (x | ~z);
}
// rotate_left rotates x left n bits.
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
return (x << n) | (x >> (32-n));
}
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
}
inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
}
inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
}
inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
}
//////////////////////////////////////////////
// default ctor, just initailize
MD5::MD5()
{
init();
}
//////////////////////////////////////////////
// nifty shortcut ctor, compute MD5 for string and finalize it right away
MD5::MD5(const std::string &text)
{
init();
update(text.c_str(), text.length());
finalize();
}
//////////////////////////////
void MD5::init()
{
finalized=false;
count[0] = 0;
count[1] = 0;
// load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
}
//////////////////////////////
// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
void MD5::decode(uint4 output[], const uint1 input[], size_type len)
{
for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
}
//////////////////////////////
// encodes input (uint4) into output (unsigned char). Assumes len is
// a multiple of 4.
void MD5::encode(uint1 output[], const uint4 input[], size_type len)
{
for (size_type i = 0, j = 0; j < len; i++, j += 4) {
output[j] = input[i] & 0xff;
output[j+1] = (input[i] >> 8) & 0xff;
output[j+2] = (input[i] >> 16) & 0xff;
output[j+3] = (input[i] >> 24) & 0xff;
}
}
//////////////////////////////
// apply MD5 algo on a block
void MD5::transform(const uint1 block[blocksize])
{
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
decode (x, block, blocksize);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
// Zeroize sensitive information.
memset(x, 0, sizeof x);
}
//////////////////////////////
// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block
void MD5::update(const unsigned char input[], size_type length)
{
// compute number of bytes mod 64
size_type index = count[0] / 8 % blocksize;
// Update number of bits
if ((count[0] += (length << 3)) < (length << 3))
count[1]++;
count[1] += (length >> 29);
// number of bytes we need to fill in buffer
size_type firstpart = 64 - index;
size_type i;
// transform as many times as possible.
if (length >= firstpart)
{
// fill buffer first, transform
memcpy(&buffer[index], input, firstpart);
transform(buffer);
// transform chunks of blocksize (64 bytes)
for (i = firstpart; i + blocksize <= length; i += blocksize)
transform(&input[i]);
index = 0;
}
else
i = 0;
// buffer remaining input
memcpy(&buffer[index], &input[i], length-i);
}
//////////////////////////////
// for convenience provide a verson with signed char
void MD5::update(const char input[], size_type length)
{
update((const unsigned char*)input, length);
}
//////////////////////////////
// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
MD5& MD5::finalize()
{
static unsigned char padding[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (!finalized) {
// Save number of bits
unsigned char bits[8];
encode(bits, count, 8);
// pad out to 56 mod 64.
size_type index = count[0] / 8 % 64;
size_type padLen = (index < 56) ? (56 - index) : (120 - index);
update(padding, padLen);
// Append length (before padding)
update(bits, 8);
// Store state in digest
encode(digest, state, 16);
// Zeroize sensitive information.
memset(buffer, 0, sizeof buffer);
memset(count, 0, sizeof count);
finalized=true;
}
return *this;
}
//////////////////////////////
// return hex representation of digest as string
std::string MD5::hexdigest() const
{
if (!finalized)
return "";
char buf[33];
for (int i=0; i<16; i++)
sprintf(buf+i*2, "%02x", digest[i]);
buf[32]=0;
return std::string(buf);
}
//////////////////////////////
std::ostream& operator<<(std::ostream& out, MD5 md5)
{
return out << md5.hexdigest();
}
//////////////////////////////
std::string md5(const std::string & str)
{
MD5 md5 = MD5(str);
return md5.hexdigest();
}

View File

@ -1,93 +0,0 @@
/* MD5
converted to C++ class by Frank Thilo (thilo@unix-ag.org)
for bzflag (http://www.bzflag.org)
based on:
md5.h and md5.c
reference implementation of RFC 1321
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef BZF_MD5_H
#define BZF_MD5_H
#include <string>
#include <iostream>
// a small class for calculating MD5 hashes of strings or byte arrays
// it is not meant to be fast or secure
//
// usage: 1) feed it blocks of uchars with update()
// 2) finalize()
// 3) get hexdigest() string
// or
// MD5(std::string).hexdigest()
//
// assumes that char is 8 bit and int is 32 bit
class MD5
{
public:
typedef unsigned int size_type; // must be 32bit
MD5();
MD5(const std::string& text);
void update(const unsigned char *buf, size_type length);
void update(const char *buf, size_type length);
MD5& finalize();
std::string hexdigest() const;
friend std::ostream& operator<<(std::ostream&, MD5 md5);
private:
void init();
typedef unsigned char uint1; // 8bit
typedef unsigned int uint4; // 32bit
enum {blocksize = 64}; // VC6 won't eat a const static int here
void transform(const uint1 block[blocksize]);
static void decode(uint4 output[], const uint1 input[], size_type len);
static void encode(uint1 output[], const uint4 input[], size_type len);
bool finalized;
uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
uint4 count[2]; // 64bit counter for number of bits (lo, hi)
uint4 state[4]; // digest so far
uint1 digest[16]; // the result
// low level logic operations
static inline uint4 F(uint4 x, uint4 y, uint4 z);
static inline uint4 G(uint4 x, uint4 y, uint4 z);
static inline uint4 H(uint4 x, uint4 y, uint4 z);
static inline uint4 I(uint4 x, uint4 y, uint4 z);
static inline uint4 rotate_left(uint4 x, int n);
static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
};
std::string md5(const std::string & str);
#endif

View File

@ -1,5 +1,11 @@
if(NOT TARGET polarssl)
message("including polarssl")
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL )
set(ENABLE_TESTING OFF CACHE BOOL "Disable tests")
set(ENABLE_PROGRAMS OFF CACHE BOOL "Disable programs")
if (SELF_TEST)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl)
else()
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL)
endif()
endif()

View File

@ -9,16 +9,27 @@ file(GLOB SOURCE
)
# add headers to MSVC project files:
# Lua is required as a DLL for LuaSQLite:
if (WIN32)
add_definitions(-DLUA_BUILD_AS_DLL)
endif()
# add headers to MSVC project files:
if (MSVC)
file(GLOB HEADERS "src/*.h")
list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.h" "${PROJECT_SOURCE_DIR}/src/luac.h")
set(SOURCE ${SOURCE} ${HEADERS})
source_group("Sources" FILES ${SOURCE})
endif()
# FreeBSD requires us to define this to get POSIX 2001 standard
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
add_flags_cxx(-D__POSIX_VISIBLE=200112)
endif()
add_library(sqlite ${SOURCE})
target_link_libraries(sqlite lua)
if (UNIX)
target_link_libraries(sqlite ${DYNAMIC_LOADER})

View File

@ -44,14 +44,13 @@ file(GLOB BIN_SOURCE
"src/bin/*.c"
)
add_executable(tolua ${BIN_SOURCE})
add_library(tolualib ${LIB_SOURCE})
target_link_libraries(tolualib lua)
#m is the standard math librarys
if(UNIX)
target_link_libraries(tolua m ${DYNAMIC_LOADER})
endif()
target_link_libraries(tolua lua tolualib)
target_link_libraries(tolua tolualib lua)

View File

@ -688,73 +688,80 @@ static const unsigned char lua_basic_lua[] = {
0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68,
0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x09, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e,
0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74,
0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x72, 0x73, 0x0a, 0x0a,
0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x69, 0x73,
0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x20,
0x20, 0x2d, 0x2d, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x61,
0x74, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20,
0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x6e, 0x64,
0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x72, 0x69, 0x70,
0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x74, 0x2d, 0x70, 0x61, 0x72, 0x65, 0x6e,
0x74, 0x68, 0x65, 0x73, 0x69, 0x73, 0x20, 0x64, 0x75, 0x65, 0x20, 0x74,
0x6f, 0x20, 0x70, 0x72, 0x65, 0x2d, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e,
0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x75,
0x73, 0x74, 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x72, 0x73,
0x0a, 0x0a, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f,
0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73,
0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d,
0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68,
0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d,
0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d,
0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a,
0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b,
0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b,
0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b,
0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x66, 0x75, 0x6e,
0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20,
0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f,
0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b,
0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63,
0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66,
0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73,
0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75,
0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79,
0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09,
0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f,
0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b,
0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, 0x74, 0x79, 0x70, 0x65, 0x5d,
0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f,
0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73,
0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74,
0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68,
0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20,
0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75,
0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a,
0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e,
0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73,
0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d,
0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f,
0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d,
0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x66,
0x75, 0x6e, 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61,
0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67,
0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65,
0x73, 0x5b, 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65,
0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09,
0x69, 0x66, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61,
0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65,
0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e,
0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67,
0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65,
0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, 0x74, 0x79, 0x70,
0x65, 0x5d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74,
0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a,
0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65,
0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72,
0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65,
0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f,
0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20,
0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f,
0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e,
0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f,
0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65,
0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22,
0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e,
0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74,
0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20,
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28,
0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f,
0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75,
0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64,
0x0a
0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75,
0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f,
0x70, 0x75, 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65,
0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09,
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, 0x6f, 0x5f, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20,
0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61,
0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f,
0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f,
0x74, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a,
0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x69, 0x66,
0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74,
0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20,
0x2e, 0x2e, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f,
0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73,
0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69,
0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29,
0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69,
0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65,
0x6e, 0x64, 0x0a
};
unsigned int lua_basic_lua_len = 9073;
unsigned int lua_basic_lua_len = 9159;

View File

@ -1154,7 +1154,7 @@ static const unsigned char lua_declaration_lua[] = {
0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65,
0x2a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61,
0x6c, 0x20, 0x73, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28,
0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x5c, 0x5b, 0x5c, 0x5d, 0x29, 0x22,
0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x25, 0x5b, 0x25, 0x5d, 0x29, 0x22,
0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6e,
0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x73, 0x75,
0x62, 0x28, 0x6e, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x2c, 0x27, 0x5c, 0x31,

View File

@ -0,0 +1,93 @@
-- Allow debugging by ZBS, if run under the IDE:
local mobdebugfound, mobdebug = pcall(require, "mobdebug")
if mobdebugfound then mobdebug.start() end
-- The list of valid arguments that the ToLua scripts can process:
local KnownArgs = {
['v'] = true,
['h'] = true,
['p'] = true,
['P'] = true,
['o'] = true,
['n'] = true,
['H'] = true,
['S'] = true,
['1'] = true,
['L'] = true,
['D'] = true,
['W'] = true,
['C'] = true,
['E'] = true,
['t'] = true,
['q'] = true,
}
-- The flags table used by ToLua scripts, to be filled from the cmdline params:
flags = {}
-- Te extra parameters used by ToLua scripts:
_extra_parameters = {}
-- ToLua version required by the scripts:
TOLUA_VERSION = "tolua++-1.0.92"
-- Lua version used by ToLua, required by the scripts:
TOLUA_LUA_VERSION = "Lua 5.1"
-- Process the cmdline params into the flags table:
local args = arg or {}
local argc = #args
local i = 1
while (i <= argc) do
local argv = args[i]
if (argv:sub(1, 1) == "-") then
if (KnownArgs[argv:sub(2)]) then
print("Setting flag \"" .. argv:sub(2) .. "\" to \"" .. args[i + 1] .. "\".")
flags[argv:sub(2)] = args[i + 1]
i = i + 1
else
print("Unknown option (" .. i .. "): " .. argv)
print("Aborting.")
os.exit(1)
end
else
print("Setting flag \"f\" to \"" .. argv .. "\".")
flags['f'] = argv
break
end
i = i + 1
end
-- Get the path where the scripts are located:
path = args[0] or ""
local index = path:find("/[^/]*$")
if (index == nil) then
index = path:find("\\[^\\]*$")
end
if (index ~= nil) then
path = path:sub(1, index)
end
print("path is set to \"" .. path .. "\".")
-- Call the ToLua processor:
dofile(path .. "all.lua")

View File

@ -383,7 +383,7 @@ end
-- called to output an error message
function output_error_hook(...)
return string.format(...)
return string.format(...) -- Note that this line must not end in the triple-dot-parenthesis due to pre-parsing
end
-- custom pushers

View File

@ -18,17 +18,16 @@ local function pp_dofile(path)
local ret = file:read("*a")
file:close()
ret = string.gsub(ret, "%.%.%.%s*%)", "...) local arg = {n=select('#', ...), ...};")
ret = string.gsub(ret, "%.%.%.%s*%)$", "...) local arg = {n=select('#', ...), ...};")
loaded = true
return ret
end
end
local f = load(getfile, path)
local f, err = load(getfile, path)
if not f then
error("error loading file "..path)
error("error loading file " .. path .. ": " .. err)
end
return f()
end

View File

@ -524,7 +524,7 @@ function Declaration (s,kind,is_parameter)
end
-- check the form: mod type* name
local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end)
local s1 = gsub(s,"(%b%[%])",function (n) return gsub(n,'%*','\1') end)
t = split_c_tokens(s1,'%*')
if t.n == 2 then
t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression

View File

@ -132,7 +132,7 @@ function classFeature:cfuncname (n)
if not fname or fname == '' then
fname = self.name
end
n = string.gsub(n..'_'.. (fname), "[<>:, \.%*&]", "_")
n = string.gsub(n..'_'.. (fname), "[<>:, %.%*&]", "_")
return n
end

113
src/AllocationPool.h Normal file
View File

@ -0,0 +1,113 @@
#pragma once
#include <memory>
template<class T>
class cAllocationPool
{
public:
class cStarvationCallbacks
{
public:
virtual ~cStarvationCallbacks() {}
/** Is called when the reserve buffer starts to be used **/
virtual void OnStartUsingReserve() = 0;
/** Is called once the reserve buffer has returned to normal size **/
virtual void OnEndUsingReserve() = 0;
/** Is called when the allocation pool is unable to allocate memory. Will be repeatedly
called if it does not free sufficient memory **/
virtual void OnOutOfReserve() = 0;
};
virtual ~cAllocationPool() {}
/** Allocates a pointer to T **/
virtual T * Allocate() = 0;
/** Frees the pointer passed in a_ptr, invalidating it **/
virtual void Free(T * a_ptr) = 0;
};
/** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve
elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/
template<class T, size_t NumElementsInReserve>
class cListAllocationPool : public cAllocationPool<T>
{
public:
cListAllocationPool(std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> a_Callbacks) :
m_Callbacks(a_Callbacks)
{
for (size_t i = 0; i < NumElementsInReserve; i++)
{
void * space = malloc(sizeof(T));
if (space == NULL)
{
m_Callbacks->OnStartUsingReserve();
break;
}
m_FreeList.push_front(space);
}
}
virtual ~cListAllocationPool()
{
while (!m_FreeList.empty())
{
free (m_FreeList.front());
m_FreeList.pop_front();
}
}
virtual T * Allocate() override
{
if (m_FreeList.size() <= NumElementsInReserve)
{
void * space = malloc(sizeof(T));
if (space != NULL)
{
return new(space) T;
}
else if (m_FreeList.size() == NumElementsInReserve)
{
m_Callbacks->OnStartUsingReserve();
}
else if (m_FreeList.empty())
{
m_Callbacks->OnOutOfReserve();
// Try again until the memory is avalable
return Allocate();
}
}
// placement new, used to initalize the object
T * ret = new (m_FreeList.front()) T;
m_FreeList.pop_front();
return ret;
}
virtual void Free(T * a_ptr) override
{
if (a_ptr == NULL)
{
return;
}
// placement destruct.
a_ptr->~T();
m_FreeList.push_front(a_ptr);
if (m_FreeList.size() == NumElementsInReserve)
{
m_Callbacks->OnEndUsingReserve();
}
}
private:
std::list<void *> m_FreeList;
std::auto_ptr<typename cAllocationPool<T>::cStarvationCallbacks> m_Callbacks;
};

Some files were not shown because too many files have changed in this diff Show More